必须用scss函数封装字号阶梯,如@function calculate-scale($level, $base: 1.25rem, $ratio: 0.85),以支持主题变量、响应式断点及兼容性处理,避免硬编码导致维护困难。

字号阶梯必须用函数封装,不能硬编码
直接写 h1 { font-size: 2.5rem; }、h2 { font-size: 2rem; } 这类静态值,等于把排版逻辑锁死在样式表里。一旦设计系统要求「所有标题在移动端缩小10%」或「暗色模式下统一放大5%」,就得全局搜替换——错漏风险高,且无法响应式联动。SCSS 自定义函数才是唯一能集中控制字号缩放逻辑的出口。
@function calculate-scale($level, $base: 1.25rem, $ratio: 0.85) 的参数设计
这个函数不是炫技,而是为解决三个真实问题:层级递减是否线性、基准值能否被主题变量覆盖、缩放比是否支持微调。常见错误是把 $ratio 写成固定 0.8 或 0.9,结果 h4–h6 缩得太小,阅读困难。
-
$level必须是整数(1–6),用于计算指数衰减:pow($ratio, $level - 1) -
$base应对接设计系统的根字号变量,比如$type-base: 1rem,而非写死16px -
$ratio推荐设为0.85:实测 h1→h6 缩放后仍保持可读性,且视觉节奏自然;0.8会导致 h6 接近0.6rem,小屏下易糊
避免 pow() 在旧版 Dart Sass 中失效
Dart Sass 1.25+ 原生支持 pow(),但早期版本(如 1.15)会报错 Undefined function "pow"。别急着升级编译器,用更稳妥的替代方案:
- 手动展开:对 h1–h6 分别定义缩放系数数组
$scales: 1, 0.85, 0.7225, 0.6141, 0.522, 0.4437,再用nth($scales, $level) - 用循环预计算:在顶层用
@for $i from 1 through 6把各阶结果存进 map,函数只做查表 - 不依赖
pow()的线性公式:$base * (1.2 - $level * 0.15),虽不够优雅但兼容性零风险
响应式字号阶梯要分断点重算,不能套一层 media
在 @for 循环里直接写 @media (max-width: 768px) { font-size: calculate-scale($i, 1.125rem); } 看似简洁,实际会为每个 h1–h6 生成独立媒体查询块,CSS 体积翻 6 倍,且破坏浏览器的媒体查询合并机制。
正确做法是提取断点字号数组:
$heading-sizes-sm: 1.5rem, 1.25rem, 1.125rem, 1rem, 0.875rem, 0.8125rem;
@for $i from 1 through 6 {
h#{$i} {
font-size: nth($heading-sizes-sm, $i);
}
}
这样既保持编译后 CSS 干净,又允许设计师在数组里单独调整某一级(比如 h3 在小屏下不缩小,保持 1.125rem)。
真正难的不是写函数,而是让字号阶梯同时满足设计一致性、可维护性和浏览器渲染效率——这三个目标常互相冲突,得靠函数参数暴露可控点,而不是藏在 magic number 里。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











