应以1rem为基准用--space-1: 0.25rem定义间距变量,后续通过calc()乘算;优先用gap配合var()控制布局间距,禁用混合单位与margin微调;必须用:not(:last-child)约束单向margin;响应式场景用clamp()替代vw,确保极端屏幕下间距可控。

用:root定义间距变量,但别只写px
直接在:root里塞一堆--space-1: 4px看似简洁,但一旦字号或视口变化,这些px值就失去响应能力。真正可维护的起点是把基准单位锚定在相对量上——比如以1rem为最小单位,再用em或clamp()衍生出弹性层级。
-
--space-1: 0.25rem(即 4px 当根字体为 16px 时),后续所有变量都基于它乘算:--space-2: calc(var(--space-1) * 2) - 需要适配小屏时,可改用
clamp(0.125rem, 0.5vw, 0.375rem)定义--space-1,让最小间距不塌缩、最大不撑爆 - 避免混合使用
px和rem定义同一套变量,否则计算链断裂,calc()里单位不匹配会静默失效
gap必须用变量,且优先于margin
Grid 和 Flex 容器里的gap是唯一不会触发外边距折叠、且天然支持变量注入的间距控制点。只要布局容器用了display: grid或flex,就该把gap当作第一选择。
- 写法必须是
gap: var(--space-4),而不是gap: var(--space-4) 0——后者在旧版 Safari 中可能被忽略 - 若需行列不同值,用
row-gap和column-gap分别赋值,它们各自支持独立变量:row-gap: var(--space-2); column-gap: var(--space-3) - 别在子元素上再加
margin去“微调”gap,这等于主动引入冗余和不可预测的叠加逻辑
给margin加约束:单方向 + 伪类过滤
当必须用margin(比如非布局容器内的普通块级元素),放任四向设置会迅速瓦解间距体系。核心约束只有两条:只设一个方向,且用:not(:last-child)收尾。
- 统一用
margin-bottom,配合.list-item:not(:last-child) { margin-bottom: var(--space-3); } - 禁用
margin-top——它极易与父容器margin-top折叠,尤其在动态插入内容时行为难控 - 如果组件内部有嵌套结构,不要在子组件里重置父级
margin,而是用margin: 0显式清除,再按新上下文重新声明
响应式gap慎用vw,clamp()才是安全带
gap: 2vw看起来很“响应”,但实际在超宽屏(如 5K 显示器)下会把间距拉到离谱程度,而小屏手机又可能缩到看不见。这不是自适应,是失控。
立即学习“前端免费学习笔记(深入)”;
- 正确写法是
gap: clamp(0.5rem, 1.5vw, 1.5rem):确保最小不窒息、最大不溢出、中间段随视口平滑过渡 - 别对所有
gap都套clamp()——仅在卡片列表、表单字段组等视觉密度敏感区域启用;标题区、按钮组这类强调节奏感的地方,用固定rem更稳 - 测试时重点看 320px 宽度(iPhone SE)和 3840px(4K)两个极端,
clamp()的三值边界是否真能兜住
真正难的不是写出clamp()或var(--space-4),而是团队所有人对“什么场景该用gap、什么必须退回到margin”有共识。变量只是工具,约束才是规范。


















