我正在设计一个新的网站,我希望它能与尽可能多的浏览器和浏览器设置兼容。我试图决定我应该使用什么测量单位的字体和元素的大小,但我无法找到一个结论性的答案。

我的问题是:我应该在CSS中使用px还是rem ?

到目前为止,我知道使用px不兼容那些在浏览器中调整基本字体大小的用户。 我忽略了ems,因为与rem相比,它们在级联时维护起来更麻烦。 有人说rem是分辨率独立的,因此更可取。但也有人说,大多数现代浏览器对所有元素都一视同仁,所以使用px不是问题。

我问这个问题是因为关于CSS中最理想的距离度量有很多不同的意见,我不确定哪个是最好的。


当前回答

Josh3736的答案很好,但要在3年后提供一个对应的答案:

I recommend using rem units for fonts, if only because it makes it easier for you, the developer, to change sizes. It's true that users very rarely change the default font size in their browsers, and that modern browser zoom will scale up px units. But what if your boss comes to you and says "don't enlarge the images or icons, but make all the fonts bigger". It's much easier to just change the root font size and let all the other fonts scale relative to that, then to change px sizes in dozens or hundreds of css rules.

我认为对于某些图像使用px单位仍然是有意义的,或者对于某些布局元素,无论设计的规模如何,都应该始终保持相同的大小。

2012年josh3736发表他的回答时,Caniuse.com可能说只有75%的浏览器支持,但截至3月27日,他们声称93.78%的浏览器支持。在他们追踪的浏览器中,只有IE8不支持。

其他回答

我想赞扬josh3736的回答提供了一些优秀的历史背景。虽然这个问题已经很清楚地表达出来了,但自从这个问题被提出以来,CSS的前景在近五年内已经发生了变化。当这个问题被问到时,px是正确答案,但今天它不再成立。


Tl;dr:用rem

单位概述

历史上,px单位通常代表一个设备像素。随着设备的像素密度越来越高,这种方法不再适用于许多设备,比如苹果的Retina Display。

Rem单位代表根em大小。它是匹配root的字体大小。在HTML的情况下,它是< HTML >元素;对于SVG,它是< SVG >元素。每个浏览器的默认字体大小*是16px。

关于使用px

互联网上的大多数CSS示例都使用px值,因为它们是事实上的标准。Pt, in和其他各种单位在理论上都可以使用,但它们不能很好地处理小的值,因为你很快就需要求助于分数,这需要更长时间输入,而且很难推理。

如果你想要一个细边框,px你可以使用1px, pt你需要使用0.75pt来获得一致的结果,这不是很方便。

关于rem的使用

Rem的默认值16px并不是一个很好的使用理由。写入0.0625rem比写入0.75pt更糟糕,那么为什么有人会使用rem呢?

雷姆与其他单位相比有两方面的优势。

尊重用户偏好 你可以随意改变rem的表观px值

尊重用户偏好

多年来,浏览器缩放功能发生了很大变化。从历史上看,许多浏览器只会扩大字体大小,但当网站意识到他们漂亮的像素完美设计在任何时候都被放大或缩小时就会被破坏时,这种情况就会迅速改变。此时,浏览器会缩放整个页面,因此基于字体的缩放就不存在了。

尊重用户的意愿并不是不可能的。仅仅因为浏览器默认设置为16px,并不意味着任何用户不能将首选项更改为24px或32px以纠正低视力或低能见度(例如屏幕眩光)。如果您以rem为单位,那么任何字体大小较高的用户都会看到相应较大的站点。边界会更大,填充会更大,边际会更大,一切都将流动地扩大。

如果您的媒体查询基于rem,您还可以确保您的用户看到的网站适合他们的屏幕。如果用户在640px宽的浏览器上将字体大小设置为32px,那么在320px宽的浏览器上,用户将有效地看到以16px宽的字体显示的站点。在使用rem时,响应式网页设计(RWD)绝对没有损失。

改变表观px值

因为rem是基于:根节点的字体大小,如果你想改变1rem所代表的东西,你所要做的就是改变字体大小:

:根{ 字体大小:100 px; } 身体{ 字体大小:1快速眼动; } <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%

:根{ 字体大小:125%; } 如果你使用默认的字体大小,我是20px高

用20的倍数来做所有事情并不是很好,但一个常见的建议是让rem的表观大小等于10px。神奇的数字是10/16,也就是0.625,即62.5%。

:根{ 字体大小:62.5%; } 如果你使用默认的字体大小,我是10px高

现在的问题是,页面其余部分的默认字体大小设置得太小了,但有一个简单的解决方法:使用rem设置正文的字体大小:

:根{ 字体大小:62.5%; } 身体{ 字体大小:1.6快速眼动; } 我是默认的字体大小</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的值取决于是否应用media-query,而media查询取决于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有一个已知的bug,更改:root font-size实际上会更改媒体查询范围的计算rem值。如果在媒体查询中改变了:root元素的font-size,则会导致一些非常奇怪的行为。幸运的是,解决方法很简单:使用em单位进行媒体查询。

上下文切换

如果您在不同的项目之间切换,rem的表观字体大小很可能具有不同的值。在一个项目中,你可能会使用10px的表观大小,而在另一个项目中,表观大小可能是1px。这可能会让人困惑并导致问题。

在这里,我唯一的建议是坚持使用62.5%来将rem转换为10px的表观大小,因为在我的经验中,这是更常见的。

共享CSS库

