设计档案馆
中EN

把设计稿里的约束翻译成前端能直接用的 CSS

前端没有设计工具账号,看不到设计稿里的约束,而约束本身只说「钉在哪条边」,不说为什么。我为两种标题栏写了一份自带实时预览的交接单,前端拖一下宽度就能自己验收。

L.13 / 14
CATEGORY
研究
YEAR
2026
STATUS
笔记
TOOLS
css / flexbox / svg

entry记录

一块 1920×1080 的数据大屏里,每个图表卡片顶部都有一条标题栏,包含渐变底板、两端带亮点的顶线、一截发光的底线、一个双箭头图标和一行标题;后来又加了第二种样式,用在助手面板顶部,多了头像、副标题、一个按钮和关闭图标。这类组件装饰层很多,卡片宽度改变时,各层的行为不同:有的跟着拉伸,有的贴着右边移动,有的原地不动。设计工具里给每个图层规定了钉在哪条边(这种设置称为约束,constraints),这些关系都已设好,问题是怎么把这些设置交给前端。起初以为这只是怎么导出的问题,实际叠着三件事:第一,前端没有设计工具账号,看不到设计稿,开发模式、检查面板和节点链接对他们都不存在,交付物必须自带全部信息;第二,约束只有四种语义(贴起始边、贴结束边、保持中心距、两边同时钉住),表达不了设计意图,不会说明底线在卡片变宽时该保持固定宽度还是按比例伸缩,也不会说明标题是可长可短的动态字段,这些不写出来,前端就会各写各的;第三,设计稿本身有看起来对、数值上却不严谨的地方,比如垂直居中的基准、按钮内边距含不含描边,在设计工具里肉眼看不出,到了 CSS 里就会产生 1 到 2px 的偏差。交接单前后改了五版,每一版几乎都来自同一个追问:前端拿到这份东西,能不能不问我就直接做?

五个版本的演进。

第一版通过设计工具的接口逐层遍历,把每一层的锚定方式、位置、尺寸、填充、描边、效果、文字属性以及矢量图形的路径数据全部读出来,将几十个属性整理成一张表,避免漏项。这一版定下的关键做法是,交接单本身就用要交付的这份 CSS 来写。页面上那条标题栏不是截图,而是真实的 .bar 组件,旁边放着一个宽度滑块;拖动滑块,就能看到底板跟着拉伸、右端头贴着右边移动、底线保持不动。

样式 A 在设计稿宽度 500px 下的渲染。
拉到 760px:底板和顶线跟随,底线和辉光固定不动。

第二版把文档改成了面向前端的口吻。第一版里有一节写给自己看的交付流程,说明怎么把这份东西发出去;还有三条征询式的「待确认项」,比如问底线是固定还是按比例、本意是什么。但这份文档的读者是前端,不是我自己。这一版删掉了交付流程,把「待确认」全部改成「实现约定」,每条直接给出结论:按固定像素实现、加截断、禁止 overflow:hidden。前端照做即可,不用等待回复;如果设计侧有不同意见,直接修改约定,不让前端去猜。

第三版去掉了对设计工具的依赖。我在表格里加过一列「节点 ID」,还写了一句前端在开发模式里能直接定位到图层,然后才想起前端没有账号。整份文档因此删掉了所有节点 ID、文件链接和工具术语,把 MIN、MAX、STRETCH、CENTER 换成「贴左、贴右、左右拉伸、居中」;原本写着请从设计稿导出图标 SVG,前端同样做不到,于是改为读取矢量路径的真实数据,直接内联进 HTML。这一版还顺带发现,第一版的图标是看着缩略图、凭图层名猜着画出来的,里面那个「点」其实是菱形而不是圆,真实路径一换上就对上了。有真实数据就不要猜,哪怕看起来差不多;检查交付物时,先假设读者没有任何设计工具权限,看这份文档还能不能用。

四种锚定语义与 CSS 写法的对应。

第四版处理了作为动态字段的标题。审阅时追问了一句:标题栏里的文字是变量,可长可短,考虑到了吗?之前只在约定里提了一句建议加截断。这一版把截断升级为必做项,直接写进代码,给标题加上 flex:0 1 auto; min-width:0; text-overflow:ellipsis,并在预览页增加了文案输入框和三个不同字数的预设。这是前端常遇到的问题:flex 子项默认的最小宽度是内容宽度,文字再长也不会收缩,所以不写 min-width:0,省略号永远不会出现。

20 字标题配 380px 窄卡片:正常截断,省略号离右端头还有 6px 余量。

第五版并入了第二种面板标题栏样式。对比发现,两种样式的 6 个装饰层结构完全相同,只是上下偏移差几个像素。代码没有写两套边框,而是抽出一个 .bar 基类,用 6 个 CSS 自定义属性(如 --plate-top、--cap-top)切换偏移,.bar--panel 修饰符只修改这 6 个值、高度和底色。第二种样式里有一个前端拿不到的头像位图,处理办法是导出成透明 PNG,把图片编码成一段文本直接写进 HTML(称为 data URI),并在页面里加一个「资源」页签供直接复制;头像外圈的渐变光环线、按钮图标和关闭的 ×,也全部转成了内联 SVG 路径。

