移動端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; width: 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; }

  優點:代碼量少,可以滿足所有場景

  缺點:邊框有陰影,顏色變淺


免責聲明!

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



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