CSS Modules в React — локальные стили без конфликтов
TL;DR
CSS Modules позволяют локально скопировать имена классов CSS, чтобы стили не конфликтовали между компонентами. В React их легко использовать через create-react-app или настроить вручную через webpack и можно сочетать с Sass, типизацией и библиотеками объединения классов.

CSS Modules дают простой способ писать CSS, который автоматически превращает локальные имена классов в уникальные идентификаторы на этапе сборки. Это устраняет проблему перезаписи стилей при повторном использовании одноимённых классов в разных компонентах.
Что такое CSS Modules
CSS Module — это обычный CSS-файл, но с тем отличием, что его классы по умолчанию локальны для файла. Компилятор изменяет имена классов на уникальные значения перед отдачей кода браузеру, поэтому два файла с одинаковым классом .btn не будут конфликтовать.
Краткое определение: CSS Modules — это механизм локализации имён классов и переменных CSS, позволяющий хранить стили рядом с компонентами.
Преимущества:
- Изоляция стилей и отсутствие конфликтов.
- Удобство отладки: легко найти модуль со стилями конкретного компонента.
- Возможность композиции и повторного использования базовых стилей.
Короткий пример CSS-модуля (Button.module.css):
.btn {
width: 90px;
height: 40px;
padding: 10px 20px;
border-radius: 4px;
border: none;
}Импорт в компоненте (React):
import styles from './Button.module.css'
export default function Button() {
return (
)
}Во время сборки класс .btn превратится в уникальную строку вида Button_btn__a1b2c (формат зависит от конфигурации сборщика), и конфликтов с другими .btn не будет.
Как работает композиция стилей
CSS Modules поддерживают ключевое слово composes, которое позволяет «наследовать» набор правил из другого класса в том же модуле или из внешнего модуля.
Пример в одном файле:
.btn {
/* базовые стили */
width: 90px;
height: 40px;
padding: 10px 20px;
border-radius: 4px;
border: none;
}
.submit {
composes: btn;
background-color: green;
color: #FFFFFF;
}Композиция из другого модуля:
.submit {
composes: primary from '../colors.module.css';
background-color: green;
}Важно: правило composes обычно должно идти перед другими свойствами в блоке.
Использование в React
Если вы создаёте приложение с помощью create-react-app, поддержка CSS Modules доступна «из коробки» при соблюдении соглашения по имени файлов: .module.css или .module.scss. Если проект настраивается вручную, потребуется соответствующий лоадер в webpack.
Минимальные требования для примеров из этой статьи:
- Node.js установлен на машине.
- Базовые знания ES6 и модулей.
- Базовые знания React.
Создание приложения:
npx create-react-app react-css-modulesСтруктура для компонента Button:
- src/Components/Button/Button.js
- src/Components/Button/Button.module.css
- src/Components/colors.module.css
Пример компонента Button:
import styles from './Button.module.css'
export default function Button({ type = 'primary', label = 'Button' }) {
return (
)
}И соответствующие CSS-модули:
Button.module.css
.btn {
width: 90px;
height: 40px;
padding: 10px 20px;
border-radius: 4px;
border: none;
}
.primary {
composes: btn;
color: #FFFFFF;
background-color: #6E41E2;
}
.secondary {
composes: btn;
color: #6E41E2;
background-color: #FFFFFF;
}colors.module.css
.primaryBg {
background-color: #6E41E2;
}
.secondaryBg {
background-color: #FFFFFF;
}
.primaryColor {
color: #FFFFFF;
}
.secondaryColor {
color: #6E41E2;
}И затем использование композиции из внешнего модуля:
.primary {
composes: btn;
composes: primaryColor from '../colors.module.css';
composes: primaryBg from '../colors.module.css';
}Sass и CSS Modules
Вы можете использовать Sass с CSS Modules: достаточно переименовать файл в *.module.scss и подключить соответствующий лоадер. Sass добавляет переменные, вложенность и миксины, что делает стили более выразительными и удобными для масштабирования.
Пример Button.module.scss:
$radius: 4px;
$btn-padding: 10px 20px;
.btn {
width: 90px;
height: 40px;
padding: $btn-padding;
border-radius: $radius;
border: none;
}
.primary {
@extend .btn;
color: #fff;
background-color: #6E41E2;
}Замечание: синтаксис @extend работает на уровне CSS-препроцессора и отличается от composes. При использовании Sass вместе с CSS Modules следите за ожидаемым поведением и конфигурацией лоадеров.
Практические советы и приёмы
- Именование: используйте нейтральные имена вроде btn, header, list; уникальность достигается за счёт модулей, поэтому длинные BEM-имена не обязательны внутри модулей.
- Конвенция файлов: храните компонент и его модуль рядом: Components/MyComponent/MyComponent.js и MyComponent.module.css.
- Динамические классы: для объединения нескольких классов удобно использовать библиотеку classnames или простой шаблон строк:
import cn from 'classnames'
Типизация: в TypeScript добавьте декларацию модуля для *.module.css или используйте генераторы типов (typed-css-modules) чтобы получать автодополнение и проверку имён классов.
Тестирование: при unit-тестировании классы обычно маппятся в простые строки; настройте Jest так, чтобы он корректно обрабатывал CSS Modules (mock или transform).
Отладка: при локальной сборке включите понятный шаблон генерации имён (например [name][local][hash:base64:5]) — это упростит сопоставление между модулем и итоговым классом.
Когда CSS Modules не подходят
Контрпримеры и ограничения:
- Полезны для компонентного подхода, но если вы пишете глобальную тему или набор utility-классов (например tailwind), CSS Modules могут усложнить повторное использование.
- Для динамических стилизованных компонентов с пропами, зависящими от JS-логики, CSS-in-JS (styled-components, emotion) иногда удобнее.
- При быстрых прототипах, где важна скорость правок дизайнером напрямую в глобальном CSS, локализация может мешать.
Альтернативы:
- CSS-in-JS (styled-components, emotion) — плюсы: динамика стилей, вложенность, темы; минусы: рантайм-стоимость или сложность SSR.
- Utility-first (Tailwind) — другой подход к повторному использованию.
- БЭМ + глобальный CSS — всё ещё разумно для больших монолитных приложений без компонентной изоляции.
Конфигурация webpack для CSS Modules (пример)
Если вы собираете проект вручную, добавьте правило в webpack:
{
test: /\.module\.(css|scss)$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]__[local]__[hash:base64:5]'
}
}
},
'sass-loader'
]
}Это включит модульную обработку только для файлов с .module.css/.module.scss, оставляя обычные CSS-файлы глобальными.
Миграция и совместимость
- Постепенная миграция: переименовывайте только те файлы, которые вы хотите изолировать, в *.module.css. Остальной CSS остаётся глобальным.
- Интеграция с дизайном: договоритесь с командой дизайна о том, где использовать модули, а где — глобальные переменные/темы (например отдельный файл variables.module.css или CSS-переменные :root).
Риски и их смягчение
- Переизбыточная локализация: слишком мелкая сегментация стилей усложняет переиспользование. Решение: выделяйте набор утилит и темы глобально.
- Непонятные имена на проде: настройте шаблон генерации имён так, чтобы он был информативным в деве и компактным в проде.
Контроль качества и критерии приёмки
Критерии приёмки:
- Компонент загружает свой CSS-модуль и не влияет на внешний стиль других компонентов.
- Визуально кнопки/формы соответствуют дизайну в основных состояниях (по макету).
- Тесты не ломаются из-за отсутствия классов (Jest корректно маппит CSS в тестах).
- Производительность страницы не деградирует заметно после внедрения модулей.
Быстрый чеклист ролей
Разработчик:
- Следует соглашению по именованию файлов (*.module.css).
- Использует classnames для составных классов.
- Настраивает типизацию при TS.
Дизайнер:
- Передаёт цвета/переменные в общий модуль цветов.
- Проверяет контраст и доступность (цвета, фокус).
DevOps:
- Проверяет, что сборка для продакшена минифицирует и хеширует имена.
- Следит за sourcemaps и кэшированием статических ресурсов.
Короткий глоссарий
- CSS Modules: локальные CSS-файлы, компилируемые в уникальные имена.
- composes: директива CSS Modules для композиции классов.
- localIdentName: шаблон формирования итогового имени класса.
Итого
CSS Modules — удобный инструмент для изоляции стилей в компонентном приложении. Они просты в подключении через create-react-app и гибки при настройке через webpack. Использование композиций и Sass повышает повторное использование кода и упрощает поддержку больших интерфейсов.
Важно выбирать подходы в зависимости от архитектуры проекта: для дизайн-систем и глобальных тем разумно сочетать локальные модули и глобальные переменные.
Полезные шаги для старта:
- Создайте Button.module.css рядом с компонентом.
- Импортируйте styles и применяйте className={styles.btn}.
- По мере роста вынесите цвета и утилиты в отдельный colors.module.css.
- Для динамики используйте classnames и/или типизацию в TypeScript.
Примечание
При использовании изображений и путей убедитесь, что пути к ресурсам остаются неизменными в проекте. Для production-сборки подбирайте компактный формат имён, а в development — читаемый, чтобы облегчить отладку.
Похожие материалы
Несколько аккаунтов Skype: Multi Skype Launcher
Журнал для работы: повысить продуктивность
Персональные звуки уведомлений на Android
Скачивание шоу Hulu для офлайн‑просмотра
Microsoft Start: персонализированная новостная лента