Адаптация мобильной верстки hotcss+postcss-pxtorem

CSS
Адаптация мобильной верстки hotcss+postcss-pxtorem

задний план

Изначально команда занималась разработкой для ПК, но некоторое время назад структура была скорректирована, а людей на мобильном терминале не хватило, поэтому команда взяла на себя и работу над мобильным терминалом.

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

На этот раз я представлю процесс улучшения нашего решения по адаптации мобильного терминала.

библиотека hotcss

В начале мобильной разработки, из-за плотного графика, чтобы быстро построить весь проект, я, наконец, решил использоватьhotcssэта библиотека. У этой библиотеки много преимуществ:

  1. легко использовать
  2. Поддержка различных размеров эскиза дизайна
  3. Адаптер после преобразования поддерживает пиксель в коде js
  4. Эффективно решить проблему 1PX

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

Однако из-за опасений по поводу задержки доступа к cdn и проблем с производительностью анализа DNShotcss.jsНе получается загрузить ресурс, а сам исходник не длинный, напрямую сжимаем исходник и инлайним в шаблон.

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

проблема 1px/0.5px

После реального машинного теста наших одноклассников QA мы обнаружили, что в случае некоторых мобильных телефонов Android 4 с dpr=1,1pxа также0.5pxСтиль проходит черезpx2remПосле конвертации все равно будут проблемы.На младших машинах с dpr=1 следуйте меткеfont-sizeбудет рассчитываться как20px(все еще 22,5px забыл), в этом случае некоторые очень маленькие пиксели, такие как1pxили0.5pxВозможно, поскольку ширина меньше, чем минимальная ширина, отображаемая браузером, для совместимости с мобильными телефонами 1dpr нам нужно написать схему совместимости селектора dpr для этого маленького пиксельного стиля (то же самое верно и для других стилей CSS). стили):

@mixin border-bottom($width: 1) {
  border-bottom: px2rem($width) solid map-get($defaultColor, borderColor);
  [data-dpr='1'] & {
    border-bottom-width: $width + 'px';
  }
}

Лично я считаю, что этот вопрос более0.5pxВызвано, но мне просто нравится использовать пользовательский интерфейс, если я этого не выношу0.5pxРазделительная линия и граница...

Проблема размера эскиза проекта

На самом деле, эта проблема не является проблемой самой библиотеки hotcss.Когда студенты, изучающие пользовательский интерфейс, делают эскизы дизайна, они должны давать фронтенд-студентам единый набор размеров.

Однако из-за личных привычек некоторые из наших первых одноклассников по пользовательскому интерфейсу давали нам эскизы дизайна для iOS размером 375 пикселей, а некоторые были черновиками дизайна для Android с разрешением 360 пикселей. а такжеhotcssЭта библиотека должна быть объявлена ​​заранее$designWidthэту переменную, а затем используйтеpx2rem()Метод будет заменен только тогда, когда метод будет использоваться.Поскольку в CSS нет понятия области действия, необходимо использовать sass и less.

Когда файлы sass скомпилированы, они также выполняются сверху вниз, а объявления переменных могут быть переопределены, поэтому, если вы используете язык расширения sass или less, в этом месте не должно быть проблем, но не забывайте давать каждому sass и less файл оба объявляют$designWidth, в противном случае может возникнуть исключение, поскольку некоторые файлы не объявляют переменные и используют измерения, объявленные другими страницами.

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

громоздкое письмо

Честно говоря, хоть и очень удобен в использовании, нужно только ввести официальный sdk для завершения схемы адаптации мобильного терминала. Но при написании бизнес-кода CSS я все еще чувствую, что использование hotcss очень громоздко.

Когда размер в черновике пользовательского интерфейса такой:

font-size: 16px;
font-height: 20px;
height: 50px;
width: 200px;

Мы не можем скопировать его напрямую, нам нужно преобразовать его в единицу измерения:

// 这一块代码可以放到common.scss中
@function px2rem($px) {
  @return $px * 320 / $designWidth/20 + rem;
}

$designWidth: 360;

font-size: px2rem(16);
font-height: px2rem(20);
height: px2rem(50);
width: px2rem(200);

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

По вышеуказанным причинам, в процессе обновления инструмента упаковки webpack->razzle, наша команда улучшила схему адаптации и принялаhotcss+postcss-pxtoremкомбинированная программа.

HotCSS с Postcss-Pxtorem

