Skip to content

Стили

Базовая стилевая инфраструктура: токены, breakpoints и точка сборки глобальных стилей в src/shared/styles/.

CSS-процессор — отдельный шаг (PostCSS). Правила написания CSS в компонентах — Стили: использование.

Требования

  • Структура src/ соответствует SLM (Структура проекта). Глобальные стили живут в src/shared/styles/, не в src/app/.
  • В проекте нет globals.css с кастомным содержимым и не установлен tailwindcss.

Файлы

Состав глобальных стилей — три файла:

ФайлРоль
variables.cssТокены проекта (цвета, отступы, радиусы)
media.cssCustom media queries (брейкпоинты по ширине и высоте)
global.cssТочка сборки глобальных стилей: через @import тянет все остальные глобалы, импортируется в приложение один раз

Правила подключения:

  • В приложение импортируется только global.css.
  • variables.css и будущие глобальные файлы (резеты, темы, типографика) подключаются в global.css через @import.
  • media.css не импортируется — ни в global.css, ни в компоненты, ни в точку инициализации. Его читает CSS-процессор на этапе сборки (см. PostCSS).

Корневой font-size

Базовая единица rem в проекте привязана к 16px: корневой font-size не переопределяется. html { font-size: ... } писать запрещено — пользовательская настройка размера шрифта в браузере должна работать (a11y). Все rem-значения в media.css и других стилях трактуются как 1rem = 16px по умолчанию.

Reset браузерных дефолтов (box-sizing, сброс margin, типографика) каноном не задаётся — каждый проект решает сам. Если заводится — подключается через global.css.

Установка

1. Создать файлы

bash
mkdir -p src/shared/styles
touch src/shared/styles/variables.css src/shared/styles/media.css src/shared/styles/global.css

2. Заполнить media.css

Файл src/shared/styles/media.css. Стандартный набор брейкпоинтов проекта; редактировать только при согласованном изменении шкалы.

Единица — rem (реагирует на корневой font-size). Перевод исходит из дефолтного html { font-size: 16px }, т.е. 1rem = 16px.

css
/* src/shared/styles/media.css */

/* Ширина — Mobile First (min-width), кроме --xs (max-width) */
@custom-media --xs  (max-width: 35.9375rem);  /* 575px  — до sm */
@custom-media --sm  (min-width: 36rem);       /* 576px  — телефон альбом / малый планшет */
@custom-media --md  (min-width: 48rem);       /* 768px  — планшет */
@custom-media --lg  (min-width: 62rem);       /* 992px  — малый десктоп */
@custom-media --xl  (min-width: 75rem);       /* 1200px — десктоп */
@custom-media --2xl (min-width: 88rem);       /* 1408px — широкий десктоп */
@custom-media --3xl (min-width: 120rem);      /* 1920px — full HD+ */

/* Высота — min-height */
@custom-media --h-xs  (min-height: 41.6875rem); /* 667px  — iPhone SE портрет */
@custom-media --h-sm  (min-height: 43.875rem);  /* 702px */
@custom-media --h-md  (min-height: 50.625rem);  /* 810px  — iPad портрет */
@custom-media --h-lg  (min-height: 56.25rem);   /* 900px */
@custom-media --h-xl  (min-height: 62.5rem);    /* 1000px */
@custom-media --h-2xl (min-height: 68.75rem);   /* 1100px */
@custom-media --h-3xl (min-height: 75rem);      /* 1200px */

Правила:

  • только @custom-media на верхнем уровне;
  • имена короткие, по шкале (--xs--3xl); высотные — с префиксом --h-;
  • единица — rem, не em/px; пиксельное значение указывается комментарием;
  • значения ширины — min-width (Mobile First), исключение --xsmax-width (блок «строго меньше --sm»);
  • значения высоты — min-height.

3. Заполнить variables.css

Файл src/shared/styles/variables.css. Набор токенов под проект расширяется по мере роста дизайн-системы.

css
/* src/shared/styles/variables.css */
:root {
  /* Цвета */
  --color-primary: #3b82f6;
  --color-bg: #ffffff;
  --color-bg-hover: #f5f5f5;
  --color-text: #1a1a1a;

  /* Отступы */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;

  /* Скругления */
  --radius-1: 4px;
  --radius-2: 8px;
}

Правила:

  • все токены определяются в :root — без вложенных селекторов;
  • именование — kebab-case по ролям: --color-*, --space-*, --radius-*;
  • px — основная единица для пространственных токенов;
  • темы накладываются поверх через [data-theme="..."] { ... } — в отдельном файле темы или здесь же.

variables.css напрямую в приложение не импортируется — только через global.css.

4. Заполнить global.css

Файл src/shared/styles/global.css. Единственный глобальный файл, импортируемый в точку инициализации приложения. Внутри — @import остальных глобалов относительным путём.

css
/* src/shared/styles/global.css */
@import './variables.css';

/* Сюда же подключаются будущие глобалы через @import:
 * @import './reset.css';
 * @import './typography.css';
 * @import './themes.css';
 * media.css НЕ импортируется — он работает через PostCSS.
 */

Правила:

  • пути в @import — относительные (./variables.css), не через алиасы; нативный CSS @import не понимает tsconfig-paths;
  • media.css в global.css не импортируется;
  • собственные глобальные правила (html { ... }, body { ... }) писать не здесь, а в отдельных файлах рядом (reset.css, typography.css) и подключать через @import. global.css — только точка сборки;
  • порядок @import определяет порядок каскада: токены первыми, дальше резеты / темы / типографика.

5. Подключить global.css в layout

Импорт делается один раз — в корневом layout приложения:

tsx
// src/app/layout.tsx
import 'shared/styles/global.css'

import type { Metadata } from 'next'

export const metadata: Metadata = {
  title: 'App',
  description: '',
}

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="ru">
      <body>{children}</body>
    </html>
  )
}

variables.css и media.css в layout не импортируются напрямую — только через global.css (variables) или через PostCSS на сборке (media).

Проверка установки

  • В src/shared/styles/ присутствуют три файла: variables.css, media.css, global.css. В src/app/ папки styles/ нет.
  • В src/app/layout.tsx есть import 'shared/styles/global.css'. Импортов variables.css и media.css там нет.
  • В проекте не появились PostCSS-пакеты и postcss.config.* — этот раздел их не ставит.
  • npm run build завершается успешно.

Дальше

  • PostCSS — подключить процессор, чтобы заработали @media (--md) и вложенность.
  • Стили: использование — правила написания CSS в компонентах.
  • SVG-спрайты — стили иконок отдельно от глобальных.