CSS модули — это современный способ организации стилей в приложениях на React, обеспечивающий изоляцию стилей и предотвращение конфликтов имен классов. В сочетании с React Aria, библиотекой для создания доступных пользовательских интерфейсов, CSS модули позволяют создавать компоненты, полностью соответствующие стандартам доступности, с аккуратной структурой стилей.
В React проекте, созданном через Create React App или аналогичный билд-инструмент, CSS модули подключаются следующим образом:
import styles from './Button.module.css';
function Button({ children }) {
return <button className={styles.button}>{children}</button>;
}
Особенности подключения:
.module.css.clsx.import clsx from 'clsx';
import styles from './Button.module.css';
function Button({ primary }) {
return (
<button className={clsx(styles.button, primary && styles.primary)}>
Кнопка
</button>
);
}
React Aria предоставляет набор хуков и компонентов для управления состоянием и поведением элементов с поддержкой доступности (ARIA). CSS модули позволяют стилизовать эти элементы без риска переписывания глобальных стилей.
Пример кнопки с использованием хуков React Aria и CSS модулей:
import { useButton } from '@react-aria/button';
import { useRef } from 'react';
import styles from './Button.module.css';
function AriaButton({ children, onPress }) {
const ref = useRef();
const { buttonProps } = useButton({ onPress }, ref);
return (
<button {...buttonProps} ref={ref} className={styles.button}>
{children}
</button>
);
}
Ключевые моменты:
useButton добавляет ARIA-атрибуты и обработчики
событий.React Aria часто требует управления состояниями компонентов: активный, выбранный, фокусированный. CSS модули отлично сочетаются с этим через динамическое присвоение классов:
import { useToggleButton } from '@react-aria/button';
import { useRef, useState } from 'react';
import styles from './ToggleButton.module.css';
import clsx from 'clsx';
function ToggleButton({ children }) {
const ref = useRef();
const [isSelected, setSelected] = useState(false);
const { buttonProps } = useToggleButton(
{
isSelected,
onChange: setSelected
},
ref
);
return (
<button
{...buttonProps}
ref={ref}
className={clsx(styles.button, isSelected && styles.selected)}
>
{children}
</button>
);
}
Особенности:
clsx упрощает условное применение стилей.При работе с компонентами, содержащими несколько элементов (например, меню, модальные окна, вкладки), CSS модули позволяют структурировать стили по иерархии, избегая конфликтов:
/* Menu.module.css */
.menu {
background: white;
border: 1px solid #ccc;
}
.menuItem {
padding: 8px 16px;
}
.menuItemSelected {
background: #0078d4;
color: white;
}
import { useMenu, useMenuItem } from '@react-aria/menu';
import { useRef } from 'react';
import styles from './Menu.module.css';
import clsx from 'clsx';
function Menu({ items }) {
const ref = useRef();
const { menuProps } = useMenu({}, ref);
return (
<ul {...menuProps} ref={ref} className={styles.menu}>
{items.map((item) => (
<MenuItem key={item.key} item={item} />
))}
</ul>
);
}
function MenuItem({ item }) {
const ref = useRef();
const { menuItemProps, isSelected } = useMenuItem(
{ key: item.key },
ref
);
return (
<li
{...menuItemProps}
ref={ref}
className={clsx(styles.menuItem, isSelected && styles.menuItemSelected)}
>
{item.name}
</li>
);
}
Преимущества такого подхода:
CSS модули можно сочетать с переменными CSS для создания темной и светлой темы:
/* Button.module.css */
:root {
--button-bg: #f0f0f0;
--button-color: #000;
}
.button {
background-color: var(--button-bg);
color: var(--button-color);
border: none;
padding: 10px 16px;
cursor: pointer;
transition: background 0.3s;
}
.button:hover {
background-color: #e0e0e0;
}
Для темизации можно динамически изменять корневые переменные через JavaScript или React Context, при этом стили компонентов остаются полностью локализованными.
CSS модули не мешают использовать утилитарные библиотеки вроде Tailwind. Можно применять Tailwind классы вместе с локальными:
<button className={`${styles.button} bg-blue-500 hover:bg-blue-600`}>
Комбинированная кнопка
</button>
Такой подход позволяет гибко управлять дизайном, оставляя CSS модули для локальных и уникальных стилей, а Tailwind — для быстрых утилитарных правок.
Использование CSS модулей в сочетании с React Aria обеспечивает изолированную, масштабируемую систему стилей, которая полностью совместима с ARIA-стандартами доступности. Комбинация локальных классов, динамических состояний и переменных CSS делает разработку компонентов более управляемой и безопасной для больших приложений.
CSS модули позволяют создавать чистую архитектуру UI без глобальных конфликтов, а React Aria обеспечивает функциональность и доступность, создавая единый подход к построению сложных и доступных интерфейсов.