zoukankan      html  css  js  c++  java
  • 移动端1px细线解决方案总结

    一、移动端1px变粗的原因

      为什么移动端css里面写了1px, 实际看起来比1px粗,其实原因很好理解:这个px的含义是不一样的。移动端html的header总会有一句

    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

      这句话定义了本页面的viewport的宽度为设备宽度,初始缩放值和最大缩放值都为1,并禁止了用户缩放。viewport通俗的讲是浏览器上可用来显示页面的区域,这个区域是可能比屏幕大的。根据这篇文章http://www.cnblogs.com/2050/p/3877280.html的分析, 手机存在一个能完美适配的理想viewport,分辨率相差很大的手机的理想viewport的宽度可能是一样的,这样做的目的是为了保证同样的css在不同屏幕下的显示效果是一致的,上面的meta实际上是设置了ideal viewport的宽度。

      以实际举例:iphone3和iphone4的屏幕宽度分别是320px,640px,但是它们的ideal viewport的宽度都是320px,设置了设备宽度后,320px宽的元素都能100%的填充满屏幕宽。不同手机的ideal viewport宽度是不一样的,常见的有320px, 360px, 384px。iphone系列的这个值在6之前都是320px,控制viewport的好处就在于一套css可以适配多个机型。

      看懂的人应该已经明白 1px 变粗的原因了,viewport的设置和屏幕物理分辨率是按比例而不是相同的,移动端 window 对象有个devicePixelRatio属性,它表示设备物理像素和css像素的比例,在retina屏的iphone手机上,这个值为2或3,css里写的 1px 长度映射到物理像素上就有 2px 或 3px 那么长。

      简言之,就是说1px变粗是由于不同的手机有不同的像素密度导致的。如果移动显示屏的分辨率始终是普通屏幕的2倍,1px的边框在devicePixelRatio=2的移动显示屏下会显示成2px,所以在高清屏下看着1px总是感觉变胖了。

      产生原因

      1、设备像素比:dpr=window.devicePixelRatio,也就是设备的物理像素与逻辑像素的比值。

      2、在retina屏的手机上, dpr23css里写的1px宽度映射到物理像素上就有2px3px宽度。例如:iPhone6dpr2,物理像素是750(x轴),它的逻辑像素为375。也就是说,1个逻辑像素,在x轴和y轴方向,需要2个物理像素来显示,即:dpr=2时,表示1个CSS像素由4个物理像素点组成。

    二、解决方案

    1、用小数来写px值

      IOS8下已经支持带小数的px值,媒体查询 media query 对应 devicePixelRatio 有个查询值-webkit-min-device-pixel-ratio,css可以写成这样

    .border { border: 1px solid #999 }
    @media screen and (-webkit-min-device-pixel-ratio: 2) {
        .border { border: 0.5px solid #999 }
    }
    @media screen and (-webkit-min-device-pixel-ratio: 3) {
        .border { border: 0.333333px solid #999 }
    }

      如果使用less/sass的话只是加了1句mixin

      缺点: 安卓与低版本IOS不适用,这个或许是未来的标准写法,现在不做指望

    2、伪元素 + transform 实现

      对于老项目 伪元素 + transform 是比较完美的方法了。

      原理是把原先元素的 border 去掉,然后利用 :before 或者 :after 重做 border ,并 transform 的 scale 缩小一半,原先的元素相对定位,新做的 border 绝对定位。

      构建1个伪元素,将它的长宽放大到2倍,边框宽度设置为1px,再以transform缩放到50%。

    .radius-border{
        position: relative;
    }
    @media screen and (-webkit-min-device-pixel-ratio: 2){
        .radius-border:before{
            content: "";
            pointer-events: none; /* 防止点击触发 */
            box-sizing: border-box;
            position: absolute;
             200%;
            height: 200%;
            left: 0;
            top: 0;
            border-radius: 8px;
            border:1px solid #999;
            -webkit-transform(scale(0.5));
            -webkit-transform-origin: 0 0;
            transform(scale(0.5));
            transform-origin: 0 0;
        }
    }

      需要注意<input type="button">是没有:before, :after伪元素的

      优点: 其实不止是圆角, 其他的边框也可以这样做出来

      缺点: 代码量也很大, 占据了伪元素, 容易引起冲突

    3,viewport + rem 实现

      这种兼容方案相对比较完美,适合新的项目,老的项目修改成本过大。

      在devicePixelRatio = 2 时,输出viewport:

      在devicePixelRatio = 3 时,输出viewport:

      优点:所有场景都能满足,一套代码,可以兼容基本所有布局

      缺点:老项目修改代价过大,只适用于新项目

    4,使用box-shadow模拟边框

      利用css 对阴影处理的方式实现0.5px的效果。样式设置:

    .box-shadow-1px {
        box-shadow: inset 0px -1px 1px -1px #c8c7cc;
    }

      优点:代码量少,可以满足所有场景

      缺点:边框有阴影,颜色变浅

  • 相关阅读:
    linux系统根目录文件系统空间不足导致的错误
    python---对象
    公共函数
    PHP接口(interface)和抽象类(abstract)
    mysql引擎
    InstallShield自定义图片资源
    InstallShield 创建自己的Dialog
    InstallShield:自己备份
    注册表和ODBC
    IS脚本学习
  • 原文地址:https://www.cnblogs.com/goloving/p/13087139.html
Copyright © 2011-2022 走看看