Стили
Базовая стилевая инфраструктура: токены, breakpoints и точка сборки глобальных стилей в src/shared/styles/.
CSS-процессор — отдельный шаг (PostCSS). Правила написания CSS в компонентах — Стили: использование.
Требования
- Структура
src/соответствует SLM (Структура проекта). Глобальные стили живут вsrc/shared/styles/, не вsrc/app/. - В проекте нет
globals.cssс кастомным содержимым и не установленtailwindcss.
Файлы
Состав глобальных стилей — три файла:
| Файл | Роль |
|---|---|
variables.css | Токены проекта (цвета, отступы, радиусы) |
media.css | Custom 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. Создать файлы
mkdir -p src/shared/styles
touch src/shared/styles/variables.css src/shared/styles/media.css src/shared/styles/global.css2. Заполнить media.css
Файл src/shared/styles/media.css. Стандартный набор брейкпоинтов проекта; редактировать только при согласованном изменении шкалы.
Единица — rem (реагирует на корневой font-size). Перевод исходит из дефолтного html { font-size: 16px }, т.е. 1rem = 16px.
/* 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), исключение--xs—max-width(блок «строго меньше--sm»); - значения высоты —
min-height.
3. Заполнить variables.css
Файл src/shared/styles/variables.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 остальных глобалов относительным путём.
/* 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 приложения:
// 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-спрайты — стили иконок отдельно от глобальных.