zoukankan      html  css  js  c++  java
  • 【译】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是什么,如果你不清楚,请阅读这篇文章



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

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

    接着,因为我们是在比较媒体查询单位,所以我分别在三个选择器上各建立了一个min-width查询。

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

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

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

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

    既然现在所有条件都是理想的,我可以假设16px == 1em == 1rem,这没什么问题,那么400px就等于25em或者25rem。

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

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

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

    基础实验
    基础实验


    因为三个媒体查询全都在同一个断点触发,在此阶段px、em和rem媒体查询并无区别

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

    我们来一个一个地测试吧。



    #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

    https://github.com/suukii
  • 相关阅读:
    42. Trapping Rain Water
    223. Rectangle Area
    645. Set Mismatch
    541. Reverse String II
    675. Cut Off Trees for Golf Event
    安装 VsCode 插件安装以及配置
    向上取整 向下取整 四舍五入 产生100以内随机数
    JS 判断是否为数字 数字型特殊值
    移动端初始配置,兼容不同浏览器的渲染内核
    Flex移动布局中单行和双行布局的区别以及使用
  • 原文地址:https://www.cnblogs.com/sukiY/p/9776932.html
Copyright © 2011-2022 走看看