CSS Modules — это метод организации CSS, который позволяет локализовать стили для конкретного компонента, предотвращая конфликты имен классов и упрощая поддержку крупных проектов. В основе лежит принцип, что каждый класс или идентификатор в CSS получает уникальное имя при импорте в JavaScript, что делает его изолированным от глобального пространства стилей.
В современных проектах на React или Next.js CSS Modules интегрируются через стандартный импорт:
import styles from './Button.module.css';
Здесь Button.module.css — файл с локальными стилями для
компонента Button. Важно использовать расширение
.module.css или .module.scss для корректной
работы модулей. После импорта объект styles содержит ключи,
соответствующие именам классов в CSS:
/* Button.module.css */
.button {
background-color: #0070f3;
color: white;
padding: 0.5rem 1rem;
border-radius: 4px;
border: none;
cursor: pointer;
}
// Button.jsx
<button className={styles.button}>Click me</button>
При сборке проекта класс .button будет преобразован в
уникальное имя, например Button_button__3fX4L, что
полностью исключает конфликты с другими .button.
CSS Modules по умолчанию локализует все классы. Для создания
глобальных стилей используется синтаксис :global:
/* Button.module.css */
:global(.reset) {
margin: 0;
padding: 0;
box-sizing: border-box;
}
В этом случае класс reset будет доступен глобально, а
все остальные стили останутся локальными.
CSS Modules прекрасно работают с динамическим назначением классов через условные выражения. Для удобства можно использовать библиотеку clsx или classnames:
import clsx from 'clsx';
import styles from './Button.module.css';
const Button = ({ primary }) => {
return (
<button className={clsx(styles.button, primary && styles.primary)}>
Click me
</button>
);
};
/* Button.module.css */
.button {
padding: 0.5rem 1rem;
border-radius: 4px;
border: none;
}
.primary {
background-color: #0070f3;
color: white;
}
clsx объединяет классы и применяет
styles.primary только если проп primary равен
true.
CSS Modules позволяет использовать все стандартные возможности CSS: вложенные селекторы, псевдоклассы, медиа-запросы:
/* Card.module.css */
.card {
padding: 1rem;
border: 1px solid #ddd;
border-radius: 8px;
transition: box-shadow 0.2s ease;
}
.card:hover {
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
@media (max-width: 768px) {
.card {
padding: 0.5rem;
}
}
Локализация классов сохраняется даже при использовании вложенных селекторов, что делает стили полностью компонентными.
Radix UI предоставляет низкоуровневые, полностью контролируемые компоненты интерфейса. Их стили можно легко адаптировать с CSS Modules, сочетая преимущества локальных стилей и готовых компонентов Radix. Например, для компонента Radix Dialog:
import * as Dialog from '@radix-ui/react-dialog';
import styles from './Dialog.module.css';
<Dialog.Root>
<Dialog.Trigger className={styles.trigger}>Open</Dialog.Trigger>
<Dialog.Content className={styles.content}>
<Dialog.Title className={styles.title}>Dialog Title</Dialog.Title>
<Dialog.Description className={styles.description}>Description text</Dialog.Description>
</Dialog.Content>
</Dialog.Root>
/* Dialog.module.css */
.trigger {
background-color: #0070f3;
color: white;
padding: 0.5rem 1rem;
border-radius: 4px;
border: none;
}
.content {
background: white;
border-radius: 8px;
padding: 1rem;
max-width: 400px;
box-shadow: 0 10px 25px rgba(0,0,0,0.15);
}
.title {
font-size: 1.25rem;
font-weight: bold;
margin-bottom: 0.5rem;
}
.description {
font-size: 1rem;
color: #555;
}
Такое разделение обеспечивает строгую компонентную структуру, где стили Dialog изолированы и не конфликтуют с другими частями интерфейса.
CSS Modules можно комбинировать с SCSS, что добавляет возможности переменных, миксинов и вложенности:
/* Button.module.scss */
$primary-color: #0070f3;
.button {
padding: 0.5rem 1rem;
border-radius: 4px;
border: none;
background-color: $primary-color;
color: white;
&:hover {
background-color: darken($primary-color, 10%);
}
}
Импорт в компонент остается прежним:
import styles from './Button.module.scss';
При работе с крупными проектами рекомендуется:
.module.css или
.module.scss.ComponentName_element или
componentName__element для удобства.globals.css для сброса стилей, сеток и общих
переменных.Такой подход обеспечивает модульность, предсказуемость и простоту масштабирования интерфейса.