Практические рекомендации по CSS
Эта глава — шпаргалка по распространённым практикам. Здесь собраны типичные свойства и приёмы: что закладывать в проект по умолчанию, что лучше не применять без причины и где нужна осторожность. Таблицы охватывают и десктоп, и мобильные экраны.
Подробные объяснения — в тематических главах раздела; в конце таблиц указаны ссылки.
Как читать таблицы
| Колонка | Смысл |
|---|---|
| Использовать | Рекомендуемая база или современная замена устаревшему |
| Избегать | Частый источник багов, лишней сложности или плохого UX |
| Осторожно | Допустимо точечно; на мобильных или в проде — с проверкой |
Контекст важнее абсолютных запретов: таблица задаёт направление, а не заменяет макет и тесты на целевых устройствах.
Частые паттерны вёрстки
Ниже — пять заготовок, которые повторяются от лендинга до личного кабинета. Теория по осям Flex и трекам Grid — в Flexbox и CSS Grid. Полные страницы с комментариями к каждой строке — HTML + CSS, готовые макеты.
Центрирование по горизонтали и вертикали
Flexbox выстраивает дочерние элементы вдоль главной оси (flex-direction) и поперечной. Свойства justify-content и align-items выравнивают содержимое по центру контейнера.
.center {
display: flex;
justify-content: center; /* по главной оси */
align-items: center; /* по поперечной */
min-height: 100dvh;
}
100dvh— динамическая высота viewport: учитывает панели браузера на телефоне (подробнее в справочнике);- тот же приём на Grid:
display: grid; place-items: center;(place-items— сокращение дляalign-items+justify-items).
Интерактивный разбор блочной модели — на странице о разделе CSS. Готовый макет с комментариями — лаборатория 110.
Подвал внизу короткой страницы
Если контента мало, footer «висит» посередине экрана. Решение — колонка Flex на body, а main растягивается и занимает свободное место.
body {
display: flex;
flex-direction: column;
min-height: 100dvh;
}
main {
flex: 1; /* flex-grow: 1 — main тянется и отталкивает footer к низу */
}
Семантическая разметка header / main / footer — HTML-страницы целиком.
Каркас страницы на CSS Grid
grid-template-areas задаёт именованные зоны. Каждому блоку в CSS пишут grid-area с тем же именем, что в сетке.
.page {
display: grid;
grid-template-areas:
"header header"
"nav content"
"footer footer";
grid-template-columns: 200px 1fr;
grid-template-rows: auto 1fr auto;
min-height: 100dvh;
}
.page__header { grid-area: header; }
.page__nav { grid-area: nav; }
.page__main { grid-area: content; }
.page__footer { grid-area: footer; }
На узком экране зоны перестраивают в одну колонку через @media — адаптивный дизайн. Имена классов здесь в духе BEM — §111.
Адаптивная сетка карточек
repeat(auto-fill, minmax(...)) сам подбирает число колонок по ширине родителя:
auto-fill— создать столько колонок, сколько влезает;minmax(min(100%, 16rem), 1fr)— колонка не уже 16rem и не шире контейнера;1fr— равномерно делит оставшееся место.
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(100%, 16rem), 1fr));
gap: 1.25rem;
}
Готовая галерея с разбором — макеты, лаборатория 110. Функция minmax() — Функции в CSS.
Равная ширина колонок во Flex
flex: 1 на дочерних элементах делит строку поровну. min-width: 0 снимает ограничение по умолчанию (min-width: auto), и длинный текст не раздувает колонку.
.row {
display: flex;
gap: 1rem;
}
.row__col {
flex: 1;
min-width: 0;
}
gap задаёт расстояние между элементами без отрицательных margin — см. таблицу «Макет» выше и §2.
Основа документа и сброс
| Тема | Использовать | Избегать | Осторожно | Подробнее |
|---|---|---|---|---|
| Модель коробки | 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 для всего макета | Основные стили — position |
| Порядок блоков | Порядок в HTML; order только для визуала | order, меняющий смысловой порядок для скринридеров | flex-direction: column-reverse без проверки a11y | Flex и Grid |
| Фиксированные панели | position: sticky для шапки при прокрутке | Много position: fixed слоёв | fixed без учёта safe-area на iPhone | position — sticky и fixed, Справочник |
| Компонент в контейнере | @container для карточек в sidebar | Только @media по ширине окна для внутренних блоков | @container без container-type | Адаптивность, Логические свойства |
| RTL и многоязычность | margin-inline, padding-inline, inset-inline | Только left / right в интерфейсах с RTL | Смешение физических и логических свойств в одном блоке | Логические свойства |
| Учебный проект "с нуля" | Копировать готовый .html из лаборатории, менять по одному свойству | Сразу Bootstrap/Tailwind без понимания Flex/Grid | Смешивать фреймворк и учебный чистый CSS в одной работе | Сначала HTML-страницы целиком, затем HTML + CSS — готовые макеты; после Flex/Grid — Tailwind — готовые блоки |
Размеры, 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 | Адаптивность |
| Ширина по содержимому | width: fit-content + max-width + margin-inline: auto для компактных блоков | display: inline-block ради "сжатия", когда нужен блочный элемент | fit-content без лимита ширины на мобильных | Основные стили, Справочник |
| Высота экрана | 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 для перебивки цветов | Переменные, Подключение |
| Оттенки и hover | `color-mix(in oklch, var(--brand) N%, white | black)` | Отдельный hex на каждый шаг палитры в Sass | Смешение в srgb, если нужна перцептивная равномерность |
| Тёмная тема | @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 |
| Контраст | Основной текст читаем на фоне |
| Реальное устройство | Хотя бы один проход на телефоне, не только эмулятор |
| Производительность | Тяжёлые эффекты выключены или упрощены на мобильных |
Расширенный чек-лист вопросов — в самопроверке.
Куда углубиться
| Тема | Глава |
|---|---|
| Пошаговая адаптивность | Адаптивный и отзывчивый дизайн |
Доступность и prefers-* | Доступность и пользовательские настройки |
| Все свойства по алфавиту | Справочник по CSS |
| Частые паттерны вёрстки | § выше |
| Типовые UI-паттерны | Типовые элементы интерфейса |
| Каталог UI (Uiverse / Galaxy, MIT) | UI-паттерны из Uiverse |
| Готовые страницы с разбором | HTML-страницы целиком, HTML + CSS — готовые макеты, Tailwind — готовые блоки |
| Готовые анимации с разбором | CSS-анимации — готовые эффекты |
| Итоги раздела | Итоги |
В подборках
Статья входит в тематические подборки и блок "С чего начать?" на главной. Соседние шаги того же маршрута:
Веб-разработка — HTML — о разделе, JavaScript — о разделе, CSS — о разделе, Адаптивный и отзывчивый дизайн, Доступность и пользовательские настройки в CSS.