em 和 rem 到底差在哪,改字号为什么会翻倍?

4 个讲解板块 · 关联 3 款站内工具 · 内容最后核对 2026-10-09

em 参照父元素字号、多层嵌套会连乘,rem 只参照根元素、写在哪儿都一样。

直接答案

差别只有一个字:参照物。em 看的是「这里当前的字号是多少」,对字号属性本身来说就是父元素的字号,对内外边距这类属性来说则是元素自身的字号;而 rem 永远看根元素的字号。因为参照物会随层级变化,em 就会连乘:三层都写一点二倍,最终是一点二的三次方,也就是 1.728 倍,而不是一点二倍。

这个性质决定了它们各自的主场。em 适合组件内部的相对比例,比如按钮的内边距,按钮字号一变,内边距跟着等比变化,只改一个值就能整体缩放。rem 适合控制页面尺度,比如标题字号、区块间距、容器宽度,无论元素嵌得多深,一点五 rem 永远是同一个尺寸,不会因为某层容器改了字号而意外变小。

不少人有过这样的经历:给列表项写了字号,结果第三层嵌套的文字小到看不清。这不是浏览器出了错,而是 em 在按层级连乘,每一层都把上一层的缩小幅度又缩了一次。

理解这件事只需要记住两个参照点:em 参照就近的父级,rem 参照根节点。剩下的所有差异都是这一条推出来的。

1一表看清参照物

三个单位放在一起比,差别立刻显形。

单位参照物嵌套是否连乘是否随用户设置字号变化
em父元素字号(字号属性)/ 自身字号(其他属性)会连乘会
rem根元素字号,全页面统一不会会
px固定像素,无参照不会不会,这是它最大的缺点

把根元素字号设成百分数而不是固定像素,用户的字号偏好才能继续生效。设成固定像素会屏蔽掉这项无障碍设置。

2连乘是怎么发生的

用一组数字把这件抽象的事变具体。

写法第一层第二层第三层
每层 1.2em1.2 倍1.44 倍1.728 倍
每层 0.9em0.9 倍0.81 倍0.729 倍
每层 1.2rem1.2 倍1.2 倍1.2 倍
每层固定像素固定值固定值固定值
放大也会失控
每层写一点二倍,三层下来字号涨了七成多,标题会撑破容器。
缩小更隐蔽
每层写零点九倍,三层后只剩原来的七成,用户在深色主题下更难看清。
混合使用最常见
父层用 em、子层用 rem,是最不容易出错也最容易读懂的组合。

3媒体查询里两者其实一样

这一条反转了很多人的直觉。

媒体查询不看你设的根字号
规范规定媒体查询里的相对单位按字号初始值解析,所以你把根字号设小、写了四十个 rem 的断点,断点仍按默认字号换算,也就是 640 像素。
不要在媒体查询里做单位换算
想精确控制断点位置,直接写像素或用明确的比例,不要指望靠改根字号来挪动断点。
被查询的样式里则照常生效
断点条件内的规则仍按正常规则解析单位,两者别搞混。

4按用途分配就对了

不用纠结谁更好,按场景分工最省心。

要页面尺度统一,用 rem
标题、正文、块间距、容器最大宽度,这些都属于页面级别的尺度。
要组件内部等比缩放,用 em
按钮或标签的内边距、图标与文字的间距,跟着组件自身字号走更自然。
要绝对不变,用像素
一像素的边框、阴影偏移、极小的圆角,这些不该随字号变化。
换算时记住十六这个基数
默认根字号是十六像素,零点八七五 rem 是十四像素,一点五 rem 是二十四像素;想改成十进制心智模型可以设根字号为六成二五,但记得媒体查询不受影响。

相关疑问

为什么我写了 em 之后,嵌套列表越来越小?

因为 em 参照父元素的字号,父级缩小后子级是在缩小过的字号上再缩一次,逐层累乘。解决办法是把字号这类应该统一的值改用 rem,只把组件内部需要等比的间距留给 em。

rem 会不会受用户改浏览器字号影响?

会,这正是它的优点。用户把默认字号调大后,用 rem 定义的文字会一起变大,用像素定义的文字则保持不变。这也是无障碍规范建议文字尺寸用相对单位的原因。

根字号设成 10px 好不好?

换算会变简单,一点六 rem 就是十六像素,但用固定像素设置根字号会让用户的字号偏好失效。更稳妥的做法是设成百分数,既保留换算的便利,又不屏蔽用户设置。

媒体查询里的 rem 为什么和正文里的不一样?

因为规范规定媒体查询中的相对单位按字号初始值解析,不受你在样式里给根元素设的值影响。所以断点位置不会随根字号变化,想调整断点就直接改那个数值,别绕道去改根字号。

内容标识:本页内容由人工智能辅助生成,并经人工核对与编辑。详见 人工智能生成内容标识说明。
内容说明:本页针对具体使用问题作答,方法步骤与数值由本站自行整理与复算,事实性内容以对应官方规范与文档为准。内容最后核对日期:2026-10-09。若发现错误,欢迎通过页脚反馈入口告知。