我应该在CSS中使用px或rem值单位吗?

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

我的问题是:我应该使用pxrem在我的CSS?

  • 到目前为止,我知道使用px不兼容那些在浏览器中调整基本字体大小的用户。
  • 我忽略了__abc0,因为与__abc1相比,它们在级联时维护起来更麻烦。
  • 有人说__abc是分辨率独立的,因此更可取。但其他人说,大多数现代浏览器无论如何都会平等地缩放所有元素,所以使用px不是问题。

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

269529 次浏览

我发现对网站字体大小进行编程的最好方法是为body定义基本字体大小,然后对此后声明的所有其他font-size使用em's(或rem's)。我想这是我的个人喜好,但它对我很有帮助,也让我很容易融入更多响应设计

至于使用rem单元,我认为在代码的渐进性和对旧浏览器的支持之间找到一个平衡是很好的。看看这个关于浏览器支持rem单元的链接,这应该有助于你的决定。

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

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

更新:

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

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

这篇文章很好地描述了pxemrem的优缺点。

作者最后得出结论,最好的方法可能是同时使用pxrem,对于较老的浏览器先声明px,对于较新的浏览器重新声明rem:

html { font-size: 62.5%; }
body { font-size: 14px; font-size: 1.4rem; } /* =14px */
h1   { font-size: 24px; font-size: 2.4rem; } /* =24px */

TL;博士:使用px

事实

  • 首先,非常重要的是要知道每一个规格, CSS的px单元等于一个物理显示像素。这已经总是是真的-即使在1996年的CSS 1规范

    CSS定义了参考像素,它测量96 dpi显示器上像素的大小。在dpi与96dpi有本质差异的显示器(如Retina显示器)上,用户代理重新缩放px单元,使其大小与参考像素相匹配。换句话说,这种重新缩放正是为什么1个CSS像素等于2个物理视网膜显示像素。

    也就是说,直到2010年(尽管有移动缩放的情况),px几乎总是等于一个物理像素,因为所有广泛使用的显示器都在96dpi左右。

  • ems中指定的大小是相对的到父元素。这就导致了em的“复合问题”。其中嵌套元素逐渐增大或减小。例如:

      body { font-size:20px; }
    div { font-size:0.5em; }
    

    给我们:

      <body> - 20px
    <div> - 10px
    <div> - 5px
    <div> - 2.5px
    <div> - 1.25px
    
  • CSS3 rem总是只相对于根元素html,现在在99.67%的浏览器在使用中上被支持。

意见

我想每个人都同意,设计你的页面是很好的,以适应每个人,并考虑到视力受损。其中一个需要考虑的问题(但不是唯一的!)是允许用户将网站的文本变大,这样就更容易阅读。

一开始,为用户提供缩放文本大小的唯一方法是使用相对大小单位(例如ems)。这是因为浏览器的字体大小菜单只是改变了根字体大小。因此,如果你在px中指定字体大小,它们在更改浏览器的字体大小选项时不会缩放。

现代浏览器(甚至不那么现代的IE7)都改变了默认的缩放方法,只需要放大所有内容,包括图像和盒子大小。本质上,它们使参考像素变大或变小。

是的,有人仍然可以改变他们的浏览器默认样式表来调整默认字体大小(相当于老式字体大小选项),但这是一种非常深奥的方式,我敢打赌没有人__abc0会这样做。(在Chrome中,它被隐藏在高级设置、网页内容、字体大小下面。在IE9中,它更加隐蔽。你必须按Alt键,然后去查看,文本大小。)在浏览器的主菜单中选择缩放选项(或使用Ctrl++/-/鼠标滚轮)要容易得多。

1 -在统计误差之内,自然

如果我们假设大多数用户使用缩放选项缩放页面,我发现相对单位基本上是不相关的。当所有东西都指定在同一个单位(图像都以像素为单位处理)时,开发页面要容易得多,而且不必担心复合。(“我被告知不会有数学”; -需要计算1.5em的实际值。)

仅使用相对单位表示字体大小的另一个潜在问题是,用户调整字体大小可能会破坏布局的假设。例如,这可能会导致文本被剪切或运行太长。如果你使用绝对单位,你不必担心意外的字体大小会破坏你的布局。

所以我的答案是使用像素单位。我使用px来处理所有事情。当然,你的情况可能会有所不同,如果你必须支持IE6(愿rfc的上帝怜悯你),你无论如何都必须使用__abc1。

pt类似于rem,因为它是相对固定的,但几乎总是dpi独立的,即使不兼容的浏览器以依赖于设备的方式对待pxrem随根元素的字体大小而变化,但你可以使用Sass/Compass之类的东西来自动使用pt

如果你有这个:

html {
font-size: 12pt;
}

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

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

html {
font-size: 16px;
}

那么1rem将是设备相关的。对于默认情况下继承自html的元素,1em也依赖于设备。12pt将是希望保证的与设备无关的对等物:16px / 96px * 72pt = 12pt,其中96px = 72pt = 1in

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

  • 使用pt表示绝对大小。如果你真的需要它相对于根元素是动态的,你对CSS的要求太高了;你需要一种可以编译成CSS的语言,比如Sass/SCSS。
  • 相对大小使用em可以很方便地说,“我想让左边的边距大约是一个字母的最大宽度”,或者“让这个元素的文本比它周围的环境稍大一点”。<h1>是一个在ems中使用字体大小的好元素,因为它可能出现在不同的地方,但应该总是比附近的文本大。这样,就不必为应用于h1的每个类都设置单独的字体大小:字体大小将自动调整。
  • 对于非常小的尺寸使用px在非常小的尺寸下,在96 DPI的某些浏览器中,pt可能会变得模糊,因为ptpx并没有完全对齐。如果你只是想创建一个单薄的单像素边框,那就直说。如果你有一个高dpi显示器,在测试过程中这对你来说不会很明显,所以一定要在某个时候测试一个通用的96 dpi显示器。
  • 不要在高dpi显示器上处理子像素来制造花哨的东西。一些浏览器可能支持它——特别是在高dpi显示器上——但这是一个禁忌。大多数用户喜欢大而清晰,尽管web教会了我们开发人员其他方面。如果您想用最先进的屏幕为用户添加扩展细节,您可以使用矢量图形(即SVG),无论如何您都应该这样做。

