1. 程式人生 > >thin-border: Retina螢幕下的1px解決方案

thin-border: Retina螢幕下的1px解決方案

問題來源

眾所周知,Retina螢幕下將 border 設定為1px , 其顯示卻比1px大,通常為2px。原因很簡單,同樣大小的手機一個為普通手機,一個為Retina手機,在css的世界中,其大小都為320px。而Retina螢幕的實際寬度卻為640px。這就導致了css中的1px在Retina螢幕中實際為2px。這也是Retina螢幕顯示效果比普通要更清晰,售價也更貴的原因所在。

解決方案

問題的原因清楚了,那我們就來談談具體的解決辦法吧。

方案一: .5px

@media screen and (-webkit-min-device-pixel-ratio: 2) {
  border: .5
px solid red; }

該方案本應是最理想的方案,無奈Android與低版本的iOS(ios8才開始支援)不支援該方案。故,放棄!

方案二: border-image

@media screen and (-webkit-min-device-pixel-ratio: 2){ 
    .border{ 
        border: 1px solid transparent;
        border-image: url(border.gif) 2 repeat;
    }
}

缺點:處理圓角只能這麼放大或縮小圖片,麻煩

方案三:background漸變(FrozenUI採用該方式實現)

@media screen and (-webkit-min-device-pixel-ratio: 2){
    .ui-border-t {
        background-position: left top;
        background-image: -webkit-gradient(linear,left bottom,left top,color-stop(0.5,transparent),color-stop(0.5,#fff),to(#fff));
    }
}

缺點:無法實現圓角、一個div上下左右只能實現一個方向、佔用background屬性

方案四::before、:after與transform結合 《極力推薦》

簡單的實現程式碼如下:

.radius-border{
  position: relative;  /*該句不可少,因為要對:before 進行絕對定位*/
}
@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));    /*核心:其實border還是1px,只是縮小一倍後可顯示為.5px的效果;同時由於是對:before進行縮小,所以不會影響到div的大小及內容*/
  -webkit-transform-origin: 0 0;
  transform(scale(0.5));
  transform-origin: 0 0;
 }
}

優點:圓角、一個div上下左右可同時實現一個或多個(本人目前工作中使用該方式)
缺點:程式碼量在,且佔用了偽元素

結論:最優方案-方案四-sass封裝minxin

方案二、三、四可行,《如果考慮到 div大小不定問題》、《圓角問題》、《一個div多邊同時實現問題》 這三個問題,毫無疑問,只能選擇方案四。但是如果每次都要寫一大堆的程式碼來實現 thin-border 效果。這對我們碼農來說簡直是一場災難。
所以本人 用sass實現了 thin-border 系列的 minxin
用法如下:按需求將下面四個中的一個 class 賦給 div 即可,不用對div進行任何額外的處理 (此時該 div 的before元素將被佔用)

.thin-border-left{      // 只讓 left 邊實現thin-border
    @include thin-border-left(red);
}
.thin-border-right{     // 只讓 right 邊實現thin-border
    @include thin-border-right(red);
}
.thin-border-top{       // 只讓 top 邊實現thin-border
    @include thin-border-top(red);
}
.thin-border-bottom{    // 只讓 bottom 邊實現thin-border
    @include thin-border-bottom(red);
}
.thin-border-all{   // 四個邊同時實現thin-border, 其中 5px 為 border-radio 值
    @include thin-border-all(red, 5px);
}