Makepad 界面怎么做得更像产品,而不是示例
2026/6/10 23:53:32 网站建设 项目流程

前言

前两周我用 Makepad 做了一个 JSON 查看器。功能跑通了,文件能打开,树能展开折叠,搜索能跳转。自己用着挺爽。

然后给一个前端朋友看了截图。他回了句:

“功能感觉还行,但这界面……你是还没开始写 CSS 对吧?”

我愣了一下。确实。全程只调了flowalignwidthheight。颜色没管,字体没调,间距全默认。界面能跑,但看起来就像一个程序员半夜两点的临时作品。

这一期就是从那句话开始的。

Makepad 没有 CSS。样式系统是另一套东西。但不代表你只能做出 demo 感。我把调界面的过程捋了一遍:先吃透布局,再搭一套简陋但够用的"设计系统",最后用 before/after 展示怎么把 demo 调出产品感。

1. 先把布局模型吃透

1.1 Makepad 的布局不是 Flexbox

如果你从 Web 背景过来,看到flow: Downalign: Center这些词,第一反应肯定是"这不就是 flex-direction + align-items 吗"。

像,但不是。

关键差异有三个。

第一,没有独立的尺寸轴控制。CSS 里justify-content管主轴、align-items管交叉轴,两个维度可以独立设置。Makepad 里align同时控制两个方向的子元素对齐,颗粒度更粗。

第二,没有margin控件之间的间距主要靠spacing属性,它作用于容器上,控制所有子元素之间的统一间距。