作为条件反射的回答,我建议使用rem,因为它允许您在必要时一次性更改整个文档的“缩放级别”。在某些情况下,当您希望大小相对于父元素时,请使用em。

rem支持是不稳定的,IE8需要一个polyfill, Webkit显示一个错误。此外,亚像素计算有时会导致单像素线等内容消失。补救办法是对这些非常小的元素进行像素编码。这就带来了更多的复杂性。

所以,总的来说,问问自己这样做是否值得——在CSS中改变整个文档的“缩放级别”有多重要,有多可能?

有些情况下答案是肯定的,有些情况下答案是否定的。

因此,这取决于您的需求,您必须权衡利弊,因为使用rem和em与“正常的”基于像素的工作流相比引入了一些额外的考虑因素。

请记住,它很容易切换(或更确切地说转换)你的CSS从px到rem (JavaScript是另一个故事),因为下面两个CSS代码块将产生相同的结果:

html {
}


body {
font-size:14px;
}


.someElement {
width: 12px;
}

html {
font-size:1px;
}


body {
font-size:14rem;
}


.someElement {
width: 12rem;
}

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

我建议使用rem单位的字体,如果只是因为它使开发人员更容易改变大小。确实,用户很少改变浏览器中的默认字体大小,而且现代浏览器缩放将扩大px单位。但如果你的老板对你说“不要放大图片或图标,而是把所有字体都放大”怎么办?只改变根字体大小并让所有其他字体相应地缩放要容易得多,然后在几十或数百个css规则中改变px大小。

我认为它仍然是有意义的使用px单位的某些图像,或某些布局元素,应该始终是相同的大小,而不管设计的规模。

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

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


tl;博士:使用rem

单位概述

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

rem单位代表root 新兴市场大小。它是匹配:rootfont-size。在HTML中,它是<html>元素;对于SVG,它是<svg>元素。每个浏览器的默认font-size *是16px

关于使用px

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

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

关于使用rem

rem的默认值16px对于它的使用并不是一个非常强大的参数。写0.0625rem比写0.75pt更糟糕的是,那么为什么会有人使用rem呢?

rem与其他单元相比有两个优势。

  • 尊重用户偏好
  • 你可以将rem的显式px值更改为你想要的任何值

尊重用户偏好

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

尊重用户的意愿并不是不可能的。仅仅因为浏览器默认设置为16px,并不意味着任何用户不能将他们的首选项更改为24px32px来纠正低视力或低能见度(例如屏幕眩光)。如果你的单位基于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>

Whatever you do, don't set the :root element's font-size to a px value.

If you set the font-size on html to a px value, you've blown away the user's preferences without a way to get them back.

If you want to change the apparent value of rem, use % units.

The math for this is reasonably straight-forward.

The apparent font-size of :root is 16px, but lets say we want to change it to 20px. All we need to do is multiply 16 by some value to get 20.

Set up your equation:

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>

Doing everything in multiples of 20 isn't all that great, but a common suggestion is to make the apparent size of rem equal to 10px. The magic number for that is 10/16 which is 0.625, or 62.5%.

:root {
font-size: 62.5%;
}
<p>If you're using the default font-size, I'm 10px tall.</p>

The problem now is that your default font-size for the rest of the page is set way too small, but there's a simple fix for that: Set a font-size on body using rem:

:root {
font-size: 62.5%;
}


body {
font-size: 1.6rem;
}
<p>I'm the default font-size</p>

It's important to note, with this adjustment in place, the apparent value of rem is 10px which means any value you might have written in px can be converted directly to rem by bumping a decimal place.

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有一个已知的错误,即更改:root字体大小实际上会更改媒体查询范围的计算rem值。如果在媒体查询中改变了:root元素的字体大小,这可能会导致一些非常奇怪的行为。幸运的是,修复很简单:使用em单位进行媒体查询

上下文切换

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

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

共享CSS库

如果你写的CSS将被用在一个你不能控制的网站上,比如一个嵌入式小部件,真的没有好办法知道rem的表观大小。如果是这种情况,请继续使用px

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


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

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

使用vh

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

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

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

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

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

是的,REM和PX是相对的然而其他的答案已经建议在PX上进行REM,我也想用一个可访问性的例子来支持这一点。
当用户在浏览器上设置不同的字体大小时,REM会自动放大或缩小网页上的字体、图像等元素,而PX则不会这样


在下面的gif中,左侧文本使用REM单位设置字体大小,而右侧字体使用PX单位设置。

enter image description here

正如你所看到的,当我调整大小时,REM会自动缩放 网页的默认字体大小。(右下方)< / p >

网页的默认字体大小是16px,等于1 rem(只适用于默认的html页面,即html{font-size:100%}),因此,1.25rem等于20px

附注:还有谁在使用REM?CSS框架!像Bootstrap 4, Bulma CSS等,所以最好与它相处。