如果您编写的CSS将用于您无法控制的站点,例如嵌入式小部件,那么实际上没有好方法知道rem的表观大小。如果是这种情况,可以继续使用px。

如果您仍然想使用rem,可以考虑使用一个变量发布样式表的Sass或LESS版本,以覆盖rem表观大小的缩放。


*我不想吓走任何人使用rem,但我还不能正式确认每个浏览器默认使用16px。你看,有很多浏览器,对于一个浏览器来说,稍微偏离15px或18px并不难。然而,在测试中,我还没有看到一个使用默认设置的浏览器在使用默认设置的系统中有16px以外的值的例子。如果你发现了这样的例子,请分享给我。

pt类似于rem,因为它相对固定,但几乎总是与dpi无关,即使不兼容的浏览器以依赖于设备的方式对待px。rem随根元素的字体大小而变化,但您可以使用Sass/Compass之类的工具自动使用pt来完成此操作。

如果你有这个:

html {
    font-size: 12pt;
}

那么1rem总是12pt。Rem和em仅仅像它们所依赖的元素那样与设备无关;有些浏览器不按照spec行事,按字面意思对待px。即使在过去的网络时代,1点也一直被认为是1/72英寸——也就是说,一英寸有72个点。

如果你有一个旧的,不兼容的浏览器,你有:

html {
    font-size: 16px;
}

那么1rem是与电子器件相关的。对于默认情况下从html继承的元素,1em也依赖于设备。12pt应该是与设备无关的同等内容:16px / 96px * 72pt = 12pt,其中96px = 72pt = 1英寸。

如果你想坚持使用特定的单位,计算起来会很复杂。例如,html的.75em = .75rem = 9pt, html的.75em = .5rem = 6pt。一个很好的经验法则:

Use pt for absolute sizes. If you really need this to be dynamic relative to the root element, you're asking too much of CSS; you need a language that compiles to CSS, like Sass/SCSS. Use em for relative sizes. It's pretty handy to be able to say, "I want the margin on the left to be about the maximum width of a letter," or, "Make this element's text just a bit bigger than its surroundings." <h1> is a good element on which to use a font size in ems, since it might appear in various places, but should always be bigger than nearby text. This way, you don't have to have a separate font size for every class that's applied to h1: the font size will adapt automatically. Use px for very tiny sizes. At very small sizes, pt can get blurry in some browsers at 96 DPI, since pt and px don't quite line up. If you just want to create a thin, one-pixel border, say so. If you have a high-DPI display, this won't be obvious to you during testing, so be sure to test on a generic 96-DPI display at some point. Don't deal in subpixels to make things fancy on high-DPI displays. Some browsers might support it--particularly on high-DPI displays--but it's a no-no. Most users prefer big and clear, though the web has taught us developers otherwise. If you want to add extended detail for your users with state-of-the-art screens, you can use vector graphics (read: SVG), which you should be doing anyway.

Josh3736的答案很好,但要在3年后提供一个对应的答案:

I recommend using rem units for fonts, if only because it makes it easier for you, the developer, to change sizes. It's true that users very rarely change the default font size in their browsers, and that modern browser zoom will scale up px units. But what if your boss comes to you and says "don't enlarge the images or icons, but make all the fonts bigger". It's much easier to just change the root font size and let all the other fonts scale relative to that, then to change px sizes in dozens or hundreds of css rules.

我认为对于某些图像使用px单位仍然是有意义的,或者对于某些布局元素,无论设计的规模如何,都应该始终保持相同的大小。

2012年josh3736发表他的回答时,Caniuse.com可能说只有75%的浏览器支持,但截至3月27日,他们声称93.78%的浏览器支持。在他们追踪的浏览器中,只有IE8不支持。

是的。或者,更确切地说,没有。

呃,我是说,没关系。使用对您的特定项目有意义的方法。PX和EM或两者都有效,但根据整个页面的CSS架构的不同,它们的行为会有所不同。

更新:

为了澄清,我的意思是,通常情况下,使用哪一种并不重要。有时,您可能特别希望选择其中一种。如果你可以从头开始,想要使用基本字体大小,并使所有内容都与之相关,那么EMs是很好的。

当您在现有代码基础上进行重新设计时,通常需要px,并且需要px的专一性来防止糟糕的嵌套问题。

一半(但只有一半)尖刻的回答(另一半是对官僚主义现实的痛苦蔑视):

使用vh

一切都是浏览器窗口的大小。

总是允许向下滚动,但禁用水平滚动。

将主体宽度设置为静态50vh,并且永远不要编写浮动或跳出父div的css(如果他们试图模拟一些看起来像这样的东西,聪明地使用背景gif会让他们偏离轨道)。样式只使用表,所以所有东西都按照预期严格地保持在适当的位置。包括一个javascript函数来撤销用户可能做的任何ctrl+/-活动。

用户会讨厌你,因为网站不会因为他们使用的内容而发生变化(比如文本太小,在手机上无法阅读)。你的同事会讨厌你的,因为没有哪个头脑正常的人会这么做,这很可能会影响他们的工作(当然不会影响你的工作)。你的编程教授会讨厌你,因为这不是一个好主意。你的用户体验设计师会讨厌你,因为这将暴露他们在设计用户体验模型时为了赶在最后期限前做的事情。

几乎所有人都会讨厌你,除了那些告诉你要让东西与模型匹配并快速这么做的人。然而,这些人(通常包括项目经理)会为你的准确性和快速周转时间而欣喜若狂。每个人都知道他们的意见是唯一影响你薪水的因素。