10 PostCSS плагинов, которые сэкономят время вашему верстальщику


    У нас, у фронтендеров, есть такая категория инструментов, которые никак не решают стоящие перед нами задачи, а скорее влияют на сам процесс их решения. Изменяют его. Отношение к таким инструментам самое разное – начиная от мании в духе “давайте эту штуку пихать везде, это же так круто” и заканчивая отговорками вроде “раз не решает задачи бизнеса, значит оно нам не нужно”. Но, так или иначе, сегодня мы поговорим про PostCSS — один из таких инструментов.


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


    PostCSS vs SASS


    Ох… Видимо стоит сказать пару слов про это. Думаю сейчас редкий верстальщик не встречался с препроцессорами. SASS или любимый мною LESS, реже Stylus, применяют и на больших проектах, и на маленьких. Кто-то пытается выжимать из них максимум, кто-то использует минималистичный набор – вложенность, переменные, импорты. Но, так или иначе, эти инструменты помогают с вопросами синтаксиса. Они делают так, чтобы нам было удобнее писать код.


    Года два-три назад PostCSS постоянно сравнивали с препроцессорами. И это понятно. Формально с его помощью можно сделать все то же самое, сделать какой-то синтаксис, который будет удобнее, чем чистый CSS. Но все это вызывало бурления в массах, в основном потому, что каждый с помощью PostCSS делал что-то свое. Бесчисленные неизвестные плагины, миллионы комбинаций и кроме автора того или иного конфига никто не понимал, как он работает и что делает. Это как Vim или Emacs – можно из них сделать космический корабль, но научить другого разработчика им пользоваться будет очень непросто.


    Но если эти сравнения отбросить, то PostCSS – это инструмент, который позволяет взять наш CSS и что-то с ним сделать. Никто не мешает использовать SASS ради синтаксиса, а после сборки воткнуть PostCSS и что-то сделать с результатом. Они друг другу не противоречат.


    Старое – не значит неработающее


    В последнее время у нас модно создавать комбайны, которые умеют делать все, что только в голову придет, и их разработка никогда не прекращается. А если в репозитории уже пару месяцев нет свежих коммитов, то все – можно считать, что он устарел и пользоваться им теперь – не комильфо. Я утрирую, конечно, но думаю вы и сами замечали, до какого абсурда это иногда доходит.


    В мире PostCSS обычно один плагин решает одну задачу. Можно тут увидеть элементы философии Unix. Из этого следует логичный вывод – если плагин уже решает свою задачу, то больше с ним ничего особо делать не нужно. Вы можете встретить плагины, которые годами не обновлялись, но это не значит, что они вдруг перестали решать задачи, для которых были созданы.


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


    №1. Doiuse


    https://github.com/anandthakker/doiuse


    Думаю все мы сталкивались с такой проблемой: пишешь код, проверяешь в хроме – все ок. Проверяешь в FF – ок. А потом в мобильном Safari все разваливается. Или в Edge. И ты сидишь и не понимаешь, что не так. Потом долго пялишься в код, пьешь чай, и вдруг приходит озарение, что какое-то свойство не поддерживается в каком-то браузере. Идешь на caniuse и видишь подтвержение очевидного.



    Конечно, с опытом руки сами запоминают, какие свойства нужно избегать, но всякое бывает. Можно не выспаться, могут быть сжатые сроки и нервы, может поменяться список браузеров, которые нужно поддерживать. И тут опыт начнет подводить. Doiuse – это инструмент, который очень выручает в таких ситуациях.


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


    Список браузеров мы можем задавать прямо в package.json. Просто и удобно. PostCSS использует browserslist и, если вы не видели раньше, то выглядит это примерно так:


    "browserslist": [
        "> .5% and last 2 versions",
        "not dead",
        "not OperaMini all",
        "ie >= 11",
        "Edge >= 12"
    ]

    Также есть конфиг самого doiuse, в котором можно заставить его игнорировать некоторые группы свойств, если вы уверены, что это ни на что не влияет. Например если вы используете полифилы или от потери поддержки какого-то свойства ничего не изменится:


    ignore: [
        'will-change',
        'object-fit'
    ]

    Стандартный лог, который дает плагин, не очень читаемый. Он содержит много информации и воспринимать его не очень удобно. Но это дело поправимое. В том же конфиге мы можем сделать свою функцию для формирования лога.


    Используйте console.log чтобы сообразить, как устроен объект, который передает PostCSS в эту функцию. Там много всего интересного.

    Моя практика показала, что самый удобный вариант – это выводить селекторы и конкрентые свойства, которые не поддерживаются, без уточнения браузеров и строк кода. Если в проекте используется БЭМ или какие-то аналоги, и код компонентов распределен по отдельным файлам, то такой подход позволяет быстро находить проблемное место не нагружая мозг.


    onFeatureUsage(info) {
        const selector = info.usage.parent.selector;
        const property = `${info.usage.prop}: ${info.usage.value}`;
    
        let status = info.featureData.caniuseData.status.toUpperCase();
    
        if (info.featureData.missing) {
            status = 'NOT SUPPORTED'.red;
        } else if (info.featureData.partial) {
            status = 'PARTIAL SUPPORT'.yellow;
        }
    
        console.log(`\n${status}:\n\n    ${selector} {\n        ${property};\n    }\n`);
    }

    Чтобы не писать специальные последовательности символов для цветов в консоли, можно подключить пакет colors, с ним будет удобнее.


    При сборке будет примерно такой вывод в консоли:


    NOT SUPPORTED:
    
        html {
            -ms-text-size-adjust: 100%;
        }
    
    NOT SUPPORTED:
    
        html {
            -webkit-text-size-adjust: 100%;
        }
    
    PARTIAL SUPPORT:
    
        body {
            display: flex;
        }

    №2. Autoprefixer


    https://github.com/postcss/autoprefixer


    Даже как-то неловко про него говорить, но уж слишком часто вижу людей, которые в 2019 году пишут префиксы руками и еще уверяют окружающих, что они точно знают, какие из них нужны, а какие – нет. Такие действия приводят к тому, что код зарастает кучей ненужных префиксов и становится совершенно нечитаемым. Это влияет на производительность труда. С другой стороны, если нужна поддержка динозавров, то всегда можно что-то забыть. Так что от ручного труда при решении этой задачи стоит избавляться.


    Автопрефиксер работает все с той же базой caniuse, использует тот же browserslist и может добавлять в CSS те префиксы, которые действительно нужны в указанных нами браузерах. При этом сам код становится чище, а работа идет быстрее.


    №3. Stylelint


    https://github.com/stylelint/stylelint


    Когда много и быстро печатаешь, то рано или поздно начинаешь допускать много ошибок, совершенно их не замечая. Глаз замыливается. В случае с CSS это может давать забавный (на самом деле нет) эффект, когда ты смотришь в браузер – видишь проблему с версткой. Смотришь в код – ее там нет. Смотришь в браузер – она есть. А в коде – нет. В результате можно долго искать сложную проблему, совершенно не замечая, что просто очепятался. Чтобы такого не было, придумали линтеры.


    Stylelint – это популярный вариант. Он умеет работать с синтаксисами основных препроцессоров, знает о последних веяниях в CSS, можно настраивать на свой вкус – конфиги похожи на те, что у eslint. Формально этот инструмент можно использовать и сам по себе, без PostCSS, но не упомянуть его здесь было бы неправильно.


    №4. Postcss-flexbugs-fixes


    https://github.com/luisrudge/postcss-flexbugs-fixes


    Или в более широком смысле postcss-fixes, в состав которого этот плагин входит. Медленно, но верно, флексы вытесняют старый подход к верстке на флоатах. Это хорошо, но все мы знаем, что с ними связан набор багов. Они описаны в репозитории flexbugs. Некоторые из них требуют к себе особого внимания, но также есть несколько штук, которые настолько простые, что постоянно вылетают из головы. Например IE игнорирует функцию calc в сокращенной записи свойства flex. Это не так часто нужно, но если понадобится, то руки могут сами написать сокращенный вариант и потом придется долго думать, в чем проблема. К счастью это дело можно исправить в автоматическом режиме. На помощь приходит плагин postcss-flexbugs-fixes.


    В примере с calc он найдет в коде фрагменты вроде этого:


    .foo {
        flex: 1 0 calc(1vw – 1px);
    }

    И развернет их:


    .foo {
        flex-grow: 1;
        flex-shrink: 0;
        flex-basis: calc(1vw - 1px);
    }

    Просто и удобно.


    №5. Postcss-preset-env


    https://github.com/csstools/postcss-preset-env


    Раз уж мы говорим про поддержку браузерами, то будет не лишним сказать про postcss-preset-env. Раньше ту же роль выполнял cssnext. Этот плагин будет полезен, если вы интересуетесь новыми веяниями в CSS.



    Многие из нововведений технически можно реализовать и старыми методами, просто это будет долго, многословно и некрасиво. Preset-env помогает писать код по-новому, экономить на этом время, а потом преобразовывать его в старый надежный вариант. Разумеется, некоторые вещи вроде кастомных свойств совсем не реализованы в старых браузерах, так что там будут применяться фолбеки.


    Как можно догадаться по названию инструмента, он напоминает одноименный пресет у Babel. Здесь все так же – много преобразователей, собранных в один стабильный набор. Некоторые преобразования требуют последующее подключение скриптов-полифилов на клиенте, но большинство реализуется чисто средствами CSS. Насколько я понимаю, для Stage2+ скрипты не нужны. Во всяком случае не сталкивался с их необходимостью. Поправьте меня, если я что-то там пропустил.


    №6. Postcss-animation


    https://github.com/zhouwenbin/postcss-animation


    Часто слышу от разных людей (в основном это бэкендеры, которые не очень сильны в CSS), что они хотят использовать отдельные анимации из animate.css, но считают плохой идеей подключать всю библиотеку целиком. Вполне логично. Но в результате они тратят много времени пытаясь повторить эти анимации самостоятельно.



    Плагин postcss-animation очень ускоряет этот процесс. Мы пишем только название анимации, например:


    .foo {
        animation-name: bounce;
    }

    А он сам подтягивает из animate.css реализацию и вставляет ее в код.


    .foo {
        animation-name: bounce;
    }
    
    @keyframes bounce {
        from, 20%, 53%, 80%, to {
            animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
            transform: translate3d(0,0,0);
        }
        40%, 43% {
            animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
            transform: translate3d(0, -30px, 0);
        }
        70% {
            animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
            transform: translate3d(0, -15px, 0);
        }
        90% {
            transform: translate3d(0,-4px,0);
        }
    }

    №7. List-selectors


    https://github.com/davidtheclark/list-selectors


    Когда у вас есть несколько верстальщиков и много стилей, встает вопрос о code review, о том, что было бы неплохо иногда глазами видеть общую картину со всеми селекторами, которые у нас есть. Знать, какие ID используются, есть ли селекторы по тегам или насколько соблюдается принятая методология. Особенно это важно, когда вы проверяете код новичка, который может писать странные вещи, которые формально будут работать, но фактически будут идти вразрез с принятыми соглашениями (далеко не везде эти соглашения хорошо зафиксированы и есть возможность такие вещи автоматизировать). Самому пролистывать многочисленные файлы со стилями, чтобы проверить адекватность селекторов, долго. Нужен способ вычленить их и показать отдельно. List-selectors как раз решает эту задачу.


    Точно так же, как и doiuse, этот плагин позволяет использовать свою функцию для подготовки информации к выводу на экран. Можно вывести только то, что интересует, или раскрасить все в разные цвета. Как пример:


    require('list-selectors').plugin((list) => {
        const inspect = require('util').inspect;
    
        console.log('SELECTORS:'.blue);
        console.log(inspect(list.selectors, { maxArrayLength: null }).blue);
        console.log('IDS:'.red);
        console.log(inspect(list.simpleSelectors.ids, { maxArrayLength: null }).red);
    })

    В этом примере получится длинный-длинный список селекторов:


    SELECTORS:
    [
      '.mui-progress-bar',
      '.mui-progress-bar > .indicator',
      '.mui-progress-bar > .value',
      '.mui-progress-bar.-radial',
      '.mui-progress-bar.-radial > .indicator',
      '.mui-progress-bar.-radial > .indicator > .background',
      '.mui-progress-bar.-radial > .indicator > .progress',
      '.mui-progress-bar.-radial > .value',
      . . .

    №8. Immutable-CSS


    https://github.com/johno/immutable-css


    Еще одна вещь, за которой стоит следить – это перебивание стилей из сторонних библиотек. Если мы подключили какую-то библиотеку, а потом начинаем для селекторов из нее писать свои стили, то в конечном счете получаем запутанный код, в котором не разобрать, что откуда взялось. Это может приводить к случайным багам, которые потом отнимают слишком много времени на ровном месте. Чем больше раз мы что-то переопределяем, тем сложнее в конечном счете понять, что происходит, хотя сама проблема, которую нужно решить, может быть очень простой. В этой ситуации может пригодиться инструмент под названием immutable-css.


    В целом принцип его работы прост: берет файлы со стилями, если находит совпадения по селекторам – начинает возмущаться:


    !  .button was mutated 2 times
    [line 93, col 1]: /css/basscss.css
    [line 3, col 1]: /css/custom.css
    [immutable-css]
    !  .left was mutated 2 times
    [line 291, col 1]: /css/basscss.css
    [line 4, col 1]: /css/custom.css
    [immutable-css]

    Единственная проблема у данного инструмента – это то, что он не поддерживает не-CSS синтаксис. Так что если в проекте используются препроцессоры, то сравнивать приходится уже собранные файлы. Но в целом, если задача состоит в том, чтобы просто убедиться, что никто случайно не переписал стили из сторонней библиотеки, то это не так важно.


    №9. Bye-Bye!


    https://github.com/AoDev/css-byebye


    Думаю всем знакома ситуация, когда мы постепенно добавляем какие-то компоненты на работающий сайт. Какие-то из них отправляются сразу в продакшен, а какие-то долго сидят и ждут своей очереди (например сверстать-то мы сверстали, а не бэкенде еще что-то не доделали). Что-то может быть экспериментом или временным решением на праздники. Ситуаций может быть много, но их объединяет то, что у нас набирается куча компонентов, а на боевом сайте используются лишь малая часть из них. Было бы хорошо убрать все, что не используется, из текущей сборки. Это может заметно уменьшить ее размер, а также снизить головную боль в перспективе, когда нужно будет делать редизайн к примеру, и встанет вопрос, что же из всего этого действительно нужно переписывать сейчас, а что — нет.



    Есть разные подходы к этому вопросу. На ум сразу приходит uncss. Этот инструмент в автоматическом режиме определяет, какие стили используются на страницах и убирает лишнее. Но на практике это почти всегда приводит к тому, что никто не знает, что реально используется, а что – нет. А еще я все время сомневаюсь, не удалил ли этот инструмент чего лишнего. Но это наверное уже моя паранойя. Хотя...


    Bye-bye – это более простой инструмент, которому мы сами скармливаем список селекторов, которые нужно убрать из CSS. Причем можно использовать регулярные выражения. Если вы применяете БЭМ или что-то еще в этом духе, то одной простой регуляркой можно удалять блок со всем, что к нему относится. Bye-bye!


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


    №10. PostCSS-trolling


    https://github.com/juanfran/postcss-trolling


    Все предыдущие инструменты могут незначительно повысить производительность труда ваших верстальщиков, но этот дает просто феноменальные результаты. Очень рекомендую.


    Заключение


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

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

    Используете ли вы PostCSS в своих проектах?

    Поддержать автора
    Поделиться публикацией

    Похожие публикации

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 14

      0
      UI developer. Верстаю неверстаемое

      Наверстай упущеное.

      Спасибо. Есть кое-что интересное.
        +1

        Ребят, давайте откровенно, сам постцсс — это для довольно специфических ситуаций полезен. В остальных случаях, это больше дань моде, т.к. «старые» инструменты работают не хуже и нет смысла переходить со старого стека на постцсс. Новичкам подобные помощники только помешают научиться нормально верстать из-за исправления ошибок, а профи и без этого знают что и как. Да, линтеры, автопрефиксер очень важны и нужны, но вот польза остальных плагинов(кроме последнего) не так очевидна.

          +2
          нет смысла переходить со старого стека на постцсс

          Так никто и не говорит, что нужно отказаться от старого стека. PostCSS — это дополнение, помогающее с некоторыми вопросами, а не замена.
          –1
          Вроде на дворе 2019 год, а кто то еще не знает про postcss?
            0
            Мне тоже до определенного момента казалось, что уж такие вещи все знают, но оказалось, что это совсем не так. Особенно в небольших компаниях — там люди долго варятся в собственном соку и зачастую совершенно не в курсе происходящего в отрасли.
              –1
              В отрасли происходит форменная жесть. Этого знания достаточно.
                0
                достаточно, чтобы нажраться пива, но не решать задачу. Мне статья очень зашла.
            +1
            Как то всегда слегка раздражает обилие линтеров, пост и препроцессоров. Ощущается как удавка немного. Возможно я не вел команду фронтов и чего то не понимаю.
              0

              Пожалуйста, прежде чем добавлять к себе Postcss-preset-env прочитайте что именно он за собой тянет. Вашему проекту совсем не обязательно нужно применять столько трансформаций при каждой сборке. Вполне возможно что будет достаточно взять 1-2 плагина из этой сборки и подключить их отдельно. Это будет так же наглядно отражать какие конкретно зависимости есть в вашем проекте, вместо одной зависимости на всё.

                0
                Спорный момент. С одной стороны — да, все верно. С другой — если проектов много, разные люди приходят и что-то добавляют от себя, рано или поздно получается зоопарк. Везде разные наборы трансформаций и каждый раз вникать в то, что же там есть, совсем не хочется. А с postcss-preset-env — один стабильный набор. Он может быть избыточным, но зато везде один и тот же. Это удобно.
                  0

                  Если на проектах каждый добавляет что-то от себя вы в любом случае придёте к ситуации когда объём зависимостей будет выглядеть как зоопарк. Только на одной чаше весов у вас контролируемый и чёткий список зависимостей, а на другой чёрная коробка, в которой может быть что угодно. По-моему между очевидным и неочевидным выбора не стоит. Я не очень понимаю аргумент с «каждый раз вникать», ведь чтобы работать с post-css-env вам нужно сначала вникнуть во все плагины которые там есть, что по мыслительной нагрузке будет всегда больше чем разбираться в отдельных плагинах.


                  Представьте что человек написал код на stage 0 и ни кому об этом не сказал (а код-ревью вёрстки это скорее исключение чем правило), вы это никак не проконтролируете с таким плагином и люди будут так писать потому что это просто. Всё-таки когда вам нужно приложить некоторые усилия чтобы писать на stage 0 это очень мотивирует несколько раз подумать а нужно ли оно вообще и можно ли решить эту проблему как-то иначе. Если мы говорим про хорошие практики то все они строятся именно на том чтобы максимально уменьшить возможность сделать плохо для проекта\команды. И в данном случае post-css-env является очень плохой практикой, которая по факту развязывает руки для давнокода.


                  Так же стоит отметить что post-css-env всего лишь агрегатор плагинов. Если у вас поломался какой-то из этих плагинов вам придётся ждать когда фикс добавят в post-css-env (или форкать и фиксить самому), вместо того чтобы обновить плагин отдельно.

                    0
                    Я не очень понимаю аргумент с «каждый раз вникать», ведь чтобы работать с post-css-env вам нужно сначала вникнуть во все плагины которые там есть, что по мыслительной нагрузке будет всегда больше чем разбираться в отдельных плагинах.

                    Один раз вникнув в современный синтаксис, потом везде его используешь. А если наборы разные, то очень велика вероятность прийти, написать что-то и только потом при тестировании в разных браузерах обнаружить, что какой-то трансформации нет и все сломалось. Это как ES6 и Babel — научился использовать новый синтаксис и используешь его везде, не задумываясь, что какая-то его часть может внезапно отсутствовать. Вы же не скажете, что там тоже нужно все трансформации по одной собирать?

                    Если у вас поломался какой-то из этих плагинов вам придётся ждать когда фикс добавят в post-css-env (или форкать и фиксить самому), вместо того чтобы обновить плагин отдельно.

                    Эти плагины решают конкретные задачи, их нет смысла постоянно обновлять.
                      0

                      То что у Babel есть preset-env совершенно не означает что он делает тоже самое что postcss-preset-env. Как раз в бабеле полифилятся полностью готовые спецификации, см. https://new.babeljs.io/docs/en/next/babel-preset-env.html
                      Это похоже скорее на autoprefixer, чем на preset-env.
                      И бабель уже проходил путь preset-stage-0, что-то похожее на то что в PostCSS, только в postcss-preset-env ситуация ещё хуже потому что смешались все стейджи: 0, 1, 2, 3. И вот к чему это привело у бабеля: https://babeljs.io/blog/2018/07/27/removing-babels-stage-presets


                      А если наборы разные, то очень велика вероятность прийти, написать что-то и только потом при тестировании в разных браузерах обнаружить, что какой-то трансформации нет и все сломалось.

                      А каким образом postcss-preset-env решает эту проблему? Какая разница как подключен плагин который не полифилится в конкретном браузере? Вы и в сборке и по отдельности получите эту проблему.


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

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

                        0
                        Хорошо, с Babel пример не очень удачный получился.

                        А если наборы разные, то очень велика вероятность прийти, написать что-то и только потом при тестировании в разных браузерах обнаружить, что какой-то трансформации нет и все сломалось.
                        А каким образом postcss-preset-env решает эту проблему?

                        Мы будто о разных вещах говорим. Допустим я использую all в одном проекте. Привык, что эта штука есть. Перехожу в другой проект, по привычке ее использую, даже не думая, что ее может не быть, но потом тестировщик говорит, что в IE все сломалось. А почему? Потому что в местном конфиге эту трансформацию не включили. А если проектов 10? 20? В одних эта трансформация уже есть, а в других — еще нет. Не проверять же каждый раз перед работой список зависимостей. Postcss-preset-env дает один и тот же набор. Не будет такого, что что-то есть, есть, а потом раз — и нету.

                        если плагин работает некорректно его нужно починить… там добавились какие-то фишки

                        Работал, работал и вдруг сломался? Не припомню за последний год такого. И опять возвращаемся к тому, что новая функциональность в них не добавляется. Каждый решает только одну задачу и они обычно годами не обновляются.

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

              Самое читаемое