乐趣区

关于前端:移动端-1px-像素问题及解决办法

一、为什么会有 1px 问题

要解决这个问题,必须先补充一个知识点,就是设施的 物理像素 [设施像素] & 逻辑像素 [CSS 像素]

物理像素:挪动设施出厂时,不同设施自带的不同像素,也称硬件像素;

逻辑像素:css 中记录的像素。

在开发中,为什么挪动端 CSS 外面写了 1px,实际上看起来比 1px 粗;理解设施物理像素和逻辑像素的同学应该很容易了解,其实这两个 px 的含意其实是不一样的,UI 设计师要求的 1px 是指设施的物理像素 1px,而 CSS 里记录的像素是逻辑像素,它们之间存在一个比例关系,通常能够用 javascript 中的 window.devicePixelRatio 来获取,也能够用媒体查问的 -webkit-min-device-pixel-ratio 来获取。当然,比例多少与设施相干。

在手机上 border 无奈达到咱们想要的成果。这是因为 devicePixelRatio 个性导致,iPhone 的 devicePixelRatio==2,而 border-width: 1px; 形容的是设施独立像素,所以,border 被放大到物理像素 2px 显示,在 iPhone 上就显得较粗。

二、解决方案

1.transform: scale(0.5) 计划 – 举荐: 很灵便

1.) 设置 height: 1px,依据媒体查问联合 transform 缩放为相应尺寸。

div {
    height:1px;
    background:#000;
    -webkit-transform: scaleY(0.5);
    -webkit-transform-origin:0 0;
    overflow: hidden;
}

2.) 用::after 和::before, 设置 border-bottom:1px solid #000, 而后在缩放 -webkit-transform: scaleY(0.5); 能够实现两根边线的需要



div::after{
    content:'';width:100%;
    border-bottom:1px solid #000;
    transform: scaleY(0.5);
}

3.) 用::after 设置 border:1px solid #000; width:200%; height:200%, 而后再缩放 scaleY(0.5); 长处能够实现圆角,京东就是这么实现的,毛病是按钮增加 active 比拟麻烦。

.div::after {
    content: '';
    width: 200%;
    height: 200%;
    position: absolute;
    top: 0;
    left: 0;
    border: 1px solid #bfbfbf;
    border-radius: 4px;
    -webkit-transform: scale(0.5,0.5);
    transform: scale(0.5,0.5);
    -webkit-transform-origin: top left;
}

2. 媒体查问 + transfrom

/* 2 倍屏 */
@media only screen and (-webkit-min-device-pixel-ratio: 2.0) {
    .border-bottom::after {-webkit-transform: scaleY(0.5);
        transform: scaleY(0.5);
    }
}
/* 3 倍屏 */
@media only screen and (-webkit-min-device-pixel-ratio: 3.0) {
    .border-bottom::after {-webkit-transform: scaleY(0.33);
        transform: scaleY(0.33);
    }
}

3.viewport+rem 实现

<html style="font-size:18px;">  
    <head>  
        <title>1px question</title>  
        <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">  
        <meta name="viewport" id="WebViewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">       
        <style>  
            html {font-size: 1px;}             
            * {padding: 0;margin: 0;}              
            .bds_b {border-bottom: 1px solid #ccc;}  
            .a,  
            .b {margin-top: 1rem;padding: 1rem;font-size: 1.4rem;}  
            .a {width: 30rem;}  
            .b {background: #f5f5f5;width: 20rem;}  
        </style>  
        <script>  
            var viewport = document.querySelector("meta[name=viewport]");  
            // 上面是依据设施像素设置 viewport  
            if (window.devicePixelRatio == 1) {viewport.setAttribute('content', 'width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no');  
            }  
            if (window.devicePixelRatio == 2) {viewport.setAttribute('content', 'width=device-width,initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no');  
            }  
            if (window.devicePixelRatio == 3) {viewport.setAttribute('content', 'width=device-width,initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no');  
            }  
            var docEl = document.documentElement;  
            var fontsize = 10 * (docEl.clientWidth / 320) + 'px';  
            docEl.style.fontSize = fontsize;  
        </script>  
    </head>  
    <body>  
        <div class="bds_b a"> 上面的底边宽度是虚构 1 像素的 </div>  
        <div class="b"> 下面的边框宽度是虚构 1 像素的 </div>  
    </body>  
</html>

4.box-shadow 实现

box-shadow 属性的用法:box-shadow: h-shadow v-shadow [blur] [spread] [color] [inset]

参数别离示意: 程度暗影地位,垂直暗影地位,含糊间隔,暗影尺寸,暗影色彩,将内部暗影改为外部暗影,后四个可选。该例中为何将暗影尺寸设置为正数?设置成 -1px 是为了让暗影尺寸稍小于 div 元素尺寸,这样左右两边的暗影就不会裸露进去,实现只有底部一边有暗影的成果。从而实现分割线成果(单边边框)。

div{-webkit-box-shadow:0 1px 1px -1px rgba(0, 0, 0, 0.5);
}

https://www.jianshu.com/p/31f…
https://segmentfault.com/a/11…

退出移动版