媒体查询--PX,EM or REM?

发布于 静子

你是否思考过对于媒体查询你应该使用px, em还是rem?我也产生过同样的问题,并且目前为止,我还是没有明确的答案。

一年之前,我第一次创建 mappy-breakpoint 仓库时,我一直使用rem单位。之后一次和Sam Richard谈话之后,我开始转向使用em,因为我并没有发现两者之间的区别。

关于媒体查询,除了emrem,常用单位还有像素。自从现在所有浏览器存在像素缩放问题,我想知道像素是否还可以用于媒体查询。

这周,我打算弄明白两者之间的区别。

在开始这篇文章之前,我假设你已经知道了什么是emrem单位。如果你不知道的话,请查阅这篇文章。

基础实验

我想创建三个独立的<div>元素,一个用于px,一个用于em,一个用于rem。我给每个<div>元素添加一个背景色,便于区分。

.pixel { background: red; }
.em { background: green; }
.rem { background: blue; }

接下来,因为我们比较媒体查询单位,我在三个选择器上创建了一个min-width

当媒体查询被触发时,我决定降低元素的不透明度,这样我就可以立即看到他们之间的差异。下面是像素媒体查询的 CSS 样式:

.pixel {
  background: red;  
  @media (min-width: 400px) {
    opacity: 0.5
  }
}

接下来,我们就要弄清楚如何创建emrem单位。

在第一次实验中,如果所有条件都理想的话,我想要测试三个单位之间的差异。换句话说,没有以下情况下发生:

  • <html>中更改font-size
  • 用户放大。
  • 用户更改浏览器字体设置。

如果已经满足了以上理想的条件,我就可以想当然认为的16px == 1em == 1rem。那么 400px就等于25em25rem.

.pixel {
  background: red;  
  @media (min-width: 400px) {
    opacity: 0.5
  }
}
.em {
  background: green;  
  // 400 ÷ 16 = 25
  @media (min-width: 25em) {
    opacity: 0.5
  }
}
.rem {
  background: blue;  
  // 400 ÷ 16 = 25
  @media (min-width: 25rem) {
    opacity: 0.5
  }
}

如果三个媒体查询以相同的方式进行,我们应该就可以看到他们都准确的在 400px 触发

结果如下(我在每一个浏览器所测试的)。

rem

因为三个媒体查询在相同的断点处被触发,所以我们知道,这一阶段px, emrem之间并无差异.

建立基础实验后, 下一步是要测试在缺少以上理想条件的情况下,会出现什么情况。同样的,条件为:

  • <html>中更改font-size
  • 用户放大。
  • 用户更改浏览器字体设置。

让我们一个一个的去测试。

在HTML中更改Font-size

第一种情况是很普遍的。事实上,几乎所有的网页使用此方法在CSS中设置font-size默认值:

html { 
  // setting default font size 
  font-size: 200% 
}

这里,我在测试中选择将font-size设置为200%,这意味着我将1em1rem设置为了32px.如果emremfont-size改变的影响,他们将会在800px被触发。

如下是测试结果:所有的媒体查询在Chrome, Firefox 和 IE 11浏览器下均在400px被触发。

rem

这是正确的表现行为。emrem单位在HTML中不应受font-size的变化影响,因为他们是基于浏览器内部的font-size属性。

不幸的是,我们没在 Safari 上得到此完美的行为。它在800px时触发了rem媒体查询:(

rem

因为这种行为只发生在 Safari 浏览器中,我很想看看是否移动端 Safari也会出现此情况。实验证明,也会出现此现象。

所以,第一个场景已经证明,我们不应该使用rem媒体查询。然而,让我们继续把 rem 放在我们其余的实验中,看看是否会发生其他的事情。

用户放大

第二种情况也是十分常见的。如果你页面上的文本不足够大,用户可能会选择使用他们浏览器中内置的缩放功能来放大文本。

一个简短的说明:最初关于em的想法是因为当用户放大时,旧浏览器不能够更新像素值。在这方面,测试媒体查询单位时缩放将有助于回答这个问题,我们是否可以现在使用基于px的媒体查询。

rem

这个实验结果显示,Chrome,Firefox 和 IE 显示相同的行为。px单位查询在emrem查询时被同时触发。

rem

哈哈,你猜对了...Safari并不支持:(

rem

不幸的是,这意味着基于像素的媒体查询是不存在问题的。Safari浏览器不支持他们(除非你决定放弃 Safari?)。

现在,我们进行最后的实验,看看是否仍然会发生什么意外。

用户更改浏览器的Font值

许多开发商愿意相信,用户不会改变他们浏览器font-size的值,因为他们已经隐藏在 deeeep 的设置之中。

恩恩,如果这样子的话后果会很棒,因为所有用户都表示出此行为,我们就不需要做这个实验!:)

不幸的是,并没有数据证明用户不更改他们浏览器的font-sizes属性值,所以作为开发人员,我们仍然有责任考虑到我们网站的灵活性。

在这个实验中,我扩大了四个浏览器中的font-size属性值,并通过以下方式进行测试(如果你想跟随):

  • Chrome: 前往settings, show advanced settings, web-content.
  • Firefox: 前往preferences, content, fontscolors.
  • Internet Explorer: 在page单击, 之后 text-size.

我想不出在何处设置字体大小的唯一浏览器是Safari。所以我用代理服务器代替。例如,我将最小的字体大小更改为大于16px的设置。如果你也要这样做,请转到preferences, advanced, acessibility.

这是唯一所有浏览器表现行为一致的测试:

rem

正如你所看到的,像素查询的触发要早于emrem查询。

这里没有出现任何bug。由于 px 是绝对单位,就会正确的执行。无论用户如何更改他们默认的font-size属性值,断点应维持在 400px处。

另一方面,emrem基于浏览器的font-size属性值。因此,当用户更改默认值时,应该更新其媒体查询的font-size设置。

所以,这里对于像素的痴迷者,我很抱歉打破你的泡沫幻想,但基于像素查询是行不通。

实验总结

正如你可以从上面实验中看出,在四个浏览器之间表现一致的唯一单位是em。除了emrem在 Safari 上发现的bug之外,其并不存在任何差异。

px媒体查询在三次实验的两次中均表现正常(再一次,除了Safari)。不幸的是,在第三个实验中,当用户更改默认的浏览器font-size值时,px媒体查询仍在400px被触发。

因此,我在这些实验后得出的结论是:使用em媒体查询.

如果您正在使用一个没有使用em媒体查询的库时,你应该让其开发人员查看这篇文章,让他们知道他们的代码影响。不然,可以参考基于emMappy-breakpoints, Breakpoint-sass 或者 sass-mq 库。

本文根据@Zell的《PX, EM or REM Media Queries?》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:http://zellwk.com/blog/media-query-units/

静子

在校学生,本科计算机专业。一个积极进取、爱笑的女生,热爱前端,喜欢与人交流分享。想要通过自己的努力做到心中的那个自己。微博:@静-如秋叶

如需转载,烦请注明出处:https://www.fedev.cn/css/media-query-units.htmlFirst Look: Air Jordan 1 Low 'Shattered Backboard'