--- title: Настройка стилей description: "Подготовка стилевой основы проекта: токены, медиа-запросы, глобальные стили." keywords: [variables.css, media.css, global.css, shared/styles, токены, переменные, custom-media, breakpoints, подключение стилей, базовые стили, инициализация] --- # Настройка стилей Подготовка стилевой основы проекта: токены, медиа-запросы, глобальные стили. ## Требования - Установлен PostCSS или любой другой pre/post-процессор с поддержкой `@custom-media`. ## Файлы Состав глобальных стилей — три файла: | Файл | Роль | |------|------| | `variables.css` | Токены проекта (цвета, отступы, радиусы) | | `media.css` | Custom media queries (брейкпоинты по ширине и высоте) | | `global.css` | Точка сборки глобальных стилей: через `@import` тянет все остальные глобалы, импортируется в приложение один раз | Правила подключения: - В приложение импортируется **только** `global.css`. - `variables.css` и будущие глобальные файлы (резеты, темы, типографика) подключаются в `global.css` через `@import`. - `media.css` **не импортируется** — ни в `global.css`, ни в компоненты, ни в точку инициализации. Его читает CSS-процессор на этапе сборки (см. [PostCSS](../postcss.md)). ## Корневой `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), исключение `--xs` — `max-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 ( {children} ) } ``` `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](../postcss.md) — подключить процессор, чтобы заработали `@media (--md)` и вложенность. - [Использование стилей](./styles-usage.md) — правила написания CSS в компонентах. - [SVG-спрайты](../svg-sprites/svg-sprites-setup.md) — стили иконок отдельно от глобальных.