CSS 技巧篇(十):1px邊框解決方案

1、產生緣由

隨着移動端的web項目愈來愈多,設計師的要求也愈來愈高。在移動端上經過1px實現一條1像素的線時,它並非真正的1像素,比真正的1像素要粗一點。
那麼爲何會產生這個問題呢?主要是跟一個東西有關,DPR(devicePixelRatio) 設備像素比,它是默認縮放爲100%的狀況下,設備像素和CSS像素的比值。css

window.devicePixelRatio=物理像素 /CSS像素
複製代碼

目前主流的屏幕DPR=2 (iPhone 8),或者3 (iPhone 8 Plus)。拿2倍屏來講,設備的物理像素要實現1像素,而DPR=2,因此css 像素只能是 0.5。
通常設計稿是按照750來設計的,它上面的1px是以750來參照的,而咱們寫css樣式是以設備375爲參照的,因此咱們應該寫的0.5px就行了啊! 試過了就知道,iOS 8+系統支持,安卓系統不支持。html

2、解決方案

2.1 使用小數點方式

.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 }
}
複製代碼
  • 優勢:比較方便
  • 缺點:支持iOS 8+,不支持安卓。

2.2 使用僞元素

<span class="border-1px">1像素邊框問題</span>

// less
.border-1px{
  position: relative;
  &::before{
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    width: 200%;
    border:1px solid red;
    color: red;
    height: 200%;
    -webkit-transform-origin: left top;
    transform-origin: left top;
    -webkit-transform: scale(0.5);
    transform: scale(0.5);
    pointer-events: none; /* 防止點擊觸發 */
    box-sizing: border-box;
    @media screen and (min-device-pixel-ratio:3),(-webkit-min-device-pixel-ratio:3){
      width: 300%;
      height: 300%;
      -webkit-transform: scale(0.33);
      transform: scale(0.33);
    }
  }
}
複製代碼
  • 優勢:直接經過CSS實現,不管是圓角仍是直角均可以實現。
  • 缺點:代碼量比較多,佔有了僞元素。

注意:空元素(不能包含內容的元素)不支持 ::before,::afterweb

  • IE 不支持的元素有:img,input,select,textarea。
  • FireFox 不支持的元素有:input,select,textarea。
  • Chrome 不支持的元素有:input[type=text],textarea。

2.3 使用box-shadow

<span class="border-1px">1像素邊框問題</span>

.border-1px{
  box-shadow: 0px 0px 1px 0px red inset;
}
複製代碼
  • 優勢:直接經過CSS實現,不管是圓角仍是直角均可以實現。
  • 缺點:因爲是使用陰影的方式,邊框線的顏色會比真實顏色淡一點。

2.4 使用border-image

弄出1px像素邊框的實質是弄出0.5px這樣的邊框,因此咱們能夠利用相似於這樣的圖片,使得「border-image-slice」爲2,那麼實際上邊框有一半是透明的,便可獲得咱們想要的「1px邊框」 bash

<div class="test">1像素邊框</div>
.test{
    border: 1px solid transparent;
    border-image: url('./border-1px.png') 2 repeat;
}
複製代碼
  • 優勢:其實感受沒啥優勢。。。
  • 缺點:修改顏色麻煩, 須要替換圖片;圓角須要特殊處理,而且邊緣會模糊

2.5 設置viewport的scale值

根據設備像素設置viewport,代碼只須要寫正常像素就能夠了。less

<html>
  <head>
      <title>1px question</title>
      <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
      <meta name="viewport" id="WebViewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">        
      <style>
          html {
            font-size: 1px;
          }            
          * {
            padding: 0;
            margin: 0;
          }
          .top_b {
            border-bottom: 1px solid #E5E5E5;
          }
          .a,.b {
            box-sizing: border-box;
            margin-top: 1rem;
            padding: 1rem;                
            font-size: 1.4rem;
          }

          .a {
              width: 100%;
          }

          .b {
              background: #f5f5f5;
              width: 100%;
          }
      </style>
      <script>
          var viewport = document.querySelector("meta[name=viewport]");
          //下面是根據設備像素設置viewport
          if (window.devicePixelRatio == 1) {
              viewport.setAttribute('content', 'width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no');
          }
          if (window.devicePixelRatio == 2) {
              viewport.setAttribute('content', 'width=device-width,initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no');
          }
          if (window.devicePixelRatio == 3) {
              viewport.setAttribute('content', 'width=device-width,initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no');
          }
          var docEl = document.documentElement;
          var fontsize = 32* (docEl.clientWidth / 750) + 'px';
          docEl.style.fontSize = fontsize;
      </script>
  </head>
  <body>
      <div class="top_b a">下面的底邊寬度是虛擬1像素的</div>
      <div class="b">上面的邊框寬度是虛擬1像素的</div>
  </body>
</html>
複製代碼
  • 優勢:全機型兼容,直接寫1px不能再方便
  • 缺點:適用於新的項目,老項目可能改動大,

3、參考

相關文章
相關標籤/搜索