← Назад к вопросам

Для чего нужны CSS module?

1.0 Junior🔥 121 комментариев
#HTML и CSS#Архитектура и паттерны

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Для чего нужны 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 нужны для:

  1. Изоляции стилей компонента от остального приложения
  2. Предотвращения конфликтов имен классов
  3. Автоматического генерирования уникальных имен
  4. Лучшей поддерживаемости больших приложений
  5. Компонентной архитектуры со строгой инкапсуляцией

Это особенно полезно в больших проектах, где много разработчиков работают одновременно и риск конфликтов высок.