postcss-pxtoremИспользование этой библиотеки онлайн-инструментов также представлено повсеместно. Преимущество этой библиотеки в том, что существуют строгие правила преобразования, которые можно использовать для различных сценариев. Мы используем этот плагин здесь для автоматического преобразования px-> rem или другими процессамиhotcssпродолжать.

Некоторые параметры postcss-px2rem
require('postcss-pxtorem')({
  rootValue: 75,
  unitPrecision: 5,
  propList: ['*'],
  selectorBlackList: [],
  replace: true,
  mediaQuery: false,
  minPixelValue: 12
})
  1. rootValueэто корневой тегfont-sizeразмер
  2. unitPrecisionэто количество знаков после запятой после преобразования в rem
  3. propListэто список свойств, которые необходимо преобразовать
  4. selectorBlackListЭто массив, который фильтрует селекторы css.Например, если вы установите его в ['fs'], например, имя класса fs-xl, стиль, связанный с px в нем, не будет преобразован, а обычное написание также поддерживается здесь.
  5. minPixelValueВы можете установить меньше, чем размер не будет преобразован.
postcss.cofnig.js
const PostCssFlexBugFixes = require('postcss-flexbugs-fixes');
const autoprefixer = require('autoprefixer');
const px2rem = require('postcss-pxtorem');
const path = require('path');
const designWidth = 360; // 统一的视觉稿尺寸
const rootValue = (designWidth * 20) / 320; // root FontSize
module.exports = ctx => {
  const remInclude = [
    /\.rem\.less$/,
    /\.rem\.scss$/,
  ]; // 白名单,命中白名单则进行px2rem转换,包括.rem.less、.rem.scss结尾的文件
  const useRem = remInclude.some(x =>
    x.test(path.join(ctx.file.dirname, ctx.file.basename))
  );
  return {
    plugins: [
      PostCssFlexBugFixes, //修复某些浏览器的flex bug
      autoprefixer({
        // autprefixer
        browsers: ['>1%', 'last 4 versions', 'Firefox ESR', 'not ie < 9'],
        flexbox: 'no-2009'
      }),
      useRem &&
        px2rem({
          rootValue,
          propList: ['*'],
          minPixelValue: 1
        })
    ].filter(Boolean)
  };
};

postcss-pxtoremполная параremпреобразование, добавление передhotcssправильноfont-sizeрасчет стоимости и параviewportИнициализация, мы окончательно завершили схему адаптации мобильного терминала.

Список Whitelist устанавливается совместимым с предыдущими версиями.hotcssСпособ письма в то время, после завершения обновления razzle, все наши последующие стили используются одинаково.rem.scssВ качестве суффикса имени файла, чтобы единица измерения px могла быть нормально записана в файле стиля,postcssавтоматически сделает преобразование для нас.

Яма шкалы масштабирования hotcss

В последнее время использовались некоторые сторонние плагины (такие какechartsи видео плееры и т. Д.), НайденоhotcssУстановите страницу в соответствии с dprmeta[viewport]Между плагином и плагином будет яма.

<meta name="viewport" content="width=device-width, initial-scale=0.5, minimum-scale=0.5, maximum-scale=0.5, user-scalable=no">

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

а такжеhotcssМасштаб сбросится по dpr, в этом случае при загрузке css медленнее чем js стиль страницы будет мерцать, а стили сторонних плагинов все раскладываются по начальному масштабу , Поэтому на странице он будет отображаться маленьким при увеличении.

Однако такая ситуация обычно возникает при локальной разработке.Статические ресурсы в онлайн-режиме обычно размещаются в cdn, и скорость доступа очень высокая.Эта проблема не возникнет, когда скорость загрузки css выше, чем у js.

Однако, чтобы облегчить наблюдение за стилями во время локальной разработки, нам нужно воссоздатьfont-sizeУстановите его обратно на 1.0.

document.documentElement.style.fontSize = `${(window.innerWidth * 20) /
    320 / window.devicePixelRatio}px`;
let viewportEl = document.querySelector('meta[name="viewport"]');
const content = `width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no`;
if (viewportEl) {
  viewportEl.setAttribute('content', content);
} else {
  viewportEl = document.createElement('meta');
  viewportEl.setAttribute('name', 'viewport');
  viewportEl.setAttribute('content', content);
  document.head.appendChild(viewportEl);
}

Таким образом, сторонние плагины на всей странице также имеют нормальный размер при локальной отладке~