我想表扬josh3736的答案,他提供了一些出色的历史背景。虽然表述清晰,但自这个问题被提出以来,CSS的情况已经发生了改变。当这个问题被提出时,px
是正确的答案,但今天不再是这样了。
简而言之:使用rem
单元概述
历史上,px
单位通常代表一个设备像素。随着设备像素密度越来越高,这对于许多设备(例如苹果的Retina显示屏)不再适用。
rem
单位表示根 em大小。它是与:root
匹配的任何内容的font-size
。在HTML的情况下,它是<html>
元素;对于SVG,它是<svg>
元素。每个浏览器*中的默认font-size
为16px
。
关于使用px
互联网上的大多数CSS示例都使用px
值,因为它们是事实上的标准。理论上可以使用pt
、in
和其他各种单位,但是它们在处理小值时效果不佳,因为您很快就需要使用分数,这些分数输入更长,且更难以理解。
如果你想要一个细边框,使用
px
可以使用
1px
,而使用
pt
需要使用
0.75pt
来保持一致的结果,这并不是很方便。
使用 rem
rem
的默认值为 16px
并不能成为其使用的强有力的理由。写 0.0625rem
比写 0.75pt
更糟糕,那么为什么会有人使用 rem
呢?
rem
相对于其他单位有两个优势。
尊重用户喜好
浏览器缩放多年来发生了很大变化。历史上,许多浏览器只会扩大
字体大小
,但是当网站意识到他们美丽的像素完美设计在用户缩放时会出现问题时,这种情况迅速改变了。此时,浏览器会缩放整个页面,因此基于字体的缩放已经不再适用。
尊重用户的意愿并不是不可能的。仅因为浏览器默认设置为
16px
,并不意味着任何用户不能更改其首选项为
24px
或
32px
以纠正低视力或视力差(例如屏幕反光)。如果您的单位基于
rem
,则任何使用更高字体大小的用户都将看到比例更大的网站。边框将更大,填充将更大,边距将更大,所有内容都会流畅地缩放。
如果您基于
rem
设置媒体查询,您还可以确保用户看到的网站适合他们的屏幕。在宽度为
640px
的浏览器上将
font-size
设置为
32px
的用户,实际上将看到您网站中
320px
宽浏览器上
16px
大小的用户所看到的内容。在使用
rem
时,响应式网页设计(RWD)不会有任何损失。
更改表现为px
的值
因为rem
基于:root
节点的font-size
,如果要更改1rem
表示的内容,只需更改font-size
即可:
:root {
font-size: 100px;
}
body {
font-size: 1rem;
}
<p>Don't ever actually do this, please</p>
无论你做什么,都不要将
:root
元素的
font-size
设置为
px
值。
如果你将
html
上的
font-size
设置为
px
值,那么你就没有办法恢复用户的首选项。
如果你想改变
rem
的表现值,使用
%
单位即可。
这个数学问题相当简单。
:root
的表现字体大小为
16px
,但我们想将其更改为
20px
。我们只需要用某个值乘以
16
即可得到
20
。
设置你的方程式:
16 * X = 20
并解决 X
的值:
X = 20 / 16
X = 1.25
X = 125%
:root {
font-size: 125%;
}
<p>If you're using the default font-size, I'm 20px tall.</p>
将所有内容都以20
的倍数进行并不是很好,但一个常见的建议是使rem
的表现大小等于10px
。这个魔法数字是10/16
,即0.625
或62.5%
。
:root {
font-size: 62.5%;
}
<p>If you're using the default font-size, I'm 10px tall.</p>
现在的问题是,页面中其余部分的默认字体大小设置得太小了,但有一个简单的解决方法:使用
rem
在
body
上设置
font-size
。
:root {
font-size: 62.5%;
}
body {
font-size: 1.6rem;
}
<p>I'm the default font-size</p>
重要的是要注意,在进行这个调整后,
rem
的表现值为
10px
,这意味着你可能在
px
中编写的任何值都可以通过增加小数点来直接转换为
rem
。
padding: 20px;
变成
padding: 2rem;
您选择的显式字号取决于您自己,因此,如果您希望,就没有理由不能使用以下内容:
:root {
font-size: 6.25%;
}
body {
font-size: 16rem;
}
并且 1rem
等于 1px
。
所以,你现在懂了,这是一种尊重用户意愿的简单解决方案,同时避免了过度复杂化你的 CSS。
等等,那么有什么问题吗?
我知道你会问这个问题。尽管我想假装rem
是魔法并可以解决所有问题,但仍然有一些需要注意的问题。在我看来,并没有太大的问题,但我还是要提出来,这样你就不能说我没有警告你。
媒体查询(使用em
)
rem
的第一个问题涉及媒体查询。考虑以下代码:
:root {
font-size: 1000px;
}
@media (min-width: 1rem) {
:root {
font-size: 1px;
}
}
这里的rem
值取决于媒体查询是否适用,而媒体查询又取决于rem
的值,所以到底发生了什么?
媒体查询中的rem
使用font-size
的初始值,不应该(请参见Safari部分)考虑对:root
元素的font-size
进行的任何更改。换句话说,它的实际值始终为16px
。
这有点烦人,因为这意味着你必须进行一些小数计算,但我发现大多数常见的媒体查询已经使用了16的倍数值。
| px | rem |
+------+-----+
| 320 | 20 |
| 480 | 30 |
| 768 | 48 |
| 1024 | 64 |
| 1200 | 75 |
| 1600 | 100 |
此外,如果您正在使用CSS预处理器,则可以使用mixin或变量来管理媒体查询,这将完全掩盖该问题。
Safari
不幸的是,Safari存在已知的错误,其中对于
:root
字体大小的更改实际上会更改计算出的媒体查询范围的
rem
值。如果在媒体查询中更改
:root
元素的字体大小,则可能会导致一些非常奇怪的行为。幸运的是,修复方法很简单:
使用em
单位进行媒体查询。
上下文切换
如果您在各种不同的项目之间切换,则
rem
的表观字体大小可能具有不同的值。在一个项目中,您可能会使用看起来像
10px
的表观大小,在另一个项目中,表观大小可能是
1px
。这可能会导致混淆和问题。
我唯一的建议是坚持使用
62.5%
将
rem
转换为表观大小为
10px
,因为在我的经验中,这更为常见。
共享 CSS 库
如果你正在编写 CSS,将其用于一个你无法控制的网站上,例如嵌入式小部件,那么很难知道 rem
的大小。如果是这种情况,请继续使用 px
。
如果你仍然想使用 rem
,可以考虑发布一个 Sass 或 LESS 版本的样式表,并提供一个变量来覆盖 rem
大小的缩放。
* 我不想吓到任何人使用rem
,但我无法正式确认每个浏览器都默认使用16px
。你知道,有很多浏览器,其中一个浏览器稍微偏离一点,比如说15px
或18px
,这并不难。然而,在测试中,我没有看到一个浏览器在使用默认设置的系统中使用默认设置时具有16px
以外的任何值。如果您发现这样的例子,请与我分享。