1. 程式人生 > 其它 >移動端1px解決方案總彙

移動端1px解決方案總彙

1px問題產生的原因

從移動端的角度說個具體的場景,以iphone6為例。

iphone6的螢幕寬度為375px,設計師做的視覺稿一般是750px,也就是2x,這個時候設計師在視覺稿上畫了1px的邊框,於是你就寫了“border-width:1px”,so...1px邊框問題產生了

對設計師來說它的1px是相對於750px的(物理畫素),對你來說你的1px是相對於375px的(css畫素)“實際上你應該是border-width:0.5px”。

解決方法

解決辦法有很多種,在這裡幫大家整理常用的解決方法:

(1)0.5px實現

2014年的 WWDC,“設計響應的Web體驗” 一講中,Ted O’Connor 講到關於“retina hairlines”(retina 極細的線):在retina屏上僅僅顯示1物理畫素的邊框,開發者應該如何處理呢。
// 正常螢幕
.border { border: 1px solid black; }
// retina螢幕使用媒體查詢
@media (-webkit-min-device-pixel-ratio: 2) {
  .border { border-width: 0.5px } 
}

但是,問題是 retina 屏的瀏覽器可能不認識0.5px的邊框,將會把它解釋成0px,沒有邊框。包括 iOS 7 和 之前版本,OS X Mavericks 及以前版本,還有 Android 裝置。

解決方案是通過JavaScript檢測瀏覽器能否處理0.5px的邊框,如果可以,給<html>元素添加個class。

// js程式碼,指令碼應該放在<body>內, 如果在<head>裡面執行,需要包裝$(document).ready(function() {   })
if (window.devicePixelRatio && devicePixelRatio >= 2) {
  var
testElem = document.createElement('div'); testElem.style.border = '.5px solid transparent'; document.body.appendChild(testElem); if (testElem.offsetHeight == 1) { document.querySelector('html').classList.add('hairlines'); } document.body.removeChild(testElem); } // css程式碼 div { border: 1px solid #bbb; } .hairlines div { border-width: 0.5px; }

(2)使用border-image實現

.border{
    border-width: 1px;
    border-image: url(border.gif) 2 repeat;
}

缺點是改邊框顏色時要改圖片,不是很方便。

(3)用多背景漸變實現

設定1px的漸變背景,50%有顏色,50%透明。缺點是圓角沒法實現。

.border {
    background:
    linear-gradient(180deg, black, black 50%, transparent 50%) top    left  / 100% 1px no-repeat,
    linear-gradient(90deg,  black, black 50%, transparent 50%) top    right / 1px 100% no-repeat,
    linear-gradient(0,      black, black 50%, transparent 50%) bottom right / 100% 1px no-repeat,
    linear-gradient(-90deg, black, black 50%, transparent 50%) bottom left  / 1px 100% no-repeat;
}

(4)使用box-shadow模擬邊框實現

缺點是顏色不好處理,有陰影出現。

.hairlines li {
    border: none;
    box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.5);
}

(5)通過 viewport + rem 實現

將border設定為1px,然後將頁面根據裝置的dpr縮小相應的倍數,接著將rem放大相應的倍數,這樣頁面中只有1px的邊框縮小了,而其他內容經過縮小和擴大,還是原來的狀態。(rem元素大小不變,僅僅是px元素會根據dpr進行縮放)

https://www.houdianzi.com/suzhoulogo/ 蘇州logo設計

(6)使用偽類 + transform實現

原理是把原先元素的 border 去掉,然後利用 :before 或者 :after 重做 border ,並 transform 的 scale 縮小一半,原先的元素相對定位,新做的 border 絕對定位。

單個border

.hairlines li{
    position: relative;
    border:none;
}
.hairlines li:after{
    content: '';
    position: absolute;
    left: 0;
    background: #000;
    width: 100%;
    height: 1px;
    -webkit-transform: scaleY(0.5);
            transform: scaleY(0.5);
    -webkit-transform-origin: 0 0;
            transform-origin: 0 0;
}

四條 border

.hairlines li{
    position: relative;
    margin-bottom: 20px;
    border:none;
}
.hairlines li:after{
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    border: 1px solid #000;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    width: 200%;
    height: 200%;
    -webkit-transform: scale(0.5);
    transform: scale(0.5);
    -webkit-transform-origin: left top;
    transform-origin: left top;
}

樣式使用的時候,也要結合js程式碼,判斷是否 Retina 屏

if(window.devicePixelRatio && devicePixelRatio >= 2){
    document.querySelector('ul').className = 'hairlines';
}