CSS Modules
CSS Modules — подход, при котором CSS-классы автоматически получают уникальные имена при сборке, предотвращая конфликты стилей между компонентами. Поддерживается Vite, Webpack, Next.js и другими bundler-ами.
Зачем нужно
В обычном CSS все классы глобальные: .title в одном файле конфликтует с .title в другом. CSS Modules автоматически делает классы локальными (scoped), генерируя уникальные имена. Это решает проблему конфликтов без изменения синтаксиса CSS.
Где используется
- React / Next.js проекты
- Vue.js (через
<style module>) - Любой проект с Vite или Webpack
- Компонентные архитектуры
Предпосылки
- BEM — ручной подход к изоляции (CSS Modules автоматизирует)
- Понимание bundler-ов (Vite, Webpack)
Базовое использование
Файл стилей (Button.module.css)
.button {
padding: 10px 24px;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 1rem;
}
.primary {
background: #007bff;
color: white;
}
.secondary {
background: #6c757d;
color: white;
}
.large {
padding: 14px 32px;
font-size: 1.125rem;
}
Импорт в компоненте (React)
import styles from './Button.module.css';
function Button({ variant = 'primary', size, children }) {
const className = [
styles.button,
styles[variant],
size === 'large' ? styles.large : ''
].filter(Boolean).join(' ');
return <button className={className}>{children}</button>;
}
Результат в HTML
<!-- CSS Modules генерирует уникальные имена -->
<button class="_button_x3k2d_1 _primary_x3k2d_7">
Отправить
</button>
Compose (композиция)
/* base.module.css */
.reset() {
margin: 0;
padding: 0;
border: none;
}
/* Button.module.css */
.button {
composes: reset from './base.module.css';
padding: 10px 24px;
border-radius: 6px;
cursor: pointer;
}
/* Или из того же файла */
.primary {
composes: button;
background: #007bff;
color: white;
}
:global — глобальные стили
/* Локальный класс (по умолчанию) */
.card {
padding: 16px;
}
/* Глобальный класс — не будет переименован */
:global(.active) {
border-color: #007bff;
}
/* Комбинация локального и глобального */
.card :global(.highlight) {
background: #fff3cd;
}
/* Блок глобальных стилей */
:global {
.page-title {
font-size: 2rem;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
}
}
Паттерны использования
Условные классы
import styles from './Alert.module.css';
function Alert({ type = 'info', children }) {
return (
<div className={`${styles.alert} ${styles[type]}`}>
{children}
</div>
);
}
С библиотекой clsx
import styles from './Card.module.css';
import clsx from 'clsx';
function Card({ featured, compact, className }) {
return (
<div className={clsx(
styles.card,
featured && styles.featured,
compact && styles.compact,
className
)}>
...
</div>
);
}
CSS Modules в Vue
<template>
<button :class="[$style.button, $style[variant]]">
<slot />
</button>
</template>
<style module>
.button {
padding: 10px 24px;
border-radius: 6px;
}
.primary {
background: #007bff;
color: white;
}
</style>
CSS Modules + CSS-переменные
/* Theme.module.css */
.light {
--bg: #ffffff;
--text: #333333;
--primary: #007bff;
}
.dark {
--bg: #1a1a2e;
--text: #e9ecef;
--primary: #4dabf7;
}
/* Card.module.css — использует переменные */
.card {
background: var(--bg);
color: var(--text);
border: 1px solid var(--primary);
}
Частые ошибки
- Обращение к классу как к строке:
/* ОШИБКА */ <div className="card"> /* ПРАВИЛЬНО */ <div className={styles.card}> - Дефисы в именах классов:
/* ОШИБКА — дефис в точечной нотации */ styles.card-title /* ПРАВИЛЬНО */ styles['card-title'] /* Или используйте camelCase в CSS */ .cardTitle { } - Забыли
.module.cssв имени файла — обычный.cssфайл не будет обработан как CSS Module - Стилизация дочерних компонентов — CSS Modules не стилизуют вложенные компоненты. Передавайте
classNameкак prop
Практика
- Создать компонент с CSS Modules (
.module.css) - Использовать
composesдля наследования стилей - Применить
:globalдля глобальных классов - Настроить условные классы через
clsx - Комбинировать CSS Modules с CSS-переменными
Связанные темы
- BEM — ручная изоляция стилей
- Sass — препроцессор (можно использовать
.module.scss) - CSS переменные — кастомные свойства