Практические рекомендации по CSS
ОБЯЗАТЕЛЬНОДЛЯ НОВИЧКОВ
Разработчику
Аналитику
Тестировщику
Архитектору
Инженеру
Эта глава — шпаргалка по распространённым практикам. Здесь собраны типичные свойства и приёмы: что закладывать в проект по умолчанию, что лучше не применять без причины и где нужна осторожность. Таблицы охватывают и десктоп, и мобильные экраны.
Подробные объяснения — в тематических главах раздела; в конце таблиц указаны ссылки.
Как читать таблицы
| Колонка | Смысл |
|---|
| Использовать | Рекомендуемая база или современная замена устаревшему |
| Избегать | Частый источник багов, лишней сложности или плохого UX |
| Осторожно | Допустимо точечно; на мобильных или в проде — с проверкой |
Контекст важнее абсолютных запретов: таблица задаёт направление, а не заменяет макет и тесты на целевых устройствах.
Основа документа и сброс
| Тема | Использовать | Избегать | Осторожно | Подробнее |
|---|
| Модель коробки | box-sizing: border-box на *, *::before, *::after | content-box для всех блоков подряд | Смешение моделей в одном компоненте без документации | Блочная модель |
| Viewport (HTML) | <meta name="viewport" content="width=device-width, initial-scale=1"> | Страница без viewport на мобильных | user-scalable=no без веской причины (доступность) | Адаптивность |
| Единицы ширины | %, rem, em, max-width, min(), clamp() | Жёсткая ширина контента только в px | vw / vh для полной высоты/ширины блоков | Основные стили, Адаптивность |
| Изображения | max-width: 100%; height: auto | Картинки без ограничения ширины | object-fit без запасного соотношения | Адаптивность |
| Глобальный сброс | Небольшой reset или normalize + свои токены | Тяжёлый reset, ломающий формы и списки | Универсальный селектор * с десятками правил | Подключение CSS |
Макет и компоновка
| Тема | Использовать | Избегать | Осторожно | Подробнее |
|---|
| Сетка страницы | Flexbox (одна ось), Grid (две оси) | float для колонок и карточек | Таблицы (display: table) для вёрстки | Flex и Grid |
| Отступы между элементами | gap во Flex/Grid | Отрицательные margin как «костыль» сетки | margin на последнем ребёнке вместо gap | Flex и Grid |
| Центрирование | display: flex + justify-content / align-items, Grid place-items | Абсолютное позиционирование «на глаз» | position: absolute для всего макета | Основные стили |
| Порядок блоков | Порядок в HTML; order только для визуала | order, меняющий смысловой порядок для скринридеров | flex-direction: column-reverse без проверки a11y | Flex и Grid |
| Фиксированные панели | position: sticky для шапки при прокрутке | Много position: fixed слоёв | fixed без учёта safe-area на iPhone | Основные стили, Справочник |
| Компонент в контейнере | @container для карточек в sidebar | Только @media по ширине окна для внутренних блоков | @container без container-type | Адаптивность, Логические свойства |
| RTL и многоязычность | margin-inline, padding-inline, inset-inline | Только left / right в интерфейсах с RTL | Смешение физических и логических свойств в одном блоке | Логические свойства |
Размеры, viewport и адаптивность
| Тема | Использовать | Избегать | Осторожно | Подробнее |
|---|
| Подход к медиазапросам | Mobile-first: база для узкого экрана, @media (min-width: …) | Desktop-first с каскадом max-width в новых проектах | max-width в запросах при уже выбранном mobile-first | Адаптивность, Подключение |
| Ширина контейнера | width: 100% + max-width + margin: 0 auto | width: 100vw (скролл из‑за полос прокрутки) | «Full-bleed» через 100vw без overflow-x: hidden | Адаптивность |
| Высота экрана | min-height: 100dvh, Flex/Grid stretch | height: 100vh на мобильных (адресная строка) | 100svh / 100lvh без понимания разницы единиц | Адаптивность, Справочник |
| Текстовые колонки | max-width: 65ch–75ch, line-height: 1.5–1.7 | Строки на всю ширину 4K-монитора | ch в компонентах с нестандартным шрифтом | Адаптивность |
| Типографика по экрану | clamp(1rem, 2.5vw, 1.25rem) для заголовков | Отдельный CSS-файл на каждый брейкпоинт для каждого font-size | Слишком мелкий текст из‑за clamp на 320px | Адаптивность |
| Вырез и «чёлка» | padding: env(safe-area-inset-*) у fixed/sticky | Контент под системными панелями | constant() без fallback для старых iOS | Справочник |
Цвет, тема и контраст
| Тема | Использовать | Избегать | Осторожно | Подробнее |
|---|
| Палитра | CSS-переменные (--color-text, --space-md) | Десятки «магических» hex в селекторах | !important для перебивки цветов | Переменные, Подключение |
| Тёмная тема | @media (prefers-color-scheme: dark) + переменные | Только ручной переключатель без учёта ОС | Жёсткие цвета при forced-colors: active | Доступность |
| Контраст текста | Соотношение ≥ 4.5:1 для основного текста (WCAG) | Светло-серый текст на белом (opacity: 0.5) | Декоративный текст без требования чтения | Доступность |
| Прозрачность | rgba() / color-mix() осознанно | Единственный способ «осветлить» — opacity на родителе | Полупрозрачные слои поверх busy-фона | Основные стили |
Интерактивность, фокус и сенсор
| Тема | Использовать | Избегать | Осторожно | Подробнее |
|---|
| Фокус | :focus-visible + видимый outline или box-shadow | outline: none без замены | Стили :focus как у :hover на каждом клике | Псевдоклассы, Доступность |
| Наведение | :hover для десктопа; дублировать важное состояние иначе | Только :hover для критичной информации | Сложные анимации на :hover на touch-экранах | Псевдоклассы |
| Зоны нажатия | min-height / min-width ≥ 44–48px, padding у ссылок и кнопок | Кликабельная область размером с иконку 16px | @media (pointer: coarse) для увеличения целей | Адаптивность, Доступность |
| Жесты | touch-action: manipulation на кнопках/слайдерах | touch-action: none на всей странице | Отключение pull-to-refresh без альтернативы | Справочник |
| Прокрутка в модалках | overscroll-behavior: contain | Цепочка скролла «на фон» под оверлеем | Вложенные scroll без фиксированной высины | Справочник |
| Скрытый текст | Класс .sr-only (визуально скрыт, в DOM есть) | display: none для подписей, нужных скринридеру | visibility: hidden для интерактива | Доступность |
Анимации и производительность
| Тема | Использовать | Избегать | Осторожно | Подробнее |
|---|
| Плавные эффекты | transition на opacity, transform, color | Анимация width, height, top, left, margin | will-change на многих элементах сразу | Анимации, Справочник |
| Движение | @keyframes + transform | Параллакс и автопрокрутка без паузы | Бесконечные тяжёлые анимации фона | Анимации |
| Настройки пользователя | @media (prefers-reduced-motion: reduce) | Игнорирование «уменьшить движение» | Отключение всех transition глобально | Доступность |
| Размытие и фильтры | Лёгкие тени, редкий filter | backdrop-filter на больших областях | filter / backdrop-filter на слабых мобильных | Справочник |
| Длинные списки | content-visibility: auto | Тысячи DOM-узлов без виртуализации | contain без замера в DevTools | Справочник |
Селектор :has() | Узкий контекст (.card:has(.badge)) | body:has(...) на больших страницах | Сложные цепочки в критичном пути рендера | Селекторы :has |
Организация CSS и каскад
| Тема | Использовать | Избегать | Осторожно | Подробнее |
|---|
| Именование | BEM или согласованная методология в команде | Глубокая вложенность селекторов (.header .nav ul li a) | ID в стилях компонентов | Подключение |
| Специфичность | Классы; :where() для сброса веса | !important в основной кодовой базе | !important в утилитах дизайн-системы | Подключение, Каскад |
| Слои | @layer base, components, utilities | Хаотичный порядок файлов без правил | Слишком много слоёв без схемы | Каскадные слои |
| Подключение | Внешний файл + критичный CSS при необходимости | Сотни <link> без сборки | Inline-стили на каждом элементе | Подключение |
| Дублирование | Переменные, миксины (препроцессор) или @layer | Копипаст одних и тех же блоков | Препроцессор там, где хватит нативных переменных | Переменные |
Устаревшее и замены
| Было (устарело) | Современная замена | Комментарий |
|---|
Вёрстка колонок на float | Flexbox / Grid | float — для обтекания текстом вокруг картинки |
Фиксированные брейкпоинты только в px | rem / em в запросах, container queries | Согласованность с масштабом шрифта |
@import в середине файла | <link> или сборщик (Vite, webpack) | @import блокирует параллельную загрузку |
Префиксы вручную (-webkit-) | Autoprefixer по browserslist | Синтаксис |
!important для перебития фреймворка | Повысить специфичность, @layer, локальный scope | Временный костыль — пометить в коде |
Desktop-first (max-width каскадом) | Mobile-first (min-width) | В легаси — рефакторить постепенно |
Быстрый чек перед публикацией
| Проверка | Действие |
|---|
| Viewport | Метатег в <head> |
| Горизонтальный скролл | DevTools → 320px; нет 100vw и «вылезших» margin |
| Касания | Кнопки и ссылки ≥ 44px по высоте/ширине зоны |
| Фокус | Tab-навигация: видно, куда попал фокус |
| Движение | Есть ветка prefers-reduced-motion |
| Контраст | Основной текст читаем на фоне |
| Реальное устройство | Хотя бы один проход на телефоне, не только эмулятор |
| Производительность | Тяжёлые эффекты выключены или упрощены на мобильных |
Расширенный чек-лист вопросов — в самопроверке.
Куда углубиться
В подборках
Статья входит в тематические маршруты из меню Подборки и блока «С чего начать?» на главной. Соседние шаги того же маршрута:
Веб-разработка — HTML — о разделе, JavaScript — о разделе, CSS — о разделе, Адаптивный и отзывчивый дизайн, Доступность и пользовательские настройки в CSS.