Введение в CSS-in-JS: генерация CSS из JavaScript

автор vadim


Идея создания CSS в JavaScript стала более популярной за последние несколько лет, во многом благодаря доминированию реактивных фреймворков, таких как React и Svelte. Такие фреймворки не требуют использования JavaScript для стилизации компонентов, но они позволяют это сделать. Следовательно, появился ряд библиотек CSS-in-JS, чтобы упростить этот процесс.

Эта статья познакомит вас с CSS-in-JS, а затем продемонстрирует несколько перспективных фреймворков для его реализации.

Что такое CSS в JavaScript?

В CSS старой школы есть два варианта: встроенное определение и загрузка из внешнего файла. В обоих случаях браузер загружает CSS, анализирует его, а затем применяет стили к разметке. CSS-in-JS предлагает третий подход: предоставление CSS путем программного создания его в коде.

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

CSS-in-JS предоставляет синтаксис для преобразования вашего JavaScript в стили, которые может применять браузер. Независимо от используемой вами платформы, результат будет выглядеть примерно так, как показано в листинге 1.

Листинг 1. CSS-in-JS с инфраструктурой стилизованных компонентов


// Create a Title component that'll render an <h1> tag with some styles
const Title = styled.h1`
  font-size: 1.5em;
  text-align: center;
  color: palevioletred;
`;

// Create a Wrapper component that'll render a <section> tag with some styles
const Wrapper = styled.section`
  padding: 4em;
  background: papayawhip;
`;

// Use Title and Wrapper like any other React component – except they're styled!
render(
  <Wrapper>
    <Title>
      Hello World!
    </Title>
  </Wrapper>
);


Листинг 1 взят из структуры стилевых компонентов. Каждая структура имеет свои собственные соглашения, но этот пример дает вам основные аспекты любой системы:

  1. Определите CSS в синтаксисе JavaScript.
  2. Примените стили в разметке (например, JSX).

CSS на уровне компонента

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

CSS-in-JS решает эту проблему с помощью CSS на уровне компонентов. Почти все фреймворки JavaScript ориентированы на компоненты, поэтому создание CSS, ограниченного этими компонентами, является естественным решением.

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

Конечно, приложения по-прежнему должны иметь возможность применять стили и наследовать их. Любой достойный фреймворк CSS-in-JS должен решать эту проблему.

Одностраничные и многостраничные приложения

В последнее время было много шума по поводу одностраничных приложений по сравнению с многостраничными. В частности, возникают вопросы о том, какие части приложения могут быть полностью динамическими, какие можно предварительно визуализировать, а какие требуют и того, и другого. Суть CSS-in-JS в том, что стили должны создаваться там, где они необходимы; будь то на сервере или на клиенте. К счастью, это справедливо для большинства фреймворков.

CSS-in-JS-фреймворки

Первое, что вы обнаружите при рассмотрении реализации CSS-in-JS, — это количество доступных опций. Ваш лучший выбор будет зависеть, прежде всего, от используемой вами платформы JavaScript. Некоторые решения CSS-in-JS специфичны для конкретной реактивной среды, тогда как другие являются независимыми. Даже среди библиотек CSS-in-JS, не зависящих от фреймворка, часто существует близость к определенной фреймворку. Поэтому стоит подумать, какое решение CSS-in-JS популярно в сообществе, поддерживающем используемую вами платформу.

Еще одна особенность, которую следует учитывать при оценке фреймворков, — это поддержка TypeScript. Не все фреймворки CSS-in-JS работают с TypeScript, хотя это становится все более нормой.

Давайте посмотрим на некоторые из лучших доступных фреймворков.

Стилизованные компоненты

Styled-Components — один из старейших фреймворков CSS-in-JS. Он ориентирован на React (хотя есть попытки использовать его и в других местах) и в первую очередь касается стилизации компонентов React. Он довольно активен и популярен: на GitHub у него более 37 000 звезд.

В листинге 1 вы видели пример стилизованных компонентов.

Эмоция

Emotion не зависит от фреймворка, хотя, похоже, имеет сходство со Svelte. В листинге 2 приведен пример Emotion. Обратите внимание, что в примере мы рассматриваем встроенное определение CSS с использованием синтаксиса JavaScript.

Листинг 2. Встроенный CSS-in-JS Emotion


import { css, cx } from '@emotion/css'

const color="white"

render(
  <div
    className={css`
      padding: 32px;
      background-color: hotpink;
      font-size: 24px;
      border-radius: 4px;
      &:hover {
        color: ${color};
      }
    `}
  >
    Hover to change color.
  </div>
)

Стилизованный JSX

Styled JSX — это решение CSS-in-JS по умолчанию для Next.js, что, к сожалению, придает ему определенную инерцию. Это здоровый проект Git, имеющий более 7000 звезд, но он не так активен, как некоторые другие проекты, описанные здесь (у него есть ветка v2, которая, похоже, бездействует).

Стилизованный JSX — очевидный выбор, когда вы используете Next.js, но при желании можно заменить его на другую, дружественную к React библиотеку CSS-in-JS.

CSS-модули

Модули CSS — это ранняя и влиятельная реализация идеи CSS-in-JS. У проекта на GitHub более 16 000 звезд, но он не обновлялся уже несколько лет. Он не зависит от платформы и может быть интегрирован во многие популярные реактивные библиотеки. Например, вот это с Vue.

Модули CSS предназначены для общего решения, которое работает вне системы компонентов платформы и позволяет по умолчанию создавать локальные стили. Обратите внимание: хотя модули CSS звучат как официальная спецификация, на самом деле это не так — это проект с особым подходом к достижению CSS-in-JS.

Близнец

Tailwind CSS — это функциональная библиотека CSS. Он пользуется популярностью среди разработчиков JavaScript, поэтому неизбежно будет объединен с подходом CSS-in-JS. Twin сочетает в себе Tailwind с CSS-in-JS.

Twin позволяет нам использовать классы Tailwind в нескольких реализациях CSS-in-JS, как описано здесь. Это активный и растущий проект, имеющий более 6000 звезд на GitHub.

В Twin есть различные примеры того, как использовать его с различными платформами и инструментами сборки. Например, вот как его можно объединить с Emotion через Webpack.

JSS

JSS — это независимый от платформы подход, имеющий более 6000 звезд GitHub. Кажется, он довольно популярен и имеет хорошую документацию, хотя в последнее время в репозитории не наблюдается особой активности. JSS — одно из старейших активных решений CSS-in-JS и в некотором смысле прародитель этого движения.

Угловой

Angular, как и многие Reactive-фреймворки, поддерживает CSS на уровне компонентов. Система Angular довольно мощная и гибкая, с функциями, аналогичными другим библиотекам. Это соответствует философии дизайна Angular «все в одном» и, похоже, является наиболее распространенным подходом при использовании Angular. Однако можно использовать структуру CSS-in-JS, например JSS.

Недостатки использования CSS в JavaScript

Хотя CSS-in-JS очень популярен, существует противоположная тенденция. Причины сводятся к производительности и сложности. В недавней статье Сэма Магуры, активного сопровождающего фреймворка Emotion, подробно описываются эти проблемы. Основная проблема с производительностью заключается в том, что CSS-in-JS превращает CSS в фактор времени выполнения, что увеличивает объем работы, выполняемой браузером и платформой во время выполнения. Результатом является более медленная загрузка и увеличение количества кода, который может сломаться.

Но в статье также ясно описаны преимущества CSS-in-JS, о которых я рассказал в этой статье. Итак, решение состоит не в том, чтобы отказываться от CSS-in-JS, а в том, чтобы найти способ получить преимущества, минимизируя при этом недостатки. В статье обсуждаются различные возможные решения проблем производительности CSS-in-JS.

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

Заключение

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

Related Posts

Оставить комментарий