View { flow: Down, spacing: 12, // 所有子元素之间 12px 间距 align: Center, }

CSS 里你可以给每个元素单独设margin-bottom: 8pxmargin-right: 16px。Makepad 里不行。间距是容器级别的,所有子元素一视同仁。

第三,width: Fill的行为和flex: 1不一样。Fill的意思是"撑满父容器剩余的全部空间",但它不会像 flex-grow 那样按比例分配。如果有两个Fill子元素,它们的行为取决于flow方向——在Down流中第一个 Fill 会先占满,第二个可能没空间。

这些差异刚开始会让你很挫败。我前两个小时一直在找"Makepad 的 margin 怎么设",最后发现它就是没有。

1.2 三个属性搞定 80% 的布局

但挫败之后我发现一件事:因为可调的属性少,所以你反而更快。

Makepad 布局的核心就三个属性:

属性作用常用值
flow排列方向Down,Right
align子元素对齐Center,Start,End
width / height尺寸Fill,Fit, 具体数值

配合spacing(子元素间距)和padding(内边距),基本布局都能出来。

一个典型的"做产品感的页面"大概是这样的嵌套:

View { // 根容器 flow: Down, align: Start, padding: { top: 24, bottom: 24, left: 24, right: 24 }, spacing: 16, // 标题区 View { flow: Right, align: Center, spacing: 12, Icon { ... } Label { text: "JSON 查看器" } View { width: Fill } // 占位弹簧,把后面的元素推到右边 Button { text: "打开文件" } } // 内容区 View { width: Fill, height: Fill, flow: Right, spacing: 0, // 左侧树 View { width: 280, ... } // 右侧内容 View { width: Fill, ... } } // 底部状态栏 View { flow: Right, align: Center, Label { text: "共 120 个节点" } } }

注意那个View { width: Fill }的占位弹簧用法。因为没有justify-content: space-between,你要在中间塞一个空的Fill元素把后面的按钮推到右边。

很土。但能用。

1.3 嵌套 View 是你的主要武器

没有 margin。没有 gap。没有 flex-grow 的比例分配。那复杂布局怎么做?

嵌套 View。就这一招。

每个"需要和别人不太一样"的区域,包进一个独立View,在这个 View 上设自己的flowalignspacingpadding

这个思路和 Flutter 的"一切皆 Widget"很像,只是 Makepad 里你的唯一武器是View

比如一个常见的"图标 + 标题 + 副标题 + 右侧操作按钮"的行布局:

// 这一行不能用简单的 flow:Right + align:Center 搞定 // 因为标题和副标题是垂直排列的,右侧按钮要对齐到行顶部 View { flow: Right, align: Start, spacing: 12, padding: {left: 16, right: 16, top: 12, bottom: 12}, Icon { ... } View { // 中间文字区:标题上、副标题下 flow: Down, spacing: 4, Label { text: "文件名.json" } Label { text: "120 个节点 · 3.2 KB" } } View { width: Fill } // 弹簧 Button { text: "..." } // 更多操作 }

2. 建立一套迷你"设计系统"

布局对了,下一步是颜色和字体。这是 demo 感和产品感之间最大的一道坎。

2.1 把所有硬编码的颜色抽出来

Makepad 里颜色是直接写在控件上的:

Label { text: "标题" draw_text: { color: #333333, font_size: 16.0 } }

小项目这样没问题。但当你有 20 个 Label、15 个 Button、10 个 View 背景色的时候,散落的色值会让你调一次主题色改几十个地方。

我的做法:用 Makepad 的 live DSL 变量能力,把颜色和字号统一定义在顶部:

// ===== 设计系统变量 ===== // 主色 color_primary: #4A90D9, color_primary_hover: #357ABD, // 文字色 color_text_primary: #1A1A2E, color_text_secondary: #6B7280, color_text_disabled: #9CA3AF, // 背景色 color_bg_page: #F9FAFB, color_bg_card: #FFFFFF, color_bg_hover: #F3F4F6, // 边框 color_border: #E5E7EB, // 字号 font_size_title: 20.0, font_size_body: 14.0, font_size_caption: 12.0, // 间距 spacing_xs: 4, spacing_sm: 8, spacing_md: 16, spacing_lg: 24, // 圆角 radius_sm: 4, radius_md: 8, radius_lg: 12,

然后控件引用变量:

Label { text: "标题" draw_text: { color: (color_text_primary), font_size: (font_size_title) } } View { draw_bg: { color: (color_bg_card), border_radius: (radius_md) } }

这一套做法不是 Makepad 官方推荐的,但我在几个小项目里用了之后发现调主题快了很多。改一次色值,全局生效。跟 CSS 变量的思路一模一样。

2.2 字体层级不要超过 4 级

我做 JSON 查看器的时候,一开始用了 6 种字号。标题、小标题、正文、代码、标注、状态栏。看起来很"精细",实际上全是视觉噪音。

后来砍成 3 级:

层级字号用途
标题18-20页面标题、区块标题
正文14主要内容、列表项、按钮文字
辅助12说明文字、时间戳、状态标签

整个界面干净了不止一个档次。

如果你和我一样没有设计背景,一个很实用的原则是:先只用 2 级字号(正文+辅助),等真的需要第三级再加。大多数时候你会发现两级就够了。

2.3 颜色:一个主色 + 一套灰度

配色是最容易"调过头"的。我的原则很简单:

1 个主色,管按钮、链接、选中态。1 个主色的 hover 变体,比主色深 10-15%。4 级灰度——文字主色、文字次色、背景、边框。语义色(红/绿/黄)能不加就不加。

4 级灰度是我踩出来的。少于 4 级区分不了主文字和次文字,多于 4 级灰色会发脏,偏蓝或偏紫。

color_text_primary: #1A1A2E, // 深灰,接近黑但更柔和 color_text_secondary: #6B7280, // 中灰,辅助信息 color_bg_page: #F9FAFB, // 极浅灰,页面底色 color_border: #E5E7EB, // 浅灰边框

这套灰度偏冷,带一点蓝底,比纯中性灰看着更干净。想要暖一点可以用#F5F0EB方向,看产品调性。

3. 常见"demo 感"问题及修复

下面是我从自己项目里揪出来的 demo 感问题。

3.1 控件全部贴边

窗口边缘到第一个控件的距离为 0。内容像贴在玻璃上。

修法:根容器加padding,至少 16px。

// ❌ 之前 View { flow: Down, // 没有 padding,内容贴边 Label { text: "标题" } Button { text: "操作" } } // ✅ 之后 View { flow: Down, padding: { left: 24, right: 24, top: 20, bottom: 20 }, spacing: 16, Label { text: "标题" } Button { text: "操作" } }

3.2 没有视觉层级

所有文字一样大、一样粗、一样颜色。不知道先看哪。

修法:至少区分标题和内容。标题大一号或颜色重一点。

// ❌ 之前:标题和内容一样 Label { text: "文件列表", draw_text: { font_size: 14.0, color: #333 } } Label { text: "data.json", draw_text: { font_size: 14.0, color: #333 } } // ✅ 之后:标题 18px 深色,内容 14px Label { text: "文件列表", draw_text: { font_size: 18.0, color: (color_text_primary) } } Label { text: "data.json", draw_text: { font_size: 14.0, color: (color_text_primary) } }

3.3 间距不均匀

有的地方挤,有的地方空。随手调的感觉很重。

修法:间距只用预设变量,别写魔法数字。

// ❌ 之前:到处都是不同的间距值 View { spacing: 7, ... } View { spacing: 13, ... } View { spacing: 22, ... } // ✅ 之后:只有 4/8/16/24 四档 View { spacing: (spacing_sm), ... } // 8 View { spacing: (spacing_md), ... } // 16 View { spacing: (spacing_lg), ... } // 24

3.4 背景全白,没有区块感

所有内容在同一个纯白背景上。信息没分组,糊成一团。

修法:卡片背景 + 浅灰底色,把信息块分开。

// ❌ 之前:全白 View { flow: Down, spacing: 16, Label { text: "设置" } Label { text: "主题:暗色" } Label { text: "语言:中文" } } // ✅ 之后:卡片分组 View { flow: Down, spacing: (spacing_lg), padding: (spacing_md), draw_bg: { color: (color_bg_page) }, // 页面灰色底色 // 第一组:外观设置 View { flow: Down, spacing: (spacing_sm), padding: (spacing_md), draw_bg: { color: (color_bg_card), border_radius: (radius_md) }, Label { text: "外观" } Label { text: "主题:暗色" } } // 第二组:语言设置 View { flow: Down, spacing: (spacing_sm), padding: (spacing_md), draw_bg: { color: (color_bg_card), border_radius: (radius_md) }, Label { text: "语言" } Label { text: "当前:中文" } } }

3.5 按钮像一行字

没有背景色,没有内边距,没有圆角。看起来就是个 Label。

修法:背景色 + 横向 padding + 圆角,三样缺一不可。

// ❌ 之前 Button { text: "保存" } // ✅ 之后 Button { text: "保存" draw_bg: { color: (color_primary), border_radius: (radius_sm) } draw_text: { color: #FFFFFF, font_size: (font_size_body) } padding: { left: 20, right: 20, top: 8, bottom: 8 } }

4. before/after:一个真实的调优案例

下面是我那个 JSON 查看器的主界面,调之前和调之后的关键差异。

调之前(demo 感):

Window { body +: { View { flow: Down, View { // 顶部栏 flow: Right, Button { text: "打开" } Button { text: "展开全部" } Button { text: "折叠全部" } } TextInput { } // 搜索框 List { } // 文件树 Label { text: "120 个节点" } // 状态栏 } } }

问题:没有 padding、按钮挤在左上角、搜索框和工具栏没有视觉分隔、状态栏贴在最底部没有底边框、所有文字一样大。

调之后(产品感):

Window { body +: { View { flow: Down, spacing: 0, draw_bg: { color: (color_bg_page) }, // 顶部工具栏 View { flow: Right, align: Center, spacing: (spacing_sm), padding: { left: (spacing_lg), right: (spacing_lg), top: 12, bottom: 12 }, draw_bg: { color: (color_bg_card) }, Label { text: "JSON 查看器", draw_text: { font_size: (font_size_title), color: (color_text_primary) } } View { width: Fill } Button { text: "打开文件" } Button { text: "展开全部" } Button { text: "折叠全部" } } // 搜索栏 View { padding: { left: (spacing_lg), right: (spacing_lg), top: (spacing_sm), bottom: (spacing_sm) }, draw_bg: { color: (color_bg_card) }, TextInput { width: Fill, placeholder: "搜索节点..." } } // 分割线:一个 1px 高的 View View { width: Fill, height: 1, draw_bg: { color: (color_border) } } // 内容区(文件树) View { width: Fill, height: Fill, padding: (spacing_md), List { } } // 底部状态栏 View { flow: Right, align: Center, spacing: (spacing_md), padding: { left: (spacing_lg), right: (spacing_lg), top: 8, bottom: 8 }, draw_bg: { color: (color_bg_card) }, Label { text: "共 120 个节点 · 3.2 KB", draw_text: { font_size: (font_size_caption), color: (color_text_secondary) } } } } } }

改动看起来很多,其实全是前面说的那几件事:加了 padding、分了卡片区域、建立了颜色和字号变量、用 1px View 做分割线、按钮加了背景色。

调完之后我自己都惊了。同样的功能和控件,只是把视觉参数统一了一下,整个界面直接从"技术预览版"变成了"能给人看的工具"。

5. 几个 Makepad 特有的技巧

5.1 用 1px View 做分割线

因为没有border-bottom,分割线就是在两个区域之间塞一个 1px 高的 View:

View { width: Fill, height: 1, draw_bg: { color: (color_border) } }

5.2 用空 View 做弹簧

需要space-between效果时,中间塞View { width: Fill }

View { flow: Right, align: Center, Label { text: "左侧" } View { width: Fill } // 弹簧 Button { text: "右侧" } }

5.3 卡片圆角 + 微妙阴影感

Makepad 的draw_bg支持border_radius。虽然没有 box-shadow,但可以用一个微妙的背景色差异(卡片比页面背景稍亮)来产生层次感:

color_bg_page: #F3F4F6, // 页面底色(稍深灰) color_bg_card: #FFFFFF, // 卡片底色(纯白) // 卡片浮在灰色页面上,自然产生层次

5.4 hover 态:别忘了交互反馈

按钮和可点击的行,一定要加 hover 态。不然用户点的时候没有任何反馈,会觉得界面"卡"。

Button { draw_bg: { color: (color_primary), color_hover: (color_primary_hover), border_radius: (radius_sm) } }

列表行也类似——至少加个 hover 背景色变化。

总结

这一期不讲新 API,只讲一件事:怎么把你已有的界面从 demo 调成产品。

如果你只想记住三个操作:

  1. 根容器加 padding,至少 16px。贴边是 demo 感的第一来源。
  2. 建立颜色和字号变量。不要到处写#33314.0,统一管理。
  3. 用卡片 + 分割线做信息分组。全白背景是 demo 感的第二来源。

这三个操作做完,你的 Makepad 界面至少能达到"可以给人看"的水平。不需要设计天赋,只需要纪律。

下一期我准备做一期实战:用 Makepad 从头做一个完整的小工具(JSON 查看器或 Markdown 预览器),把前六期所有内容串起来。从需求拆解到页面结构到代码组织,完整走一遍。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询