媒体查询:PX vs EM vs REM

15

有人能解释一下为什么我将媒体查询从px转换成em后它们会出问题吗?

在文档的正文中,我包含了以下规则:font-size: 62.5%。因此,我认为我可以将我的媒体查询从650px转换为65em?但是当我将媒体查询转换为em时,布局就出错了。

作为一个替代方案,我能否将媒体查询转换为带有像素回退的REMS?但是,我不知道该怎么做。

@media screen and (min-width: 650px) {     
  body {
    font-size: 62%;
    background-color: #364759;
    background-repeat: repeat-x;
    background: url("bg.gif");
  }
    
  #wrapper, footer {
    width: 80%;
    max-width: 1050px;
    margin: 0 auto;
  }
} // end media query 

非常感谢,P


3
问题在于媒体查询并不从页面主体获取其“基准大小”,而是从UA或用户首选项设置中获取。改变页面主体的字体大小对媒体查询的基准字体大小没有影响。 - Jesse Kernaghan
3个回答

32

媒体查询规范的第1.3节中指出:

 

媒体查询中的相对单位基于初始值,这意味着单位永远不会基于声明的结果。例如,在HTML中,em单位是相对于用户代理或用户喜好定义的font-size的初始值,而不是页面上的任何样式。

同样,第2节也是这样说的:

 

除非另一个功能明确指定它影响媒体查询的分辨率,否则没有必要应用样式表以评估表达式。

因此,你的font-size: 62.5%规则在媒体查询方面没有影响,1em仍然是16px,而不是10px

之所以这样做是因为反之会导致循环,而这是CSS无法处理的。试想一下,如果没有这条规则,这个例子会发生什么:

body { font-size: 10000px; }
@media (min-width: 1em) {
  body { font-size: 1px; }
}

1em会变得巨大,所以媒体查询会匹配,因此1em会变小,所以媒体查询不会匹配,所以1em会变得巨大,如此循环。


1
我今天早些时候考虑过这个问题,然后突然想到:“他们可能有一个规定” - 我在6个小时后找到了答案,谢谢! - SidOfc

8

这是一篇很棒的文章,将帮助解释px/em/rem之间的区别。

https://www.futurehosting.com/blog/web-design-basics-rem-vs-em-vs-px-sizing-elements-in-css/

此外,以下内容可能会有用:https://css-tricks.com/rems-ems/

编辑

由于@Jesse Kernaghan评论说上面的链接容易损坏,因此我将概述PX与EM与REM之间的差异。

px

像素是绝对测量单位,这意味着它们的大小不受其他任何东西的影响。实际上,它们在各处的长度并不相同,因为特定设备对它们的处理方式不同,但在每个设备上像素始终相同。您笔记本电脑显示器上的16px与您的iPad上的16px不同。 像素是绝对的但不一致的。

em

px是长度的绝对度量时,em相对于父元素的字体大小。 以以下示例为例:

div{ font-size: 22px; }
p{ width: 200em; margin: 3em; font-size: 0.8em;}

<div>
    <p>Some text</p>
</div>

现在,如果您想将 p 元素的大小减半,只需要将周围的 <div> 的字体大小更改为 11px 即可。这种度量单位在响应式布局中非常有用。
然而,em 存在问题。因为所有元素都是相对于其父级调整大小,所以随着元素嵌套,em 的含义也会改变。如果您扩展上面的示例并在 <p> 中嵌套一个具有 0.5em 字体大小的 <blockquote>,则结果可能不是预期的结果。结果将是 <p> 的字体大小等于 11px,但是 <blockquote> 的字体大小将再次减半,因为 em 是相对于直接祖先 (<p>) 而不是 <div> 的。 rem

Rems(根em)类似于em,但它们始终相对于<html>元素的font-size。不管一个元素嵌套多深都没有关系。

结论

所以,通过简短的解释,Chris Coyier在他的文章https://css-tricks.com/rems-ems/中提出了一个基本概念。它基本上概述了设置基本的html字体大小,然后使用px进行媒体查询调整(请记住,这是绝对测量)。在这些媒体查询内,一切您要做的就是缩小字体大小。然后您使用rem设置主要元素,并使用需要与主要元素一起缩放的元素使用em。Chris Coyier的代码示例如下:

/* Document level adjustments */
html {
  font-size: 17px;
}
@media (max-width: 900px) {
  html { font-size: 15px; }
}
@media (max-width: 400px) {
  html { font-size: 13px; }
}

/* Modules will scale with document */
.header {
  font-size: 1.5rem;
}
.footer {
  font-size: 0.75rem;
}
.sidebar {
  font-size: 0.85rem;
}

/* Type will scale with modules */
h1 {
  font-size: 3em;
}
h2 {
  font-size: 2.5em;
}
h3 {
  font-size: 2em;
}

谢谢大家分享的有用技巧,但我仍然不清楚如何转换这些 px 媒体查询。我使用了 Sublime 套件将 px 转换为 rems(通过简单地将 px/16),并且这确实有效!这非常奇怪,因为我的基础字体设置为 62.5,所以我不知道为什么 REM 转换没有破坏布局... - stckpete
1
@stckpete 如果你去浏览器设置中将字体大小从16改为18,那么你的计算结果就会完全错误。这就是尝试设置“基础字体大小”而不是使用浏览器预定义值的危险所在。你最终无法控制媒体查询将使用什么作为其基础。 - Jesse Kernaghan
1
我认为Justin Ober基于Chris Coyier文章使用rem的示例代码是很好的建议。然而,我想指出,任何时候使用em时,网页设计师都需要记住它们会级联,而rem不会。Rem始终参考根元素,即html元素。 - Michael Moriarty

3
除了其他的回答之外,请注意指定在font-size以外的另一个属性中的em长度实际上是相对于元素本身的font-size而言的,即不一定是其父元素的大小。 如果您为同一元素同时指定emfont-size,那么这会产生影响,比如指定内边距、外边距等。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接