共用骨架,加自定义属性切换。
样式 B 在 500px 下的渲染。
样式 B 拉到 760px:按钮和关闭贴右,文字区吃掉所有剩余宽度。

读取数据时发现,图标中心在 27.45,标题中心在 26.5,而标题栏的几何中心是 25.5,都对不上。算了一下才明白原因:底板从 y=4 开始,顶部 4px 是透明的线条区,底板的中心是 27.5;设计稿里的居中是对底板居中,而不是对整条标题栏居中,这 2px 的差别肉眼能看出来。解决办法是让内容层先铺满底板区域,再设置 align-items:center。

垂直居中的基准是底板,不是整条标题栏。

按钮的尺寸也出现了偏差。设计工具里的内描边画在内边距里面,而 CSS 的 border 是另外计算的;设计稿上按钮的内边距写着 8/16,如果照抄进 CSS,渲染出来是 102×40,而不是 100×38。为此,代码里把内边距改写成了扣掉描边后的数值,并加上注释。这种差别如果不写清楚,前端对着设计稿量多少遍也量不出来。

设计稿里的底线画成了固定宽度,但当卡片拉宽到 760px 时,底线只占 41% 的宽度。我没有把这个问题抛回给前端,而是在约定里先给了默认值:按固定像素实现,同时写出改为比例时对应的百分比。这样前端有事可做,设计侧也有空间改。锚定语义是客观的,翻译成 CSS 没有歧义;需要人另外写出来的是设计意图,比如底线是不是按比例、标题最长多少字、外层能不能设置 overflow:hidden。

最终交付的是一份独立的 HTML 文件:开头是共用边框骨架,包含 6 层装饰在两种样式下的偏移对照表和共用 CSS;接着是样式 A 的实时预览、内容区定位表和代码;然后是样式 B 的对应内容,外加一个「资源」页签;最后是 6 条实现约定,其中 3 条通用、3 条只针对样式 B。鼠标悬停在表格某一行时,预览区里对应的图层会高亮,前端看到表格里的「底线」一行,就能直接在页面上对应到那条线。发出前,我用一个没有界面、在命令行里运行的浏览器(称为无头浏览器)自动测量页面元素坐标,逐层核对了一遍:样式 B 里头像在 (16,20)、状态点在 (56,22)、标题在 (78,17)、按钮在 (336,25)、尺寸 100×38,关闭图标在 (472,38),全部与设计稿一致。

悬停表格行,预览里对应的图层高亮。

process对比

锚定语义与 CSS

贴左
跟随起始边,宽度不变
贴右
跟随结束边,宽度不变
左右拉伸
两边同时钉住,宽度跟随容器
居中
保持到中心的距离

交接单里定下的数值

标题栏高
图表卡片 51px · 面板 92px
垂直居中
以底板(从 y=4 开始)为基准,底板中心 27.5
按钮
padding 7/15,渲染为 100×38(设计稿 8/16 含 1px 内描边)
底线
固定 312px;若改为比例,对应 62.4%
头像
96×96 透明 PNG,按 48×48 显示,以 data URI 内联
标题预设
3 字 · 11 字 · 20 字;380px 宽时省略号离右端头 6px

居中与截断

css
/* 内容层铺满底板区域,再垂直居中 */
.bar__content {
  position: absolute;
  left: 0;
  right: 0;
  top: var(--plate-top);
  bottom: var(--plate-bottom);
  display: flex;
  align-items: center;
}
.bar__title {
  flex: 0 1 auto;
  min-width: 0; /* 不写这一行,省略号永远不会出现 */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

result小结

结论
两种标题栏共用一份边框代码,靠 6 个自定义属性切换;所有图标、位图、路径内嵌在一个 HTML 里,用无头浏览器逐层核对过,位置与设计稿一致。
参数
内容层铺满底板再 align-items:center · 按钮 padding 7/15(设计稿 8/16 含 1px 内描边)· 标题 flex:0 1 auto + min-width:0 + ellipsis · 底线固定 312px
没做完
底线固定 312px 时,卡片拉到 760px 只占 41% 宽,视觉上偏短;约定里留了按比例(62.4%)的写法,设计侧还可以改。

log日志

2026-10
首次记录

相关实验

note
L.08(STUDY)2026

一张头图的响应式之旅

responsivecssobject-fit+1
note
L.12(STUDY)2026

一套求解器,十种分辨率不走样

responsivecssclamp+1
note
L.01(STUDY)2026

(一)赛前选定基座模型

chest-xraypytorchrad-dino+1
← LabL.13 / 14
1 / 1

100%