歡迎光臨
每天分享高質量文章

模擬 1px 的常用方法及利弊

作者:百度EFE – wxpuker

網址:http://efe.baidu.com/blog/1px-on-retina/?qq-pf-to=pcqq.c2c

點選“閱讀原文”可檢視本文網頁版

一直以來我們實現邊框的方法都是設定 border: 1px solid #ccc,但是在retina屏上因為裝置畫素比的不同,邊框在移動裝置上的表現也不相同:1px可能會被渲染成1.5px, 2px, 2.5px, 3px….,在使用者體驗上略差,所以現在要解決的問題就是在retina螢幕實現1px邊框。

如果你去google類似問題,誠然會找到所謂的”答案“,然後很開森的用到專案中了。運氣好的話,Yeah成功模擬1px了,運氣不好了可能遇到各種奇葩的表現讓你抓狂。

這篇文章總結了目前常用的模擬1px的方法,並分析各個方法的利弊。

實現方案

1、軟圖片

‘軟圖片’,即透過CSS漸變模擬,程式碼如下:

.retina(@top: transparent, @right: transparent, @bottom: transparent, @left: transparent, @w: 1px) {

@media only screen and (-webkit-min-device-pixel-ratio: 2),

only screen and (min-device-pixel-ratio: 2) {

border: none;

background-image:

linear-gradient(180deg, @top, @top 50%, transparent 50%),

linear-gradient(270deg, @right, @right 50%, transparent 50%),

linear-gradient(0deg, @bottom, @bottom 50%, transparent 50%),

linear-gradient(90deg, @left, @left 50%, transparent 50%);

background-size: 100% @w, @w 100%, 100% @w, @w 100%;

background-repeat: no-repeat;

background-position: top, right top, bottom, left top;

}

}

這段程式碼可能是從網上找到的出現最頻繁的程式碼了,但是這樣寫是有相容問題的,

測試小米2自帶瀏覽器、手機百度、百度瀏覽器都顯示不出上邊框,如圖:

測試小米2 chrome瀏覽器正常,如圖:

這種情況我們會考慮是不是沒有寫瀏覽器字首-webkit-的原因,好,我們加上:

background-image:

-webkit-linear-gradient(180deg, @top, @top 50%, transparent 50%),

-webkit-linear-gradient(270deg, @right, @right 50%, transparent 50%),

-webkit-linear-gradient(0, @bottom, @bottom 50%, transparent 50%),

-webkit-linear-gradient(90deg, @left, @left 50%, transparent 50%);

再次檢測小米2自帶瀏覽器、手機百度、百度瀏覽器、chrome,這一次表現都一致!慢著好像有些不對:

怎麼會這樣呢??看樣子是漸變方向不對,透過調整漸變方向得到結果:加上-webkit私有字首的0deg的漸變方向是從左向右,而規範定義的0deg的漸變方向是自下而上。

知道原因了,我們再改改程式碼吧:

background-image:

-webkit-linear-gradient(270deg, @top, @top 50%, transparent 50%),

-webkit-linear-gradient(180deg, @right, @right 50%, transparent 50%),

-webkit-linear-gradient(90deg, @bottom, @bottom 50%, transparent 50%),

-webkit-linear-gradient(0, @left, @left 50%, transparent 50%);

background-image:

linear-gradient(180deg, @top, @top 50%, transparent 50%),

linear-gradient(270deg, @right, @right 50%, transparent 50%),

linear-gradient(0deg, @bottom, @bottom 50%, transparent 50%),

linear-gradient(90deg, @left, @left 50%, transparent 50%);

Done!

優點:

  • 可以實現單個、多個邊框,大小、顏色可以配置
  • 對比下麵介紹的其他方法,這個方法相容性比較好,實現效果也相對不錯

缺點:

  • 很明顯程式碼特別長
  • 無法實現圓角
  • 使用時可能需要配合 padding,如設定子元素的背景可能會擋住父元素所設定的1px軟圖片
  • 如果有背景顏色,要寫成background-color,不然會不小心改寫掉
  • 對於非 retina 屏,需要寫 border: 1px solid #f00 進行適配

2、縮放

‘縮放’,即使用css transform縮放一半的大小,程式碼如下:

.transform-scale {

position: relative;

&:after,

&:before {

content: ”;

position: absolute;

left: 0;

top: 0;

height: 1px;

width: 100%;

-webkit-transform: scaleY(0.5);

transform: scaleY(0.5);

-webkit-transform-origin: 0 0;

transform-origin: 0 0;

background: #f00;

}

&:after {

top: auto;

bottom: 0;

-webkit-transform-origin: 0 100%;

transform-origin: 0 100%;

}

}

優點:

  • 實現單線條簡單
  • 大小、顏色可以配置

缺點:

  • 無法實現圓角
  • 四條邊框比較糾結
  • 依賴DOM,可能會與已有樣式衝突,如常用的clearfix

3、陰影

.shadow {

-webkit-box-shadow:0 1px 1px -1px rgba(255, 0, 0, 0.5);

box-shadow:0 1px 1px -1px rgba(255, 0, 0, 0.5);

}

沒覺得這個方法好用,模擬的效果差強人意,顏色也不好配置,不推薦

4、0.5px

終於等來了0.5px,雖然只有IOS8+才支援

// IOS8 hairline

.hairline(@color, @style:solid) {

@media (-webkit-min-device-pixel-ratio: 2) {

border: 0.5px @style @color;

}

}

優點:

  • “原生”,支援圓角~

缺點:

  • 目前只有IOS8+才支援,在IOS7及其以下、安卓系統都是顯示為0px

5、viewport&&rem;

再談mobile web retina 下 1px 邊框解決方案介紹了viewport結合rem解決裝置畫素比的問題,即讓我們像以前寫1倍畫素那樣寫頁面。

如在devicePixelRatio=2下設定

再設定rem,假設essay-header的高度是30px(裝置畫素比為1的情況):

html {

font-size: 20px;

}

essay-header {

height: 3rem;

}

沒有具體實踐過,不知道有神馬坑~

PS:淘寶、美團移動端頁面都是採用這個方式實現的

6、border-image

使用的背景圖片:

程式碼:

.border-image-1px {

border-width: 1px 0px;

-webkit-border-image: url(border.png) 2 0 stretch;

border-image: url(border.png) 2 0 stretch;

}

優點:

  • 額,,,

缺點:

  • 大小、顏色更改不靈活
  • 放到PS裡面看邊框,是有點模糊的(因為帶有顏色部分是1px,在retina螢幕上拉伸到2px肯定會有點模糊)

總結

1、0.5px,相信瀏覽器肯定是會慢慢支援的;目前而言,如果能用的話,可以hack一下;

2、陰影,border-image的方案不建議使用(用了你就知道。。。)

3、背景圖片和縮放可以在專案中配合使用,如單個線條使用縮放,四條框用背景圖片模擬,額,如果要圓角的話,無能無力了

其他


  • 再談mobile web retina 下 1px 邊框解決方案
  • 使用border-image實現類似iOS7的1px底邊

Demo

1px Demo – jsbin:http://jsbin.com/witida/1/edit?html,css,output

贊(0)

分享創造快樂