【译】PX、EM仍是REM媒体查询?

原文连接:https://zellwk.com/blog/media-query-units/

你有没有想过使用媒体查询的时候到底该用px、em仍是rem做单位呢?我曾经也有一样的疑问,并且我到如今也还没弄明白。

当我一年多之前开始创建mappy-breakpoint库的时候,我用的是rem。当我与Sam Richard聊过以后,我转用了em,由于我发现两者并没有差别。

除了em和rem,另外一个经常使用于媒体查询的单位是咱们的老朋友px。现在全部浏览器都已解决了px缩放问题,可能如今咱们也可使用px媒体查询了。

这周我终于下定决心完全搞懂这个问题。

在咱们开始前,我假设你已经知道了em和rem是什么,若是你不清楚,请阅读这篇文章html



#基础实验
我建立了三个div元素,分别用于测试px、em、和rem。我给每一个div指定了一个背景颜色,易于辨认。git

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

接着,由于咱们是在比较媒体查询单位,因此我分别在三个选择器上各创建了一个min-width查询。

我决定在查询起做用时下降元素的不透明度,这样我立刻就能看出区别。这是使用px的媒体查询的CSS代码:github

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

下一步是搞清楚怎样使用em和rem单位。

在第一次实验中,我想看看在理想环境中这三个单位是否有区别,也就是说,如下任何状况都没有发生:
  1.<html>的font-size发生了改变
  2.用户放大了页面
  3.用户修改了浏览器字体设置

既然如今全部条件都是理想的,我能够假设16px == 1em == 1rem,这没什么问题,那么400px就等于25em或者25rem。浏览器

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

// 400 / 16 = 25
@media (min-width: 25em) {
    .em {
        opacity: 0.5;
    }
}

// 400 / 16 = 25
@media (min-width: 25rem) {
    .rem {
        opacity: 0.5;
    }
}

若是三个媒体查询的行为是一致的,它们应该都会恰好在400px触发。

事实也是如此(在我所测试过的浏览器上)。

基础实验
基础实验sass


由于三个媒体查询全都在同一个断点触发,在此阶段px、em和rem媒体查询并没有区别

创建了基础实验以后,下一步就是测试在条件非彻底理想时,即以上所提条件之一可能会发生,再一次提醒,这些状况分别是:
  1.<html>的font-size发生了改变
  2.用户放大了页面
  3.用户修改了浏览器字体设置

咱们来一个一个地测试吧。app



#1.<html>的font-size发生了改变

第一种状况很是广泛。事实上,几乎全部网页都在他们的CSS文件中使用这种方法来改写默认的font-size。

布局

html { font-size: 200%; }

在个人测试中,我使用了200%的font-size,也就是说,我设置了1em和1rem都等于32px。若是em和rem受font-size改变的影响,它们应该只在800px的时候触发。

结果是,在Chrome、Firefox和IE11上三个媒体查询都是在400px触发。

Chrome, Firefox, IE11上的结果
Chrome, Firefox, IE11上的结果

这是正确的行为,em和rem不该该被HTML中font-size的改变所影响,由于它们是基于浏览器内部的font-size的。

不幸的是,在Safari上咱们观察不到这种正确的行为,它会在800px触发rem媒体查询:(

Safari上的结果
Safari上的结果

由于这种行为只在Safari中发生,我很好奇手机端Safari是否也受影响,事实是,它们也受了影响。

因此,第一种状况告诉咱们不该该在媒体查询中使用rem,不过,咱们仍是在接下来的实验中保留rem,看看会不会发生其余事情。测试



#2.用户放大了页面

第二种状况也很广泛。若是你的网页上的字体不够大,用户可能会使用浏览器的缩放功能来放大字体

小知识:最初是由于老浏览器不能随用户缩放页面更新px值,才有了em。在这种状况下,测试用户缩放页面状况下使用不一样单位的媒体查询行为的不一样,能够帮助咱们解答如今是否可使用px媒体查询这个问题。
用户放大页面
用户放大页面

此次实验的结果是Chrome、Firefox和IE的行为是一致的,使用px做单位的查询与em和rem同样在相同时间触发。

Chrome, Firefox, IE11上的结果
Chrome, Firefox, IE11上的结果

但猜猜怎么着......Safari并无这样作:(

Safari上的结果
Safari上的结果

不幸的是,这表示使用px做单位的媒体查询也是不可能的事了,由于Safari不能恰当地支持它们(除非你打算放弃Safari?)。

好吧,让咱们继续最后一个实验,看看还有没有意料以外的事情发生。字体

 


#3.用户修改了浏览器字体设置
不少开发者认为用户不会修改他们浏览器的字体大小,由于这项设置藏得非非很是深。

好吧,若是全部用户都这样作,那真的是太棒了,这样咱们就不用作这个实验了!:)

不幸的是,没有数据证实用户不会修改他们浏览器的字体大小,因此为咱们的网站增长灵活性依然是咱们做为开发者的责任

在这次实验中我测试的4个浏览器上,我增大了默认字体大小,如下是设置方式(若是你想跟着修改的话):
  1.Chrome: 设置 -> 外观 -> 字号
  2.Firefox: 选项 -> 语言和外观 -> 字体和颜色
  3.Internet Explorer: 菜单栏 -> 查看 -> 文字大小

有一个浏览器我没法找到如何设置字体大小,那就是Safari,因此我改用了一个代理方法。我改变了浏览器设置,使得最小字体大小大于16px,方法是preferences -> advanced -> acessibility。

此次测试是惟一一个在全部浏览器上表现一致的网站

 

在第三种状况下全部浏览器的结果
在第三种状况下全部浏览器的结果

 

如你所见,使用px的查询比使用em或rem的查询都要早触发。

这并非bug,这种实现是正确的,由于px是绝对单位,无论用户怎样设置他们的默认字体大小,断点都应该保持为400px。

而em和rem是基于浏览器的字体大小的,所以,当用户修改了默认字体大小设置时,它们的媒体查询也应该更新。

因此......pixel爱好者,很抱歉戳破了你的幻想泡泡,可是基于pixel的媒体查询是毫不可能的。

(若是你不太理解最后一个实验,这里有更详细的解释。)

若是你写了一个网站,网站的断点是600px,这个600px断点对16px(默认)的字体大小来讲是很好的。

在这里咱们把小于600px的视口叫作“小视口”,大于600px的叫作“中视口”。

咱们再进一步假设你只在600px改变布局,小于600px时使用一栏布局,大于600px时使用两栏布局。

如今把你的浏览器字体大小设置为20px,而后在650px视口打开你的网站。

若是你的媒体查询用的是em或rem,你的用户会在650px视口看到一栏布局,这个行为在以上提到的前两种状况中也是一致的。

若是你的媒体查询用的是px,你的用户会在650px视口看到两栏布局,这个行为在前两种状况中是不一致的(并且这种设计与窗口也不相符)。



#总结

从以上测试能够看出,在4个浏览器中保持表现一致的惟一单位是em。除了在Safari上找到的bug外,em和rem并没有任何区别。

这三个实验中,px媒体查询在其中两个都表现很好(除了在Safari上)。不幸的是,在第三个实验中,px媒体查询的断点一直是400px,若是你打算支持会修改浏览器字体大小设置的用户,你就不可能使用px媒体查询。

所以,我从这些实验中得出的结论就是:使用em媒体查询

若是你用的库没有用em媒体查询,把这篇文章给那个库的开发者看看,好让他们知道他们写的代码可能会有什么后果。或者改用一个使用em媒体查询的库,如Mappy-breakpointsBreakpoint-sasssass-mq

相关文章
相关标签/搜索