你是否思考过对于媒体查询你应该使用px
,em
还是rem
?我也产生过同样的问题,并且目前为止,我还是没有明确的答案。
一年之前,我第一次创建 mappy-breakpoint仓库时,我一直使用rem
单位。之后一次和Sam Richard谈话之后,我开始转向使用em
,因为我并没有发现两者之间的区别。
关于媒体查询,除了em
和rem
,常用单位还有像素。自从现在所有浏览器存在像素缩放问题,我想知道像素是否还可以用于媒体查询。
这周,我打算弄明白两者之间的区别。
在开始这篇文章之前,我假设你已经知道了什么是em
和rem
单位。如果你不知道的话,请查阅这篇文章。
基础实验
我想创建三个独立的<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
}
}
接下来,我们就要弄清楚如何创建em
和rem
单位。
在第一次实验中,如果所有条件都理想的话,我想要测试三个单位之间的差异。换句话说,没有以下情况下发生:
- 在
<html>
中更改font-size
。 - 用户放大。
- 用户更改浏览器字体设置。
如果已经满足了以上理想的条件,我就可以想当然认为的16px == 1em == 1rem
。那么 400px
就等于25em
或25rem
.
.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
触发。
结果如下(我在每一个浏览器所测试的)。
因为三个媒体查询在相同的断点处被触发,所以我们知道,这一阶段px
, em
或rem
之间并无差异.
建立基础实验后, 下一步是要测试在缺少以上理想条件的情况下,会出现什么情况。同样的,条件为:
- 在
<html>
中更改font-size
。 - 用户放大。
- 用户更改浏览器字体设置。
让我们一个一个的去测试。
在HTML中更改Font-size
第一种情况是很普遍的。事实上,几乎所有的网页使用此方法在CSS中设置font-size
默认值:
html {
// setting default font size
font-size: 200%
}
这里,我在测试中选择将font-size
设置为200%
,这意味着我将1em
和1rem
设置为了32px
.如果em
和rem
受font-size
改变的影响,他们将会在800px
被触发。
如下是测试结果:所有的媒体查询在Chrome, Firefox 和 IE 11浏览器下均在400px
被触发。
这是正确的表现行为。em
和rem
单位在HTML中不应受font-size
的变化影响,因为他们是基于浏览器内部的font-size
属性。
不幸的是,我们没在 Safari 上得到此完美的行为。它在800px
时触发了rem
媒体查询:(
因为这种行为只发生在 Safari 浏览器中,我很想看看是否移动端 Safari也会出现此情况。实验证明,也会出现此现象。
所以,第一个场景已经证明,我们不应该使用rem
媒体查询。然而,让我们继续把 rem
放在我们其余的实验中,看看是否会发生其他的事情。
用户放大
第二种情况也是十分常见的。如果你页面上的文本不足够大,用户可能会选择使用他们浏览器中内置的缩放功能来放大文本。
一个简短的说明:最初关于em
的想法是因为当用户放大时,旧浏览器不能够更新像素值。在这方面,测试媒体查询单位时缩放将有助于回答这个问题,我们是否可以现在使用基于px
的媒体查询。
这个实验结果显示,Chrome,Firefox 和 IE 显示相同的行为。px
单位查询在em
和rem
查询时被同时触发。
哈哈,你猜对了...Safari并不支持:(
不幸的是,这意味着基于像素的媒体查询是不存在问题的。Safari浏览器不支持他们(除非你决定放弃 Safari?)。
现在,我们进行最后的实验,看看是否仍然会发生什么意外。
用户更改浏览器的Font值
许多开发商愿意相信,用户不会改变他们浏览器font-size
的值,因为他们已经隐藏在 deeeep 的设置之中。
恩恩,如果这样子的话后果会很棒,因为所有用户都表示出此行为,我们就不需要做这个实验!:)
不幸的是,并没有数据证明用户不更改他们浏览器的font-sizes
属性值,所以作为开发人员,我们仍然有责任考虑到我们网站的灵活性。
在这个实验中,我扩大了四个浏览器中的font-size
属性值,并通过以下方式进行测试(如果你想跟随):
- Chrome: 前往
settings
,show advanced settings
,web-content
. - Firefox: 前往
preferences
,content
,fonts
和colors
. - Internet Explorer: 在
page
单击, 之后text-size
.
我想不出在何处设置字体大小的唯一浏览器是Safari。所以我用代理服务器代替。例如,我将最小的字体大小更改为大于16px的设置。如果你也要这样做,请转到preferences
, advanced
, acessibility
.
这是唯一所有浏览器表现行为一致的测试:
正如你所看到的,像素查询的触发要早于em
或rem
查询。
这里没有出现任何bug。由于 px
是绝对单位,就会正确的执行。无论用户如何更改他们默认的font-size
属性值,断点应维持在 400px
处。
另一方面,em
和rem
基于浏览器的font-size
属性值。因此,当用户更改默认值时,应该更新其媒体查询的font-size
设置。
所以,这里对于像素的痴迷者,我很抱歉打破你的泡沫幻想,但基于像素查询是行不通。
实验总结
正如你可以从上面实验中看出,在四个浏览器之间表现一致的唯一单位是em
。除了em
和rem
在 Safari 上发现的bug之外,其并不存在任何差异。
px
媒体查询在三次实验的两次中均表现正常(再一次,除了Safari)。不幸的是,在第三个实验中,当用户更改默认的浏览器font-size
值时,px
媒体查询仍在400px
被触发。
因此,我在这些实验后得出的结论是:使用em
媒体查询.
如果您正在使用一个没有使用em
媒体查询的库时,你应该让其开发人员查看这篇文章,让他们知道他们的代码影响。不然,可以参考基于em
的Mappy-breakpoints, Breakpoint-sass或者 sass-mq库。
本文根据@Zell的《PX, EM or REM Media Queries?》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:http://zellwk.com/blog/media-query-units/。
如需转载,烦请注明出处:http://www.w3cplus.com/css/media-query-units.html