布局方面,css有那么幾個比較熱衷的問題。其中,移動端1px邊框問題的討論不亞於垂直居中。那么移動端1px邊框問題是如何產生的呢?由於現在的手機幾乎都是retina屏,css設置的1px會被渲染成2px的物理像素(針對像素比等於2的屏幕),因此看起來會比較粗。既然知道了問題的產生原因,那么我們就開始解決。網上有很多種方案,但實際上我們用的時候只能選一種用,所以那么“不靠譜”的就不詳細敘述了...(以下方案推薦指數逐漸提高)
1、直接設置0.5px
ios8+可以識別浮點類型的單位,因此可以渲染這個0.5px。然而,絕大部分的android機是不支持浮點類型單位的。所以這種方案pass...
2、利用背景圖
不管是border-image,還是background-image,圖片的弊端還是很明顯的:想改變顏色就必須要換圖片,而且利用圖片也比較麻煩。所以不推薦這種方案...
3、viewport+rem實現
同時通過設置對應viewport的rem基准值,這種方式就可以像以前一樣輕松愉快的寫1px了。
在devicePixelRatio = 2 時,輸出viewport:
<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
在devicePixelRatio = 3 時,輸出viewport:
<meta name="viewport" content="initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no">
這種兼容方案相對比較完美,適合新的項目,老的項目修改成本過大。對於這種方案,可以看看《使用Flexible實現手淘H5頁面的終端適配》
4、背景漸變實現
與background-image方案類似,只是將圖片替換為css3漸變。設置1px的漸變背景,50%有顏色,50%透明。很多UI都是采用這種方法,比如:weui、mint-ui...
單邊:
background-image: linear-gradient(180deg, #f8f8f8, #f8f8f8 50%, transparent 50%);
background-size: 100% 1px;
background-repeat: no-repeat;
background-position: bottom left;
background-origin: content-box;
四邊:(多背景漸變)
.background-gradient-1px { background: linear-gradient(#000, #000 100%, transparent 100%) left / 1px 100% no-repeat, linear-gradient(#000, #000 100%, transparent 100%) right / 1px 100% no-repeat, linear-gradient(#000,#000 100%, transparent 100%) top / 100% 1px no-repeat, linear-gradient(#000,#000 100%, transparent 100%) bottom / 100% 1px no-repeat } /* 或者 */ .background-gradient-1px{ background: -webkit-gradient(linear, left top, right bottom, color-stop(0, transparent), color-stop(0, #000), to(#000)) left / 1px 100% no-repeat, -webkit-gradient(linear, left top, right bottom, color-stop(0, transparent), color-stop(0, #000), to(#000)) right / 1px 100% no-repeat, -webkit-gradient(linear, left top, right bottom, color-stop(0, transparent), color-stop(0, #000), to(#000)) top / 100% 1px no-repeat, -webkit-gradient(linear, left top, right bottom, color-stop(0, transparent), color-stop(0, #000), to(#000)) bottom / 100% 1px no-repeat }
這種方案顯示是比較牛*的,不僅實現了1px的邊框,還能實現多條邊框。缺點就是不能實現圓角的1px邊框,瀏覽器的兼容性也要考慮...
5、偽類 + transform 實現
個人認為偽類+transform是比較完美的方法。利用 :before 或者 :after 實現 border ,並 transform 的 scale 縮小一半,將border 絕對定位。
單邊:
.scale-1px{ position: relative; border:none; } .scale-1px:after{ content: ''; position: absolute; bottom: 0; width: 100%; height: 1px;
background: #000; -webkit-transform: scaleY(0.5); transform: scaleY(0.5); -webkit-transform-origin: 0 0; transform-origin: 0 0; }
@media (-webkit-min-device-pixel-ratio:3),(min-device-aspect-ratio:3){
.scale-1px:after::before{-webkit-transform:scaleY(0.333);transform:scaleY(0.333);}
}
四邊:
.scale-1px{ position: relative; margin-bottom: 20px; border:none; } .scale-1px: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; } 或者: .scale-1px:after{ content:''; position:absolute; border:1px solid #000; top:-50%; right:-50%; bottom:-50%; left:-50%; -webkit-transform:scale(0.5); transform:scale(0.5); }
至此,移動端1px的實現就這么多,如有更牛*的方案,歡迎補充~