Некоторые из моих мыслей после года использования Tailwind CSS

React.js CSS

Примечание. Эта статья не предназначена для того, чтобы научить вас использовать Tailwind CSS.

Популярность Tailwind CSS сохраняет тенденцию к быстрому росту в последние два года, особенно в 2020 году. Это тема бурных дискуссий на крупных форумах/сообществах. На рисунке ниже показана динамика загрузок Tailwind CSS на npm за последние два года.

image.png

Я использую Tailwind CSS уже почти год, начиная с мая 2020 года. Если вы представляете Tailwind CSS одним предложением,Я думаю, что Tailwind CSS — это набор Atomic/Utility-First CSS-дизайна полной системы (Design System).

Atomic/Utility-First CSS

«Атомарный/полезный-первый CSS» — это спецификация CSS, противоположная «Семантическому CSS» (Semantic CSS). Независимо от того, слышали ли вы термин «семантический CSS», это наиболее часто используемая и традиционная спецификация CSS при разработке реальных проектов.

Возьмите пример на официальном веб-сайте Tailwind CSS в качестве примера, чтобы добиться следующего эффекта уведомления.Общий способ написания:

<div class="chat-notification">
  <div class="chat-notification-logo-wrapper">
    <img class="chat-notification-logo" src="/img/logo.svg" alt="ChitChat Logo">
  </div>
  <div class="chat-notification-content">
    <h4 class="chat-notification-title">ChitChat</h4>
    <p class="chat-notification-message">You have a new message!</p>
  </div>
</div>

<style>
  .chat-notification {
    display: flex;
    max-width: 24rem;
    margin: 0 auto;
    padding: 1.5rem;
    border-radius: 0.5rem;
    background-color: #fff;
    box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
  }
  .chat-notification-logo-wrapper {
    flex-shrink: 0;
  }
  .chat-notification-logo {
    height: 3rem;
    width: 3rem;
  }
  .chat-notification-content {
    margin-left: 1.5rem;
    padding-top: 0.25rem;
  }
  .chat-notification-title {
    color: #1a202c;
    font-size: 1.25rem;
    line-height: 1.25;
  }
  .chat-notification-message {
    color: #718096;
    font-size: 1rem;
    line-height: 1.5;
  }
</style>

Это типичный метод именования «Семантический CSS»: определите имена семантических классов для разных тегов html, а затем каждый класс будет содержать все стили CSS, примененные к соответствующим тегам html.

Однако по мере развития проекта эта спецификация css сделает поддержку css более дорогой:

  1. Именование затруднено. Все больше и больше похожих семантических сцен приведут ко все большему количеству имен классов, таких как aa-title, bb-title, bb-b1-title, aa-content, bb-content. Разработчики должны убедиться, что такие имена, как aa, bb, bb-b1, могут точно выражать семантику, и в то же время должны быть осторожны, чтобы избежать конфликтов, вызванных глобальной областью действия CSS (например, разные области пользовательского интерфейса определяют стиль, вызванный из-за конфликта aa-title; aa-content, bb-content непреднамеренно вложены друг в друга, в результате чего внутренние классы наследуют стили, которые не ожидаются внешними классами). Это создает большую психологическую нагрузку на разработчика.
  2. Сложно повторно использовать. Трудно повторно использовать стили css через классы с семантическими именами, потому что класс содержит несколько стилей css, и даже если несколько стилей css находятся в одной и той же семантической среде, на них будет влиять более широкий контекст, в результате чего некоторые стили будут разными и класс нельзя повторно использовать напрямую. Например, попытка добиться повторного использования css в соответствии с семантикой «заголовок» с помощью именования классов, таких как заголовок и заголовок-заголовок, определенно не сработает. Продолжение этого пути неизбежно приведет к появлению большего количества классов с похожими именами: nav-title, nav-min-title, sider-title... и эти классы, скорее всего, будут лишь одним из правил CSS, которые отличаются друг от друга. например, размер шрифта.
  3. Затраты на рефакторинг высоки. Это не обязательно серьезный рефакторинг общего стиля.Даже если все размеры шрифтов увеличены на 2 пикселя, в соответствии со спецификацией «Семантический CSS» для достижения этого необходимо изменить большое количество файлов.
  4. размер файла css завышен. Каждый класс содержит большое количество повторяющихся стилей CSS, что не может решить проблему повторного использования.Эти проблемы приведут к увеличению требований к проекту, файл CSS будет становиться все больше и больше, и вполне вероятно, что скорость расширения файла CSS будет больше. чем общий склад кода.темп роста объема.

Итак, как «Атомарный/Утилитарный-первый CSS» решает проблемы, с которыми сталкивается «Семантический CSS»? Давайте посмотрим на пример реализации того же с помощью Tailwind CSS:

<div class="p-6 max-w-sm mx-auto bg-white rounded-xl shadow-md flex items-center space-x-4">
  <div class="flex-shrink-0">
    <img class="h-12 w-12" src="/img/logo.svg" alt="ChitChat Logo">
  </div>
  <div>
    <div class="text-xl font-medium text-black">ChitChat</div>
    <p class="text-gray-500">You have a new message!</p>
  </div>
