Для чего нужны CSS module?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Для чего нужны CSS Modules
CSS Modules - это способ сделать CSS локальным по умолчанию, избежав конфликтов имен классов и улучшив инкапсуляцию стилей в компонентах.
Проблема, которую решают CSS Modules
В обычном CSS все классы глобальны, что может привести к конфликтам:
/* styles.css */
.button {
padding: 10px 20px;
background: blue;
}
/* в другом файле, разработчик не знает о существовании .button */
.button {
padding: 5px 10px;
background: red; /* Перезапишет предыдущий стиль! */
}
Результат: нужно использовать BEM, другие соглашения об именовании, или длинные уникальные имена классов.
Как работают CSS Modules
CSS Modules преобразуют классы в уникальные имена автоматически:
/* Button.module.css */
.button {
padding: 10px 20px;
background: blue;
color: white;
}
.buttonLarge {
padding: 15px 30px;
font-size: 18px;
}
.buttonDanger {
background: red;
}
В JavaScript:
import styles from './Button.module.css';
const Button = ({ size = 'normal', danger = false }) => {
return (
<button className={`
${styles.button}
${size === 'large' ? styles.buttonLarge : ''}
${danger ? styles.buttonDanger : ''}
`}>
Click me
</button>
);
};
Что происходит во время компиляции:
// styles = {
// button: "Button_button__2xvpK",
// buttonLarge: "Button_buttonLarge__3kDmX",
// buttonDanger: "Button_buttonDanger__pQ9aE"
// }
// HTML выведет уникальные классы:
// <button class="Button_button__2xvpK Button_buttonLarge__3kDmX">
Преимущества CSS Modules
1. Локальный scope по умолчанию
/* Modal.module.css */
.overlay {
position: fixed;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.5);
}
.container {
background: white;
padding: 20px;
border-radius: 8px;
}
Эти классы не конфликтуют с классами в других компонентах, даже если они называются одинаково.
2. Компонентная инкапсуляция
// Modal.jsx
import styles from './Modal.module.css';
export function Modal({ title, children }) {
return (
<div className={styles.overlay}>
<div className={styles.container}>
<h2>{title}</h2>
{children}
</div>
</div>
);
}
// Все стили привязаны к компоненту
// Нет утечек в глобальный scope
3. Автоматическое генерирование уникальных имен
Ты не беспокоишься о конфликтах имен. Компилятор сделает все за тебя.
4. IDE помощь и автозаполнение
import styles from './Button.module.css';
// IDE показывает доступные классы при печати styles.
<button className={styles.button}> {/* IDE поможет с автозаполнением */}
Синтаксис и практика
Базовое использование:
/* Card.module.css */
.card {
border: 1px solid #ddd;
border-radius: 8px;
padding: 20px;
background: white;
}
.cardTitle {
font-size: 20px;
font-weight: bold;
margin-bottom: 10px;
}
.cardContent {
font-size: 14px;
color: #666;
}
// Card.jsx
import styles from './Card.module.css';
export function Card({ title, children }) {
return (
<div className={styles.card}>
<h3 className={styles.cardTitle}>{title}</h3>
<div className={styles.cardContent}>{children}</div>
</div>
);
}
Условные классы:
import styles from './Button.module.css';
const cn = (classes) => Object.values(classes).filter(Boolean).join(' ');
export function Button({ disabled, primary }) {
return (
<button className={cn({
[styles.button]: true,
[styles.buttonPrimary]: primary,
[styles.buttonDisabled]: disabled
})}>
Click
</button>
);
}
// Или с helper функцией (clsx, classnames)
import cx from 'clsx';
export function Button({ disabled, primary }) {
return (
<button className={cx(
styles.button,
primary && styles.buttonPrimary,
disabled && styles.buttonDisabled
)}>
Click
</button>
);
}
CSS Modules vs Tailwind
Часто сравнивают CSS Modules с Tailwind CSS.
CSS Modules - когда использовать:
- Сложные стили со множеством свойств
- Нужна полная инкапсуляция
- Предпочитаешь писать CSS вместо запоминания классов Tailwind
- Нужна отладка через DevTools
/* Modal.module.css - сложные стили */
.modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
animation: modalAppear 0.3s ease-out;
}
@keyframes modalAppear {
from {
opacity: 0;
transform: translate(-50%, -60%);
}
to {
opacity: 1;
transform: translate(-50%, -50%);
}
}
Tailwind - когда использовать:
- Быстрое прототипирование
- Стандартные компоненты
- Не нужна сложная инкапсуляция
- Предпочитаешь utility-first подход
// Tailwind версия
export function Modal() {
return (
<div className="fixed inset-1/2 transform -translate-x-1/2 -translate-y-1/2 bg-white rounded-lg shadow-lg animate-modalAppear">
Content
</div>
);
}
CSS Modules в разных фреймворках
Create React App (по умолчанию поддерживает):
// Просто используй .module.css
import styles from './Component.module.css';
Next.js (встроенная поддержка):
// Файл: pages/components/MyComponent.module.css
// Использование то же
Webpack (нужно настроить):
// webpack.config.js
module: {
rules: [
{
test: /\.module\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: { modules: true }
}
]
}
]
}
Глобальные стили с CSS Modules
Для глобальных стилей не используй .module.css:
/* globals.css - обычный CSS */
body {
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto;
}
html, body, #root {
height: 100%;
}
// В главном файле приложения
import './globals.css'; // Просто импортируем
import styles from './App.module.css'; // CSS Modules для компонентов
Пример полного компонента
/* Header.module.css */
.header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
display: flex;
justify-content: space-between;
align-items: center;
}
.logo {
font-size: 24px;
font-weight: bold;
}
.nav {
display: flex;
gap: 20px;
}
.navLink {
color: white;
text-decoration: none;
padding: 8px 12px;
border-radius: 4px;
transition: background-color 0.3s;
}
.navLink:hover {
background-color: rgba(255, 255, 255, 0.2);
}
.navLink.active {
background-color: rgba(255, 255, 255, 0.3);
}
// Header.jsx
import styles from './Header.module.css';
export function Header({ activePage }) {
const links = ['Home', 'About', 'Contact'];
return (
<header className={styles.header}>
<div className={styles.logo}>MyApp</div>
<nav className={styles.nav}>
{links.map(link => (
<a
key={link}
href={`/${link.toLowerCase()}`}
className={`
${styles.navLink}
${activePage === link ? styles.active : ''}
`}
>
{link}
</a>
))}
</nav>
</header>
);
}
Вывод
CSS Modules нужны для:
- Изоляции стилей компонента от остального приложения
- Предотвращения конфликтов имен классов
- Автоматического генерирования уникальных имен
- Лучшей поддерживаемости больших приложений
- Компонентной архитектуры со строгой инкапсуляцией
Это особенно полезно в больших проектах, где много разработчиков работают одновременно и риск конфликтов высок.