1px решение для мобильных устройств

CSS
1px решение для мобильных устройств

Автор: пустой@Edamame Front End.

предисловие

Появляется все больше и больше мобильных веб-проектов, а дизайнеры предъявляют все более высокие требования к пользовательскому интерфейсу, например, граница в 1 пиксель. существует高清屏Ниже 1px на мобильной стороне будет очень толстым. Например, это фейк 1 пиксель

Это действительно 1 пиксель

1. Причины

Так почему возникает эта проблема? В основном это связано с одной вещью, соотношением пикселей устройства DPR (devicePixelRatio), которое представляет собой отношение пикселей устройства к пикселям CSS, когда масштаб по умолчанию равен 100%.

window.devicePixelRatio=物理像素 /CSS像素

Текущий основной экран DPR=2 (iPhone 8) или 3 (iPhone 8 Plus). Возьмем в качестве примера экран 2x, физический пиксель устройства должен достигать 1 пикселя, а DPR=2, поэтому пиксель CSS может быть только 0,5. Общий эскиз разработан по 750, 1px над ним основан на 750, и мы пишем стиль CSS на основе устройства 375, поэтому мы должны написать 0,5px! После того, как вы попробуете это, вы узнаете, что система iOS 8+ поддерживает его, а система Android — нет.

2. Решения

1. Схема предоставлена ​​WWDC для системы iOS

推荐指数:**

На конференции WWDC была дана схема 1px, при написании 0.5px будет отображаться бордюр с шириной физического пикселя вместо css пиксельного бордюра. Итак, под iOS вы можете писать так.

border:0.5px solid #E5E5E5

Может вы спросите, почему не 0.3333px под 3х экраном? После моего теста я смоделировал iPhone 8Plus в Chrome и обнаружил, что он не отображается, когда его размер меньше 0,46 пикселя.

Суммировать:

  • Достоинства: Простой, без побочных эффектов.

  • Минусы: Поддерживает iOS 8+, а не Android. Более поздняя версия Android будет в порядке.

    2. Используйте изображение границы

    推荐指数:**

      border: 1px solid transparent;
      border-image: url('./../../image/96.jpg') 2 repeat;
    

    Картинка просто скриншот, рекомендуется сделать картинку самостоятельно

Цвет картинки - это цвет границы после этого

Пример этого метода на W3CPlus очень подробныйWoohoo. Я 3 с prussian.com/content/CSS….

Суммировать:

  • Преимущество: отсутствие побочных эффектов

  • Недостатки: При изменении цвета границы изображение приходится создавать заново, закругленные углы будут размыты.

    3. Используйте box-shadow для достижения

    推荐指数:***

    Давайте сначала рассмотрим box-shadow и прочитаем эту статью на MDN.developer.Mozilla.org/this-cn/docs/…. Посмотрите на результаты

Как реализуется код?

box-shadow: 0  -1px 1px -1px #e5e5e5,   //上边线
            1px  0  1px -1px #e5e5e5,   //右边线
            0  1px  1px -1px #e5e5e5,   //下边线
            -1px 0  1px -1px #e5e5e5;   //左边线

Первые два значения x, y в основном управляют тем, какое ребро отображается, а последние два значения управляют радиусом тени и радиусом расширения. На самом деле метод может перейти на эту адресную строкупопытайся.

