移動端1像素邊框問題的解決方案


對於不同的移動設備,其物理像素與邏輯像素間存在不同的比例關系。所以我們僅僅在CSS中為border設置1px時,在手機上看起來會顯得比較粗,達不到預期效果。

關於物理像素與邏輯像素

  • 物理像素
    移動設備出廠時,不同設備自帶的不同像素,也稱硬件像素;
  • 邏輯像素
    即css中記錄的像素。

物理像素與邏輯像素的比例

通常可以通過js的 window.devicePixelRatio 在獲取不同設備的物理像素和邏輯像素的比例關系(在控制台打印即可得到)。

解決 1px 問題的推薦方法

方法

項目中引入:border-1px.css,然后通過控制元素的before和after偽元素,改變border大小或顏色。

@charset "utf-8";
.border,
.border-top,
.border-right,
.border-bottom,
.border-left,
.border-topbottom,
.border-rightleft,
.border-topleft,
.border-rightbottom,
.border-topright,
.border-bottomleft {
    position: relative;
}
.border::before,
.border-top::before,
.border-right::before,
.border-bottom::before,
.border-left::before,
.border-topbottom::before,
.border-topbottom::after,
.border-rightleft::before,
.border-rightleft::after,
.border-topleft::before,
.border-topleft::after,
.border-rightbottom::before,
.border-rightbottom::after,
.border-topright::before,
.border-topright::after,
.border-bottomleft::before,
.border-bottomleft::after {
    content: "\0020";
    overflow: hidden;
    position: absolute;
}
/* border
 * 因,邊框是由偽元素區域遮蓋在父級
 * 故,子級若有交互,需要對子級設置
 * 定位 及 z軸
 */
.border::before {
    box-sizing: border-box;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    border: 1px solid #eaeaea;
    transform-origin: 0 0;
}
.border-top::before,
.border-bottom::before,
.border-topbottom::before,
.border-topbottom::after,
.border-topleft::before,
.border-rightbottom::after,
.border-topright::before,
.border-bottomleft::before {
    left: 0;
    width: 100%;
    height: 1px;
}
.border-right::before,
.border-left::before,
.border-rightleft::before,
.border-rightleft::after,
.border-topleft::after,
.border-rightbottom::before,
.border-topright::after,
.border-bottomleft::after {
    top: 0;
    width: 1px;
    height: 100%;
}
.border-top::before,
.border-topbottom::before,
.border-topleft::before,
.border-topright::before {
    border-top: 1px solid #eaeaea;
    transform-origin: 0 0;
}
.border-right::before,
.border-rightbottom::before,
.border-rightleft::before,
.border-topright::after {
    border-right: 1px solid #eaeaea;
    transform-origin: 100% 0;
}
.border-bottom::before,
.border-topbottom::after,
.border-rightbottom::after,
.border-bottomleft::before {
    border-bottom: 1px solid #eaeaea;
    transform-origin: 0 100%;
}
.border-left::before,
.border-topleft::after,
.border-rightleft::after,
.border-bottomleft::after {
    border-left: 1px solid #eaeaea;
    transform-origin: 0 0;
}
.border-top::before,
.border-topbottom::before,
.border-topleft::before,
.border-topright::before {
    top: 0;
}
.border-right::before,
.border-rightleft::after,
.border-rightbottom::before,
.border-topright::after {
    right: 0;
}
.border-bottom::before,
.border-topbottom::after,
.border-rightbottom::after,
.border-bottomleft::after {
    bottom: 0;
}
.border-left::before,
.border-rightleft::before,
.border-topleft::after,
.border-bottomleft::before {
    left: 0;
}
@media (max--moz-device-pixel-ratio: 1.49), (-webkit-max-device-pixel-ratio: 1.49), (max-device-pixel-ratio: 1.49), (max-resolution: 143dpi), (max-resolution: 1.49dppx) {
    /* 默認值,無需重置 */
}
@media (min--moz-device-pixel-ratio: 1.5) and (max--moz-device-pixel-ratio: 2.49), (-webkit-min-device-pixel-ratio: 1.5) and (-webkit-max-device-pixel-ratio: 2.49), (min-device-pixel-ratio: 1.5) and (max-device-pixel-ratio: 2.49), (min-resolution: 144dpi) and (max-resolution: 239dpi), (min-resolution: 1.5dppx) and (max-resolution: 2.49dppx) {
    .border::before {
        width: 200%;
        height: 200%;
        transform: scale(.5);
    }
    .border-top::before,
    .border-bottom::before,
    .border-topbottom::before,
    .border-topbottom::after,
    .border-topleft::before,
    .border-rightbottom::after,
    .border-topright::before,
    .border-bottomleft::before {
        transform: scaleY(.5);
    }
    .border-right::before,
    .border-left::before,
    .border-rightleft::before,
    .border-rightleft::after,
    .border-topleft::after,
    .border-rightbottom::before,
    .border-topright::after,
    .border-bottomleft::after {
        transform: scaleX(.5);
    }
}
@media (min--moz-device-pixel-ratio: 2.5), (-webkit-min-device-pixel-ratio: 2.5), (min-device-pixel-ratio: 2.5), (min-resolution: 240dpi), (min-resolution: 2.5dppx) {
    .border::before {
        width: 300%;
        height: 300%;
        transform: scale(.33333);
    }
    .border-top::before,
    .border-bottom::before,
    .border-topbottom::before,
    .border-topbottom::after,
    .border-topleft::before,
    .border-rightbottom::after,
    .border-topright::before,
    .border-bottomleft::before {
        transform: scaleY(.33333);
    }
    .border-right::before,
    .border-left::before,
    .border-rightleft::before,
    .border-rightleft::after,
    .border-topleft::after,
    .border-rightbottom::before,
    .border-topright::after,
    .border-bottomleft::after {
        transform: scaleX(.33333);
    }
}

使用案例:

<!doctype html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width,user-scalable=no">
    <title> 移動端一像素解決方案 </title>
    <link rel="stylesheet" href="./border-1px.css">
</head>
<style>
    .box {
        padding: 5px;
        margin: 5px;
    }

    .border::before {
        border-color: red;
    }

    .border-top::before {
        border-color: red;
    }

    .border-bottom::before {
        border-color: red;
    }

    .border-topbottom::before,
    .border-topbottom::after {
        border-color: red;
    }

    .border-rightleft::before,
    .border-rightleft::after {
        border-color: red;
    }

    .box2 {
        padding: 5px;
        border: 1px solid red;
    }
</style>

<body>
    <div class="box2">
        <p>這是另一句話,其父元素div的border為沒有處理的一像素</p>
    </div>
    <br>
    <div class="box border">
        <p>這是一句話,其父元素div的border為處理后的的一像素</p>
    </div>
    <br>
    <div class="box border-top">
        <p>這是一句話,其父元素div的border-top為處理后的的一像素</p>
    </div>
    <br>
    <div class="box border-bottom">
        <p>這是一句話,其父元素div的border-bottom為處理后的的一像素</p>
    </div>
    <br>
    <div class="box border-topbottom">
        <p>這是一句話,其父元素div的border-topbottom為處理后的的一像素</p>
    </div>
    <br>
    <div class="box border-rightleft">
        <p>這是一句話,其父元素div的border-rightleft為處理后的的一像素</p>
    </div>
</body>

</html>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM