Frog Proger 04 декабря 2024

🎨⚛️ CSS в React: сравниваем 5 подходов к стилизации

Стилизация React-приложений может быть сложной задачей: существует множество подходов, и выбор подходящего способа влияет на удобство разработки, производительность приложения и легкость управления кодом. Разберем основные методы стилизации, их преимущества и недостатки.
🎨⚛️ CSS в React: сравниваем 5 подходов к стилизации
Этот материал взят из нашей еженедельной email-рассылки, посвященной фронтенду. Подпишитесь, чтобы быть в числе первых, кто получит дайджест.

Ванильный CSS

Это традиционный метод стилизации, при котором вы пишете стили в отдельных CSS-файлах и подключаете их к компонентам:

        // styles.css
.button {
  background-color: blue;
  color: white;
  padding: 10px;
}

// Button.js
import React from 'react';
import './styles.css';

function Button() {
  return (
    <button className="button">
      Follow The T-Shaped Dev
    </button>
  );
}

export default Button;
    

Плюсы:

  • Самый простой и знакомый большинству разработчиков способ.
  • Не требует дополнительной настройки проекта.

Минусы:

  • Глобальная область видимости может привести к конфликтам имен классов.
  • Отсутствие инкапсуляции стилей – сложно управлять стилями в крупных проектах.
  • Ограниченные возможности динамической стилизации.
  • Названия для множества классов приходится придумывать самостоятельно.

Разделение файлов для стилей и компонентов приводит к частым переключениям контекста (нет локальности поведения).

CSS-препроцессоры и постпроцессоры

CSS-препроцессоры (например, SASS/SCSS, LESS) добавляют возможности вроде переменных, вложенности, циклов и др. Затем код компилируется в обычный CSS.

CSS-постпроцессоры (PostCSS с Autoprefixer, Tailwind CSS и т.д.) добавляют функциональность после написания CSS, например, автоматическое добавление вендорных префиксов.

Принцип работы пре- и постпроцессоров
Принцип работы пре- и постпроцессоров
Пример SASS/SCSS
        // styles.scss
$primary-color: blue;

.button {
  background-color: $primary-color;
  color: white;
  padding: 10px;

  &:hover {
    background-color: darken($primary-color, 10%);
  }
}

// Button.js
import React from 'react';
import './styles.scss';

function Button() {
  return (
    <button className="button">
      Follow The T-Shaped Dev
    </button>
  );
}

export default Button;
    

Преимущества препроцессоров:

  • Расширенные возможности – переменные, вложенность, условные операторы, циклы, миксины.
  • Более модульный и структурированный код.

Недостатки препроцессоров:

  • Требуют дополнительной настройки.
  • Стили по-прежнему глобальны (конфликты классов).
  • Разделение стилей и компонентов.
  • Имена классов нужно придумывать самостоятельно.

Tailwind CSS

Утилитарный CSS-фреймворк, в котором используются одноцелевые классы.

Пример стилизации кнопки в React с помощью Tailwind CSS
        import React from 'react';

function Button() {
  return (
    <button className="bg-blue-500 text-white p-2 hover:bg-blue-700">
      Follow The T-Shaped Dev
    </button>
  );
}

export default Button;
    

Преимущества Tailwind CSS:

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

Недостатки Tailwind CSS:

  • Компоненты могут быть перегружены классами.
  • Относительная сложность изучения.
  • Требует дополнительной настройки для кастомизации.

CSS-модули

CSS-модули позволяют писать CSS-файлы, где классы по умолчанию имеют локальную область видимости. Это предотвращает конфликты имен классов и делает стили модульными.CSS-модули можно использовать вместе с CSS-препроцессорами SASS/SCSS.

Пример использования CSS-модуля
        // Button.module.css
.button {
  background-color: blue;
  color: white;
  padding: 10px;
}

// Button.js
import React from 'react';
import styles from './Button.module.css';

function Button() {
  return (
    <button className={styles.button}>
      Follow The T-Shaped Dev
    </button>
  );
}

export default Button;
    

Плюсы CSS-модулей:

  • Локальная область видимости стилей исключает конфликты имен классов. Каждый стиль применяется только внутри конкретного компонента.
  • Гибкость – можно использовать как обычный CSS, так и CSS-препроцессоры.
  • Поддержка модульности – стили привязаны к конкретным компонентам, что улучшает читаемость и поддержку кода.

Минусы CSS-модулей:

  • Приходится придумывать уникальные имена для разных элементов.
  • Стили хранятся отдельно от компонентов, нет локальности поведения.

CSS-in-JS библиотеки

Библиотеки styled-components, emotion, vanilla-extract, и linaria позволяют писать CSS непосредственно в JavaScript-файлах. Этот подход позволяет стилизовать компоненты с использованием синтаксиса JavaScript, а стили автоматически связываются с конкретными компонентами, что исключает конфликты имен классов.

Типы CSS-in-JS библиотек:

  • Runtime-библиотеки (styled-components, emotion) – стили создаются во время выполнения.
  • Compile-time библиотеки (vanilla-extract, linaria) – стили компилируются на этапе сборки, что может повысить производительность.
Пример использования CSS-in-JS
        import React from 'react';
import styled from 'styled-components';

const ButtonStyled = styled.button`
  background-color: blue;
  color: white;
  padding: 10px;

  &:hover {
    background-color: brown;
  }
`;

function Button() {
  return (
    <ButtonStyled>
      Follow The T-Shaped Dev
    </ButtonStyled>
  );
}

export default Button;

    

Плюсы CSS-in-JS:

  • Инкапсуляция стилей – стили связаны с компонентами, что предотвращает конфликты имен классов и упрощает управление кодом.
  • Динамическая стилизация позволяет использовать JavaScript и свойства компонентов (пропсы) для изменения стилей.
  • Локальность поведения устраняет необходимость переключаться между файлами.
  • Нет необходимости придумывать имена классов.

Минусы CSS-in-JS:

  • Зависимости – дополнительные библиотеки увеличивают размер сборки.
  • Требует изучения синтаксиса и особенностей работы библиотек.
  • Runtime-библиотеки могут замедлять приложение.
  • Проблемы с серверным рендерингом – некоторые библиотеки требуют дополнительных настроек для корректной работы на сервере.

Как выбрать оптимальный подход

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

  • Стили находятся внутри компонентов. Это упрощает их поддержку, управление и расширение.
  • Простота понимания кода. Читая файл от начала до конца, легко понять, что происходит внутри компонента.
  • Не нужно придумывать имена классов. И нет необходимости управлять отдельными CSS-файлами.
  • Нет переключения контекста. Стили находятся прямо в компоненте, поэтому не нужно искать классы в других файлах и разбираться, где они применяются.
  • Гибкость. Если стили компонента становятся слишком большими, их можно вынести в отдельные файлы, сохраняя чистоту кода. При этом мы не теряем преимущества локализованных стилей.

Примечание: библиотека twin.macro позволяет комбинировать удобство и мощь Tailwind CSS с подходом CSS-in-JS. С ее помощью можно использовать классы Tailwind прямо в JavaScript-коде, сохраняя модульность и локализованность стилей:

        import React from 'react';
import tw from 'twin.macro';

const ButtonStyled = tw.button`
  bg-blue-500 text-white p-2 hover:bg-blue-700
`;

function Button() {
  return (
    <ButtonStyled>
      Follow The T-Shaped Dev
    </ButtonStyled>
  );
}
export default Button;

    
***

Какой подход к стилизации React-компонентов ты используешь в своих проектах и почему?

***

Хочу научиться писать React-приложения. Куда пойти учиться?

Погрузитесь в мир Frontend-разработки с нуля на курсе Frontend Basic: 26 практических видеоуроков помогут освоить HTML, CSS, JavaScript и React.js, а поддержка опытных менторов и доступ к крупнейшему IT-сообществу обеспечат уверенный старт в профессии.

Источники

Комментарии

ВАКАНСИИ

Добавить вакансию
Разработчик C++
Москва, по итогам собеседования

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