Обзор раздела: Стили, доступность и производительность
В краткой версии учебника ты собрал стилизацию по верхам: написал несколько компонентов на Tailwind, добавил Dialog из Shadcn, прогнал Lighthouse и увидел три цифры — LCP, INP, CLS. Этого достаточно, чтобы сверстать страницу. Но в продакшене к тебе приходят с другими вопросами: почему CSS-бандл вырос с 8 до 40 КБ после подключения одной библиотеки? Почему дропдаун ломается при навигации с клавиатуры, хотя «всё по макету»? Почему страница с зелёным Lighthouse-рейтингом получает красный INP у реальных пользователей на Android в мобильной сети?
Этот раздел отвечает на все три вопроса. Мы разбираем не API фреймворков, а механику: как работает каскад и почему утилитарный CSS победил BEM, как устроен JIT-компилятор Tailwind и что он реально сканирует, как Radix реализует focus trap без единной строчки стилей, чем полевые метрики CrUX отличаются от лабораторного Lighthouse — и почему оптимизировать надо по первым, а дебажить по второму.
Карта раздела
Заголовок раздела «Карта раздела»Глава про утилитарный CSS как инженерную дисциплину. Разбираем, чем Tailwind решает «войны специфичности» эпохи BEM, как устроено content-сканирование и JIT-компиляция, когда использовать @apply, а когда он вреден, как выносить дизайн-токены в theme.extend и какие плагины реально нужны (typography, forms, container-queries). Отдельный блок — CSS-перфоманс: размер бандла, сложность селекторов, контainment и то, что на самом деле тормозит стилизацию в браузере. Базовый референс — документация Tailwind.
Две технологии, которые часто путают. Radix — это доступные нестилизованные примитивы: они знают про клавиатуру, фокус и ARIA, но не знают про цвета. Shadcn — это способ доставки кода компонентов в твой репозиторий через CLI, а не npm-пакет. Разбираем composition pattern с asChild, управление состоянием диалогов, cn()-хелпер, варианты через cva и то, как кастомизировать тему через CSS-переменные, не теряя обновлений.
Не весь код живёт в Tailwind-проектах: legacy на CSS Modules, сторонние виджеты, email-вёрстка. Глава про изоляцию классов через CSS Modules (composes, :global), пайплайн PostCSS (автопрефиксер, nesting) и современные возможности CSS: custom properties, селектор :has(), Container Queries, subgrid и @layer для явного управления каскадом.
Доступность — это не «добавить aria-label и забыть». Разбираем семантические лендмарки, навигацию с клавиатуры, focus-visible и focus-trap, первое правило ARIA, живые регионы для динамики, доступные формы и автоматизированное тестирование через axe-core. Отдельно — базовая работа со скринридерами NVDA и VoiceOver: что слушать, чтобы услышать то же, что слышит пользователь.
Финальная глава раздела — про метрики, которые видит и Google, и пользователь. LCP: что именно считается «самым большим элементом» и как поднять приоритет загрузки. INP: long tasks, разбиение вычислений, воркеры и почему transition-анимации не спасают от блокировки главного потока. CLS: размеры медиа, шрифты и динамический контент. Лабораторные метрики против полевых, код-сплиттинг, resource hints и бюджеты производительности, которые ломают CI при регрессии. Определения и пороги метрик — в обзоре Core Web Vitals на web.dev.
Как проходить раздел
Заголовок раздела «Как проходить раздел»Главы связаны, но не жёстко: Tailwind и Radix/Shadcn — одна связка (Shadcn-стек), CSS Modules и современный CSS — другая (для не-Tailwind проектов и legacy). Доступность и Web Vitals — сквозные темы, к ним возвращайся после каждой главы.
Порядок важен: сначала ты учишься стилизовать быстро и консистентно (Tailwind), потом — не ломать доступность готовыми компонентами (Radix/Shadcn), потом — понимать, что происходит под ними (современный CSS), и в конце — измерять результат в цифрах, а не на глаз (Web Vitals). Поехали.