</div>

Данная версия реализации по сравнению с первой версией имеет следующие отличия:

  1. Мы не настраивали какие-либо классы CSS, все используемые классы CSS были напрямую получены из CSS Tailwind, так что нет проблем с именами, и это также решает проблему инфляции CSS. Конечно, размер html также увеличился, но поскольку класс использует ограниченный набор часто повторяющихся имен классов, его можно в основном игнорировать под действием алгоритмов сжатия, таких как Gzip и Brotli.
  2. Каждый класс обычно соответствует только одному правилу css, например, p-6 соответствует padding: 1.5rem, h-12 соответствует высоте: 3rem, гранулярность класса atomic, естественно, легче повторно использовать в других местах, а спецификация atomic css/Идея заключается в том, чтобы заставить разработчиков писать все необходимые классы при определении стилей для html-тегов, что значительно снижает взаимодействие между классами разных html-тегов.
  3. Использование «Atomic/Utility-First CSS» упрощает рефакторинг/изменение стиля в целом. Мы можем изменить общий стиль приложения, переопределив атомарный класс гранулярности, например, переписав text-xl на 2rem, чтобы размер шрифта класса text-xl стал 2rem.

Теперь кажется, что «атомарный/полезный CSS-первый» гораздо удобнее в сопровождении, чем «семантический CSS». Но есть одно замечание: «Atomic/Utility-First CSS» не предлагается Tailwind CSS, фактически «Atomic/Utility-First CSS» родился задолго до Tailwind CSS: basscss (2013), tachyons (2014) , и, конечно же, множество других подобных библиотек CSS.

Так почему же «Atomic/Utility-First CSS» так долго не прижился?

Поскольку одного «атомарного/утилитарного CSS» недостаточно, для фронтенд-разработки требуется полноценная система дизайна.

Система дизайна Tailwind CSS

Полная система проектирования должна предоставлять готовые функции для соответствия 80% бизнес-сценариев, в то же время она должна поддерживать хороший механизм расширения для соответствия остальным 20% бизнес-сценариев. Tailwind CSS — это не только решение «Atomic/Utility-First CSS», но и полноценная система дизайна.

Нестандартное использование Tailwind в основном отражается в:

  1. Токен с хорошо продуманным дизайном. Токен дизайна Tailwind включает в себя как обычные классы инструментов css, такие как box-border и box-content, которые управляют блочной моделью CSS, block и inline, которые управляют режимом отображения, так и float-right, float-left и float-none, которые управляют плавающее позиционирование. и т. д.; также включает предустановки для общих атрибутов стиля, таких как цвет и интервал. Например, под цветом часто используются маркеры цвета, такие как серый, черный, белый и красный. На основе этих маркеров создаются классы css. автоматически генерируется для использования в цвете шрифта, цвете фона, цвете границы и других правилах css, требующих настройки цвета, например, для маркера серого цвета, Tailwind будет генерировать text-gray (цвет шрифта), bg-gray (цвет фона), border -серый (цвет границы) цвет) и другие классы css. Кроме того, имена классов css, разработанные Tailwind, относительно легко запомнить и отличить.По сути, вы можете сделать вывод о соответствующих правилах css, увидев имена.
  2. Отзывчивая поддержка. Tailwind предоставляет общие маркеры точек останова по ширине экрана: sm, md, lg, xl, 2xl. Эти маркеры точек останова можно комбинировать с другими классами CSS, предоставляемыми Tailwind, для обеспечения быстрой поддержки. Такие как:
<!-- Width of 16 by default, 32 on medium screens, and 48 on large screens -->
<img class="w-16 md:w-32 lg:w-48" src="...">
  1. Поддерживаются состояния CSS, такие как псевдоклассы. Tailwind предоставляет часто используемые токены псевдокласса: hover, focus, active, first-child, last-child и т. д. Эти токены используются в сочетании с другими классами css, предоставляемыми Tailwind, для достижения эффектов псевдокласса. Например, кнопка ниже по умолчанию черная, а при наведении мыши красная:
<button class="bg-black hover:bg-red ...">
  Hover me
</button>
  1. Темный режим поддерживается. Tailwind предоставляет токен псевдокласса в темном режиме: dark. Пример использования следующий:
<div class="bg-white dark:bg-gray-800">
  <h1 class="text-gray-900 dark:text-white">Dark mode is here!</h1>
  <p class="text-gray-600 dark:text-gray-300">
    Lorem ipsum...
  </p>
</div>

Большинство решений «Atomic/Utility-First CSS» хорошо справляются с решением 80% бизнес-сценариев (с точки зрения соглашений об именах классов, я лично считаю, что Tailwind лучше, чем большинство других решений). Однако большинство решений "Atomic/Utility-First CSS" ориентированы только на предоставление служебных классов, а не на полную систему дизайна. Им не хватает хорошего механизма расширения, что приводит к невозможности решить оставшиеся 20% проблем. бизнес.сцены.

