不能只靠 scss 变量(如 $spacing-xs: 4px)定义间距,因其编译为静态像素值,无法响应设备像素比、视口变化、字体缩放等运行时条件;必须结合语义化等级、相对单位(如 vmin/rem)与 calc()/max() 在 css 层动态计算。

直接结论:用 SCSS 变量 + 基础单位映射 + calc() 运行时组合,而不是只靠 Sass 算术生成固定值。
为什么不能只靠 $spacing-xs: 4px 这类变量?
这类纯数值变量在多设备场景下会迅速失效——4px 在 Retina 屏上肉眼几乎不可见,24px 在小屏手机上可能撑满半屏。SCSS 编译后输出的是静态值,它不感知设备像素比、视口宽度、用户缩放或 root font-size 变化。
常见翻车点:
- 在
@media (max-width: 768px)里写margin: $spacing-lg * 0.7;→ 编译后仍是固定像素,没解决“小屏需更紧凑”的本质问题 - 把所有间距写成
rem却没统一控制html { font-size }→ 各端表现不一致 - 混用
px和vh做运算(如16px + 2vh)→ SCSS 直接报错
推荐的三层标尺结构:基础单位、响应层、运行时层
真正可落地的跨设备间距体系,必须分层协作:
-
基础单位层:定义语义化间距等级,不带具体单位
$space-xxs: 0.25;$space-xs: 0.5;$space-sm: 1;$space-md: 1.5;$space-lg: 2;$space-xl: 3; -
响应层:用
@function将等级转为相对单位(如rem或vmin)@function space($level) { @return $level * 1rem; }@function space-fluid($level) { @return calc(#{$level} * 1vmin); } -
运行时层:在 CSS 规则中组合使用,交由浏览器计算
padding: space-fluid($space-md) space-fluid($space-lg);margin-bottom: max(space-fluid($space-sm), 8px);
移动端适配的关键细节:vmin 与 max() 的配合
vmin 比 vw 更稳,它取视口宽高中的较小值,避免窄屏文字被压扁、宽屏间距过大。但纯 vmin 在极小屏(如折叠屏半开态)下仍可能过小,必须兜底。
- 单方向声明更可靠:
padding-top: calc(2vmin + 4px);比padding: calc(2vmin + 4px);少出 bug - 用
max()设硬性下限:margin: max(calc(1.5vmin + 2px), 12px); - 老浏览器不支持
max()?加媒体查询兜底:@media (min-width: 414px) { margin: 12px; } - 别在
gap里用calc()—— Grid/Flex 的gap属性目前不支持函数表达式,必须拆成padding或margin
CRMEB uni-scss 中的实践参考
CRMEB 商城移动端的 uni-scss 插件实际采用的是「固定 rem 基准 + 语义化变量」路线,比如:$--spacing-sm: 12rpx;(rpx 是 uni-app 的响应式单位,1rpx = 1/750 * 屏幕宽度)。它的优势是简单、兼容性强;缺点是无法动态响应字体缩放或系统级放大设置。
如果你项目已用 uni-app,可直接复用其 rpx 体系:.u-mt-sm { margin-top: $--spacing-sm; }
但注意:rpx 不是标准 CSS 单位,导出 H5 或小程序转 Web 时需额外处理。
真正容易被忽略的一点:标尺不是越“智能”越好。很多团队在早期强行塞入 clamp()、container queries 或 JS 动态注入,结果调试成本飙升、CI 构建失败频发。先用好 vmin + max() 组合覆盖 90% 场景,再按需升级——这才是可维护的起点。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











