先记住这个答案
rem 适合建立全站尺度,em 适合让局部间距随组件字号变化;视口单位则跟窗口尺寸走。比如按钮内边距用 em,字号变化时按钮比例还算协调,但嵌套元素的 em 可能逐层放大。做流体字号时可用含 rem 的 clamp() 给出可访问的上下限,并实测浏览器缩放。
rem跟根字号变化em可跟组件字号变化vw跟视口宽度变化- 流体字号要设合理上下限
标题和按钮分别跟谁缩放
一个文章标题希望在手机上不过大,桌面上稍微放大。用 font-size: clamp(1.5rem, 1rem + 2vw, 3rem) 给它下限、变化段和上限;正文仍以 rem 为主,保证用户改根字号时整体能响应。按钮内边距若希望跟按钮文字一起长大,可以考虑 em。不要把所有尺寸都改成 vw,否则用户缩放文字或在很宽的屏幕上阅读时容易失控。
.article-title {
font-size: clamp(1.5rem, 1rem + 2vw, 3rem);
line-height: 1.2;
}
.button { padding: 0.6em 1em; /* 跟随按钮字号 */ }
.article { max-width: 70rem; /* 控制长行宽度 */ }rem 依赖根字体尺寸;em 用在 font-size 上时相对父元素字号,用在该元素其他属性上通常相对元素自身计算字号,嵌套时要特别注意。
示例的大标题用了 clamp(),但它仍可能在很窄的卡片里换行到四五行;字号计算只解决数值范围,不保证布局容得下。按钮内边距用 em 会跟随按钮自己的字号,触控面积也会变化,仍要检查最小点击区域。.article 的最大宽度用 rem 是整体节奏选择;如果根字号由用户放大,文章行宽也会相应变化。
三种单位对应不同基准
视口单位依据视口尺寸,不直接代表用户的字体偏好。clamp() 会在最小、首选和最大值之间取合适结果,首选值里可混合 rem 与 vw,让流体变化同时保留与字号设置的联系。单位选择应对应“跟谁变化”这个设计问题。
em 有一个常见陷阱:它在 font-size 上通常相对于父元素字体大小,而在同一元素的 padding 上依据该元素计算后的字体大小。把两者一并按“永远相对父级”理解,嵌套组件就会被放大得出乎意料。调试时在 DevTools 看计算值和继承链,必要时用 rem 固定跨组件尺度,只让局部内边距跟组件文字变化。
容易答错的地方
- 说
em永远相对父元素 font-size上通常以父字号为基准,其他属性的em通常以元素自身的计算字号为基准。- 用纯
vw设置全部字号 - 视口变化不等于阅读需求,给字号上下限并测试文字缩放更稳。
面试官还会怎么问?
为什么 em 嵌套会越放越大?
若每层都用大于 1 的 em 设置字号,下一层会以已放大的父字号为基准。
rem 是否一定是 16px?
不是。它跟根元素的计算字号走,根字号可能由浏览器设置或页面样式改变。
何时用容器单位?
组件样式应跟随自身容器而非整个视口时,建立查询容器后可使用相应单位。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。