При использовании решения «Atomic/Utility-First CSS» одной из наиболее часто встречающихся проблем является следующая: когда предоставленного класса CSS по умолчанию недостаточно, как разработчики могут расширить или написать новые классы CSS? Общий подход к решению этой проблемы заключается в том, чтобы разработчики определяли дополнительные пользовательские стили css (класс css, встроенные стили и т. д.) в своем собственном бизнес-коде. Это нарушает Единый Источник Истины уровня стиля: когда требуется модификация стиля, разработчикам необходимо учитывать правила стиля как библиотеки «Atomic/Utility-First CSS», так и пользовательского источника css.

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

// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        'regal-blue': '#243c5a',
      },
      spacing: {
        '13': '3.25rem',
      }
    }
  }
}

Таким образом могут быть сгенерированы новые классы css: text-regal-blue (установить цвет шрифта), m-13 (установить поля), p-13 (установить отступы) и т. д.Механизм расширения Tailwind CSS гарантирует, что все спецификации слоя стилей взяты из одного и того же места — Tailwind.Конечно, механизм расширения Tailwind CSS намного мощнее, чем в приведенном выше примере.

Лучший способ повторного использования стилей

Хотя это было упомянуто ранее, «Atomic/Utility-First CSS» может лучше повторно использовать классы css. Однако, поскольку уровень повторного использования — это класс css на уровне атомарных частиц, очевидно, что повторное написание нескольких атомарных классов css в разных местах не является хорошей ремонтопригодностью. Например, никто не хочет писать следующую кучу классов каждый раз, когда они используют кнопку...

<!-- Repeating these classes for every button can be painful -->
<button class="py-2 px-4 bg-green-500 text-white font-semibold rounded-lg shadow-md hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-400 focus:ring-opacity-75">
  Click me
</button>

Среди фронтенд-тройки мушкетеров HTML, CSS и JS за представление отвечает HTML + CSS, а за логику — JS. Что касается представления, HTML является основой и центром, а CSS, по сути, выполняет работу по «украшению» HTML. Поэтому в большинстве случаев CSS не подходит для (семантического) повторного использования без HTML. Повторное использование CSS необходимо повторно использовать в виде шаблонов HTML или компонентов JS. Например, в приведенном выше примере с кнопкой мы можем завершить повторное использование CSS, инкапсулировав независимый компонент Button.

Некоторые разработчики считают, что жесткая обертка компонента Button «слишком тяжела» для повторного использования стилей CSS. Это неспроста. Для очень легких компонентов, таких как кнопки, также можно комбинировать связанные правила css, определяя класс css напрямую. Например, в Tailwind CSS вы можете сделать это:

  .btn-indigo {
    @apply py-2 px-4 bg-indigo-500 text-white font-semibold rounded-lg shadow-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-400 focus:ring-opacity-75;
  }

С помощью директивы @apply, предоставляемой Tailwind CSS, объедините существующие классы CSS и инкапсулируйте их в класс btn-indigo. Это гарантирует, что Tailwind CSS по-прежнему является единственным источником истины для слоя стилей.

CSS in JS

Разработчики, которым нравится писать «CSS на JS», могут использовать библиотеку twin.macro для ссылки на Tailwind CSS в «CSS на JS». Таким образом, вы можете не только воспользоваться преимуществами «CSS в JS», но и обеспечить единый источник правды Tailwind CSS в качестве уровня стиля. Вот пример:

import 'twin.macro'

const Input = () => <input tw="border hover:border-black" />

Минусы CSS попутного ветра

  1. Способ объявления нескольких классов css в каждом классе может сделать код некрасивым, особенно для пользователей, которые не знакомы с Tailwind. Однако по прошествии некоторого времени (для меня это около 1 недели) большинство разработчиков могут привыкнуть к такому способу написания.
  2. Проблемы со скоростью сборки. Особенно на этапе разработки, когда tailwind.config.js изменяется, например, при расширении нового класса, он запускает Tailwind для перестроения.Эта скорость построения относительно низкая (десятки секунд или даже десятки секунд), что имеет определенную влияние на опыт разработки. Однако в Tailwind CSS v2.1 появилась функция Just-in-Time Mode, которая может эффективно решить эту проблему.

Суммировать

Лично мне кажется, что в Tailwind CSS не так много «удивительных» функций, но когда дело доходит до создания полноценной системы дизайна, Tailwind CSS был тщательно разработан во всех аспектах, поэтому очень «удобно» использовать файлы «. Если вы еще не использовали Tailwind CSS, я предлагаю вам попробовать, я уверен, что это принесет вам ощущение свежести!

Время набора

Моя команда: ByteDanceКоманда веб-инфраструктуры, Долгосрочный набор передовых инженеров на всех уровнях, может базироваться в Пекине, Шанхае, Ханчжоу, Гуанчжоу, Шэньчжэне, Сингапуре. Заинтересованные студенты могут добавить меня в WeChat (xuchaobei) для консультации и отметить «Самородки». Конечно, другие отделы и должности ByteDance также могут обращаться ко мне за рекомендациями.