Суммировать

  • Преимущества: простота в использовании, также можно получить закругленные углы

  • Недостатки: Метод реализации имитации, кто не увидит, что это тень, а не граница, если внимательно посмотреть.

    4. Используйте псевдоэлементы

    推荐指数:****

    Этот метод я использую чаще всего, и эффект также очень хороший, просто перейдите непосредственно к коду.

    1 граница

    .setOnePx{
      position: relative;
      &::after{
        position: absolute;
        content: '';
        background-color: #e5e5e5;
        display: block;
        width: 100%;
        height: 1px; /*no*/
        transform: scale(1, 0.5);
        top: 0;
        left: 0;
      }
    }
    

    Как видите, установите для псевдоэлемента абсолютное позиционирование и выровняйте его по верхнему левому углу родительского элемента, установите ширину на 100%, высоту на 1 пиксель, а затем уменьшите ее в направлении Y.0.5倍.

    4 границы

    .setBorderAll{
         position: relative;
           &:after{
               content:" ";
               position:absolute;
               top: 0;
               left: 0;
               width: 200%;
               height: 200%;
               transform: scale(0.5);
               transform-origin: left top;
               box-sizing: border-box;
               border: 1px solid #E5E5E5;
               border-radius: 4px;
          }
        }
    

    Также установите абсолютное позиционирование для псевдоэлемента и выровняйте его по левому верхнему углу родительского элемента. Сначала увеличьте длину и ширину псевдоэлемента в 2 раза, а затем установите рамку по центру левого верхнего угла и масштабируйте его до исходного0.5倍 Суммировать:

  • Преимущества: совместим со всеми моделями, достигает истинного 1px и может скруглять углы.

  • Недостатки: временно используется псевдоэлемент after, что может повлиять на очистку поплавков.

    5. Установите значение масштаба области просмотра

    推荐指数:*****

    Это решение реализовано с помощью viewport+rem+js. Обратитесь к примеру в ИнтернетеРешение проблемы с рамкой в ​​1 пиксель на мобильных устройствах, чтобы сделать это вручную.

    Работает хорошо. код выше

    <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не может быть более удобным

  • Недостатки: применимо к новым проектам, старые проекты могут сильно измениться

    Три, наступил на яму

    История крови и слез. . . . Вы не можете победить интерфейс, вы можете победить только себя.

    1. Используйте伪元素метод, а затем установить псевдоэлемент в псевдоклассе, вы можете выбрать его?

    Посмотрите на картинку, вам нужно изменить вертикальную линию посередине

    код выше

        &:nth-child(2){
          //border-color: #e5e5e5 !important;
            border: 0;
          position: relative;
          &:after{
            position: absolute;
            content: '';
            background-color: #e5e5e5;
            display: block;
            width: 100%;
            height: 1px; /*no*/
            transform: scale(1, 0.5);
            top: 0;
          }
        }
    

    Однако стиль, показанный в приведенном выше коде, выглядит следующим образом.

    Почему нет вертикальной линии посередине? ! Сначала я думал, что под псевдоклассом, если я напишу псевдоэлемент после, то может и не получиться.
    Увидев это, я обнаружил, что есть псевдоэлемент after, но он, похоже, находится не в том месте, поэтому я побежал к нему. Я хочу вертикальные линии, в чем причина? Наконец, я нашел способ решить эту проблему под руководством Анжи, и тогда я понял правду.

    Оказывается проблема с моими настройками ширины и высоты.Для вертикальных линий это должно быть ширина = 1px, высота = 100%, а затем масштабировать по оси X0.5倍, чтобы вышла вертикальная линия; аналогично устанавливаем горизонтальную линию, она должна быть width=100%, height=1px, а затем масштабируем по оси Y0.5倍.

Теперь, когда вы знаете причину, вам больше не нужно беспокоиться об ошибке.

&:nth-child(2){
        position: relative;
        &:after{
          position: absolute;
          content: '';
          top: 0;
          left: 0;
          width: 1px;
          height: 100%;
          transform: scaleX(0.5);
          background: #e5e5e5;
          transform-origin: 0 0;
        }
      }

Это возможно,

 &:nth-child(2){
        position: relative;
        &:after{
          content:" ";
          position:absolute;
          top: 0;
          left: 0;
          width: 200%;
          height: 200%;
          transform: scale(0.5);
          transform-origin: left top;
          box-sizing: border-box;
          border-left: 1px solid #E5E5E5;
        }
      }

Это также возможно.

2. Почему я не могу получить его?伪元素?

Я думал, что смогу написать рамку в 1 пиксель, зная описанный выше метод, но сразу же засомневался в себе.

1 пиксель приведенного выше поля ввода, все необходимые границы - 1 пиксель, я использовал ширину и высоту, чтобы увеличить на 200%, а затем уменьшить0.5倍Методы.
Это странно, этот же метод работает и в других местах, почему бы не показать его здесь. После долгих поисков я наконец нашел эту статьюПримечания по использованию псевдоэлементов CSS, и нашел:
Итак, причина не отображения найдена.==Поле ввода Textarea не поддерживает псевдоэлементы==, нет возможности, метод псевдоэлемента использовать нельзя, можно только использовать другие методы.

4. Резюме

Подводя итог, новые проекты лучше всего использовать设置viewport的scale值, этот метод имеет хорошую совместимость и его удобно написать позже. Для старых проектов может быть больше изменений, и чаще всего используются следующие методы:伪元素+transformМетоды. Другие фоновые изображения, теневые методы все еще не очень гибкие, и совместимость не очень хорошая.