/
Теги: программные средства программирование
ISBN: 978-5-17-174758-9
Текст
АЛЕКСАНДР КЛИМОВИЧ
МАГИЯ CSS
САМОЕ ГЛАВНОЕ
В КРАТКОМ
ИЗЛОЖЕНИИ
САМОЕ ГЛАВНОЕ
В КРАТКОМ
ИЗЛОЖЕНИИ
МОСКВА
ИЗДАТЕЛЬСТВО ACT
УДК 004.4
ББК 32.973-018.1
К49
Климович, Александр Дмитриевич.
К49 Магия CSS — самое главное в кратком изложении / А. Д. Климович. —
Москва : Издательство ACT, 2026. — 144 с.: ил. — (Учимся программировать).
ISBN 978-5-17-174758-9.
Перед вами практическое руководство по современным техникам веб-сти-
лизации, котором язык CSS раскрывается как инструмент точной настройки
визуальной среды — от фундаментальных принципов до самых продвинутых
возможностей.
Книга охватывает весь путь освоения CSS: от блочной модели — основы ком-
поновки элементов на странице — до сложных анимаций, эффектов и приемов,
позволяющих создавать выразительные и в то же время производительные ин-
терфейсы. В отдельных главах рассматриваются современные подходы к сеткам
и табличной верстке, работа с цветом, типографикой и переходами Особое вни-
мание уделено архитектурным аспектам управлению специфичностью и слоя ми,
поддержке адаптивности с помощью контейнерных запросов, применению суб-
гридон и логических свойств Все это сопровождается практическими примерами
и стратегиями оптимизации, что делает книгу полезной как для проектирования
модульных компонентов, так и для масштабных систем
«Магия CSS» предназначена для широкого круга специалистов — и для тех, кто
только начинает знакомство с i-еб-стилизацией, и для опытных разработчиков,
стремящихся углубить свои знания и использовать CSS на профессиональном
уровне.
УДК С: 04.4
ББК 32.973-018.1
ISBN 978-5-17-174758-9
© Оформление. ООО «Интеджер», 2025
© ООО «Издательство ACT», 2026
Содержание
Введение....................................................................9
Глава 1. Блочная модель CSS: основа визуального отображения................11
Теория и терминология...................................................11
Исторический контекст...................................................12
Быстрый пример...........................................................12
Основные техники и паттерны.............................................13
Универсальное применение burder-box..................................13
Гибкие формы ввода...................................................14
Компонентная система с предсказуемыми размерами......................15
Современные CSS-возможности.............................................16
Логические свойства и блочная модель.................................16
Контейнерные запросы (Container Queries) и блочная модель............17
Cascade Layers и управление специфичностью...........................17
Современные CSS-функции для размеров.................................18
Селекторы :hasQ и условная стилизация................................18
Производительность......................................................19
Оптимизация перерасчета макета.......................................19
Использование CSS Containment........................................19
Стратегии для will-change............................................19
Доступность (А11у)......................................................20
Адаптивная типографика и блочная модель............................ 20
Видимые области фокуса...............................................21
Поддержка направления текста.........................................21
Отладка.................................................................22
Инструменты разработчика........................................... 22
Методы диагностики размеров..........................................22
Диагностика специфичности и каскада................................. 23
Частые ошибки и антипатгерны............................................23
Специфичность и hmportant............................................23
Смешивание единиц измерения без border-box...........................24
Неправильное использование margin для внутренних отступов............24
Z-index без контекста наложения......................................25
Архитектура и масштабирование ..........................................26
Совместимость браузеров.................................................29
Стратегии прогрессивною улучшения..................................... 29
Практические упражнения.................................................30
Упражнение 1. Адаптивная кар] очная система..........................30
Упражнение 2. Универсальная система форм.............................31
Упражнение 3. Производительный макет списка.............................31
Заключение.................................................................32
Углубленное чтение......................................................32
Глава 2. Придвинутые техники компоновки.......................................34
Теория и терминология......................................................34
Layout vs Paint vs Composite...............................................35
Быстрый пример..........................................................35
Основные техники и паттерны..................................... .......36
Типы отображения (Display Types)........................................36
Современные возможности CSS.............................................. 38
Cascade Layers (Экспериментальная функция)..............................38
Container Queries (Экспериментальная функция)...........................38
CSS Subgrid (Экспериментальная функция).................................38
Селекторы :has(), :is(), :where().......................................39
CSS Nesting (Экспериментальная функция).................................39
Логические свойства.....................................................39
Производительность.........................................................40
Стоимость селекторов....................................................40
Оптимизация Reilow/Repaint/Composite....................................40
Использование wiU-change................................................40
Доступность................................................................41
Стили фокуса............................................................41
Контрастность и пользовательские предпочтения...........................41
Логические свойства для RTI.............................................42
Отладка....................................................................42
Техники Dev Tools.......................................................42
Диагностика специфичности...............................................43
Типичные ошибки и антипаттерны............................................ 43
Проблемы специфичности..................................................43
Проблемы z-index...................................................... 44
Схлопывание margin......................................................44
Архитектура и масштабирование..............................................45
Методологии.............................................................45
Cascade Layers для архитектуры..........................................45
Система дизайнлокенов...................................................46
Совместимость браузеров....................................................47
Стратегии fallback.........................................................47
Практические упражнения....................................................48
Упражнение 1. Адаптивная карточная сетка................................48
Упражнение 2. Сложная компоновка с Subgrid..............................48
Упражнение 3. Оптимизированная анимация.................................48
Заключение.................................................................49
Углубленное чтение......................................................49
Глава 3. Мастерство табличной верстки и продвинутые техники...................51
Теория и терминология......................................................51
Быстрый пример.. ........................................................ .52
Основные техники и паттерны................................................53
Контроль пропорций с table-layout: auto.................................53
Точное позиционирование с table-layout; fixed...........................55
Гибридный подход с Container Queries....................................56
Современные возможности CSS............................................ 58
Каскадные слои для организации табличных стилей........................ 58
Селектор :has() для контекстной стилизации......-.... ................ 59
Логические свойства дтя интернационализации.............................59
Современные функции для динамических размеров....................... 60
Производительность.................................................... ..61
Стоимость селекторов в табличном контексте..............................61
Создание слоев компоновки для анимаций................................ 62
Оптимизация перерисовки.................................................62
Доступность (ally).........................................................62
Семантическая разметка и навигация.................................. 62
Стили фикуса и навигации................................................63
Адаптивная типографика..................................................64
Отладка....................................................................65
Техники визуальной отладки............................................ 65
Диагностика специфичности и каскада.....................................65
Методология бинарного поиска проблем.................................. 66
Распространенные ошибки и антипаттерны............................. 66
Специфичность и злоупотребление 'important..............................66
Утечки z-index и нежелательные контексты наложения......................67
Схлопывание margin и негативные отступы как костыли.................... 68
Переиспользование табличных хаков при доступности современных решений...68
Архитектура и масштабирование.......................................... 69
Методолоши организации табличных стилей.................................69
Design tokens и кастомные свойства для тематизации......................71
Паттерны композиции и переиспользования................................ 72
Совместимость браузеров.................................................. 73
Стратегии fallback и прогрессивного улучшения..............................74
Практические упражнения................................................... 75
Упражнение 1. Адаптивная таблица данных (средняя сложность).............75
Упражнение 2. Сложная финансовая таблица (высокая сложность)............75
Упражнение 3 Табличный дашборд (высокая сложность)......................76
Заключение............................................................... 77
Углубленное чтение......................................................78
Глава 4. Цвет и современные техники стилизации................................79
Цветовые пространства и рендеринг..........................................79
Этапы рендеринга цвета.............................................. 79
Быстрый пример........................................................... 79
Основные техники и паттерны................................................80
Управление прозрачностью без цветовых конфликтов.........................80
Семантическая система цветов............................................81
Контрастные пары и доступность..........................................82
Современные возможности CSS................................................83
Каскадные слои для цветовых систем......................................83
Контейнерные запросы для адаптивных цветовых схем......................84
Новые цветовые функции и пространства..................................85
Логические свойства для интернационализации............................86
Производительность........................................................86
Оптимизация селекторов и инвалидация...................................86
GPU-композит инг и стекинг.................. -....................... 87
Оптимизация градиентов и фильтров......................................88
Доступность...............................................................89
Контраст и цветовые предпочтения пользователя..........................89
Цветонезависимая индикация.............................................90
Отладка................................................................. 91
DevTools и инструменты диагностики.....................................91
Диагностика проблем специфичности......................................92
Распространенные ошибки и антипаттерны....................................93
1 Троблемы специфичности...............................................93
Злоупотребление iimponant............................................. 93
Архит ектура и масштабирование............................................94
Организация цветовых токенов...........................................94
Темизация и области видимости..........................................95
Интеграция с методологиями CSS........................................ 96
Совместимость браузеров...................................................97
Стратегии прогрессивного улучшения........................................98
Практические упражнения...................................................98
Упражнение 1. Адаптивная цветовая система..............................98
Упражнение 2. Система статутных индикаторов............................99
Упражнение 3. Производительная анимация цветов.........................99
Заключение................................................................ 100
Углубленное чтение....................................................100
Глава 5. CSS-типографика: продвинутые техники и современные возможности.....102
Теория и терминология....................................................102
Этапы рендеринга типографики.................................. 102
Быстрый пример........................................................... 103
Основные техники и паттерны.............................................. 104
Адаптивное масштабирование типографики................................ 104
Оптические корректировки межбуквенных интервалов......................105
Контрастная типографическая иерархия..................................105
Современные возможности CSS..............................................106
Каскадные слои для типографических систем.............................106
Контейнерные запросы для адаптивной типографики.......................107
Продвинутые селекторы и состояния................................... 107
Новые единицы измерения области просмотра.............................108
Производительность.......................................................109
Оптимизация селекторов.................................................109
Управление перерисовками..............................................109
Оптимизация загрузки шрифтов....... ............................. 110
Доступность..............................................................110
Фокусные состояния....................................................110
Адаптивная типографика для различных режимов письма.....................110
Отладка....................................................................111
Визуализация типографических метрик.....................................111
Диагностика каскада и специфичности.....................................111
Распространенные ошибки и антипаттерны.....................................112
Злоупотребление отрицательными отступами................................112
Система дизайн-токенов..................................................113
Модульная архитектура (ВЕМ + современный CSS)...........................113
Совместимость браузеров....................................................114
Практические упражнения....................................................114
Упражнение 1. Адаптивная типографическая система....................... 114
Упражнение 2. Компонентная типографика..................................115
Упражнение 3. Производительная анимация текста..........................115
Заключение.................................................................115
Долгосрочная перспектива................................................116
Углубленное чтение......................................................116
Глава G. CSS-переходы и магия анимации........................................118
Теория и терминология......................................................118
Быстрый пример..............................................................119
Основные техники и паттерны................................................120
Базовый синтаксис и свойства............................................120
Техника поэтапной задержки ............................................ 120
Паттерн accordion без JavaScript........................................122
3D трансформации с переходами...........................................123
Современные CSS-возможности.............................................. 124
Интеграция с каскадными слоями..........................................124
Контейнерные запросы и адаптивные переходы..............................125
Современные селекторы с переходами......................................126
CSS Nesting с переходами................................................127
Производительность.........................................................128
Оптимизация селекторов и инвалидация........................... 128
Управление перерасчетом макета..........................................128
Композитные слои и GPU-ускорение........................................129
Управление производительностью через containment........................129
Доступность................................................................130
Доступные фокусные состояния............................................130
Контрастность и цветовые переходы.......................................131
Отладка....................................................................131
Визуализация слоев композитинга.........................................131
Диап юс гика производительности.........................................132
Распространенные ошибки и антипаттерны.....................................132
Гонка специфичности.....................................................132
Утечки z-index и непредвиденные контексты наложения.....................133
Злоупотребление хаками вместо современных решений.......................134
Архитектура и масштабирование..............................................135
Методолот ии и организация переходов....................................135
дизайн-токены и темизация...............................................136
Композиция и повторное использование..................................137
Совместимость браузеров..................................................138
Стратегии прогрессивного улучшения_________________________ 139
Практические упражнения..................................................139
Упражнение 1. Адаптивная карточка товара............................ 139
Упражнение 2. Accordion с плавными переходами высоты..................140
Упражнение 3. Система уведомлений с анимацией.........................140
Заключение...............................................................141
Стратегии безопасного внедрения в крупных проектах....................141
Углубленное чтение....................................................141
Заключение..................................................................143
Введение
Каскадные таблицы стилей (CSS) в современной веб-разработке пред-
ставляют собой не просто средство декоративного оформления, а сложную
декларативную систему, способную решать архитектурные задачи пользо-
вательского интерфейса, которые ранее требовали императивного програм-
мирования. За двадцать пять лет эволюции CSS трансформировался из про-
стого языка стилизации в мощную платформу для создания интерактивных,
адаптивных и производительных веб-приложений.
Термин «магия CSS» в контексте данной книги относится к техникам, в ос-
нове которых лежат глубинные механизмы спецификации для достижения
результатов, кажущихся невозможными при поверхностном понимании язы-
ка. Эти техники основаны на фундаментальных принципах каскадирования,
наследования, контекстов форматирования и алгоритмов компоновки, закре-
пленных в рекомендациях W3C.
Современная веб-платформа предоставляет разработчикам беспрецедент-
ные возможности: контейнерные запросы (Container Queries) для создания
истинно модульных компонентов, каскадные слои (@1ауег) для управления
специфичностью на архитектурном уровне, логические свойства для под-
держки многонаправленного письма, субгриды для точного контроля вло-
женных сеток. Однако использование этих возможностей требует понимания
не только синтаксиса, но и внутренних процессов браузерного движка.
Данная книга предназначена для ведущих инженеров среднего и старше-
го звена, которые стремятся выйти за рамки фреймворк-специфичных реше-
ний и овладеть фундаментальными принципами платформы. Материал ори-
ентирован на практическое применение в производственных системах, где
критически важны производительность, поддерживаемость кода и предска-
зуемость поведения интерфейсов.
В каждой главе теоретические основы сочетаются с практическими при-
мерами, анализом производительности и стратегиями отладки. От блочной
модели CSS — фундамента всех алгоритмов компоновки — до сложных ком-
позиционных техник с переходами и анимациями книга обеспечивает систе-
матическое усвоение возможностей современного CSS.
Понимание этих принципов позволяет создавать решения, которые рабо-
тают стабильно в различных браузерных средах, масштабируются в крупных
кодовых базах и адаптируются к изменяющимся требованиям без архитек-
турных переработок. Эти знания становятся особенно ценными в эпоху ком-
понентно-ориентированной разработки, где каждый интерфейсный элемент
должен функционировать независимо, но согласованно в рамках общей си-
стемы дизайна.
Материал книги основан на актуальных спецификациях W3C, тестирова-
нии в современных браузерных движках и опыте применения техник в про-
изводственных проектах различного масштаба. Каждый пример протестиро-
ван на совместимость и производительность, что обеспечивает готовность
решений к использованию в реальных условиях.
Глава 1. Блочная модель CSS: основа
визуального отображения
Блочная модель CSS (CSS Box Model) представляет собой фундаментальную
концепцию, определяющую, как браузер вычисляет размеры и позиционирова-
ние элементов на веб-странице. Каждый элемент в документе генерирует пря-
моугольный блок, состоящий из областей содержимого, внутренних отступов
(padding), границ (bo г de г) и внешних отступов (margin). Понимание принципов
работы блочной модели критически важно для создания предсказуемых и мас-
штабируемых пользовательских интерфейсов.
В этой главе мы рассмотрим не только базовые концепции блочной модели,
но и современные техники управления размерами элемент ов, включая свойство
box- sizing, взаимодействие с новыми CSS-возможностями, такими как контей-
нерные запросы (Container Queries) и логические свойства, а также стратегии оп-
тимизации производительности и отладки. Материал ориентирован на разра-
ботчиков. которые стремятся к глубокому пониманию механизмов рендеринга
браузера и созданию профессиональных CSS-архитектур.
TexiniKH. описанные в данной главе, применимы в создании адаптивных компо-
нентов, системах дизайна, сложных макетах с использованием CSS Grid и ПехЬох,
а также при оптимизации производительности рендеринга в крупных веб-прило-
жениях.
Теория и терминология
Блочная модель — спецификация CSS, определяющая, как браузер вычисляет
общий размер элемента на основе четырех прямоугольных областей: содержимо-
го (content), внутренних отступов (padding), границ (border) и внешних отступов
(margin).
Каскад (Cascade) — алгоритм определения приоритета CSS-правил на основе
специфичности, порядка объявления и источника стилей.
Специфичность (Specificity) — числовое значение, определяющее вес CSS-се-
лектора при разрешении конфликтов стилей.
Контекст форматирования (Formatting Context) — область документа, в ко-
торой дочерние элементы размещаются согласно определенному набору пра-
вил. Основные типы: блочный (Block Formatting Context, ВЕС), строчный (Inline
Formatting Context) и llex/grid контексты.
Контекст наложения (Stacking Context) — трехмерное представление
HTML-элементов вдоль оси Z, определяющее порядок отрисовки элементов
на экране.
Вычисленное значение (Computed Value) — значение CSS-свойства после
применения каскада и наследования, но до окончательного разрешения в ис-
пользуемое значение.
Используемое значение (Used Value) — окончательное значение CSS-свой-
ства после всех вычислений, включая разрешение процентных значений и еди-
ниц измерения.
Исторический контекст
Блочная модель была стандартизирована в CSS1 (1996) и существенно уточ-
нена в CSS 2.1. Введение свойства box-sizing в CSS3 решило многие проблемы
интуитивности размеров элементов. Современные возможности, такие как ло-
гические свойства (CSS Logical Properties) и контейнерные запросы (Container
Queries), расширяют блочную модель для поддержки многонаправленного
письма и контейнерно-ориентированного дизайна.
Быстрый пример
Рассмотрим классический пример, демонстрирующий разницу между
content-box и border-box:
<div class=”container">
<div class=”box content-box”>Content Box</div>
<div class=’’box border-box">Border Box</div>
</div>
.container {
display: flex;
gap: 20px;
max-width: 600px;
}
.box {
width: 200px;
height: 1O0px;
padding: 20px;
border: 5px solid #333;
background-color: #f0f0f0;
font-family: system-ui;
}
.content-box {
box-sizing: content-box; /* значение по умолчанию */
}
.border-box {
box-sizing: border-box;
}
.container {
display: flex;
gap: 20px;
max-width: 600px;
}
Почему это работает
При box-sizing: content-box (значение но умолчанию) браузер интерпре-
тирует width и height как размеры области содержимого. Общий размер эле-
мента вычисляется как:
Общая ширина = width » padding-left + padding-right + border- left-width +
border-right-width.
Для нашего примера: 20Ирх + 20рх + 20рх + 5рх + 5рх = 250рх.
При box-sizing: border-box значения width и height включают padding
и border:
Общая ширина = width = 200px.
Область содержимого = width - padding - border = 200рх - 40рх -10рх = 150рх.
Браузер применяет каскадные правила для определения окончательного зна-
чения box-sizing, затем использует это значение при вычислении размеров
в процессе layout (макетирования).
Основные техники и паттерны
Универсальное применение border-box
Техника глобального переопределения box-sizing для всех элементов, обе-
спечивающая более интуитивное поведение размеров:
*
* ::before,
* ::after {
box-sizing: border-box;
}
Расширенная версия с наследованием:
html {
box-sizing: border-box;
}
*
* ::before,
*: rafter {
box-sizing: inherit;
}
Почему это работает
Первый подход использует универсальный селектор (*) со специфичностью
0-0-0-1, что позволяет легко переопределить поведение для конкретных эле-
ментов. Селекторы псевдоэлементов ::before и : rafter обеспечивают согласо-
ванность поведения генерируемого содержимого.
Второй подход создает каскадное наследование: корневой элемент html
устанавливает border-box, а все остальные элементы наследуют это значение
через inherit. Это позволяет создавать компоненты, которые могут временно
переключаться на content-box без глобального влияния.
Гибкие формы ввода
Техника создания адаптивных полей ввода с фиксированными внутренними
отступами и переменной шириной:
<form class="search-form''>
<input
type=”search"
class="search-input"
placeholder^"Поиск..
>
<button type="submit" class="search-button">
Найти
</button>
</form>
.search-form {
display: flex;
max-width: 500px;
margin: 0 auto;
}
.search-input {
flex: 1;
padding: 0.8em 1em;
border: 2px solid #ddd;
border-radius: 4px 0 0 4px;
font-size: 16px;
box-sizing: border-box;
min-width: 0; /* предотвращает переполнение flex-элемента */
}
.search-button {
padding: 0.8em 1.2em;
border: 2px solid #097acc;
border-left: none;
background-color: #0О7асс;
color: white;
border-radius: 0 4px 4px 0;
font-size: 16px;
cursor: pointer;
box-sizing: border-box;
}
Почему это работает
Flexbox создает гибкий контекст форматирования, где элемент с flex: 1 за-
нимает все доступное пространство. Свойство box-sizing : border-box гаран-
тирует, что padding и border включены в вычисления flex-размеров, предот-
вращая переполнение контейнера. Свойство min-width: 0 переопределяет
автоматический минимальный размер flex-элемента, позволяя ему сжиматься
ниже размера содержимого
Компонентная система с предсказуемыми размерами
.card {
width: 100%;
max-width: 400рх;
padding: 1.5rem;
border: 1px solid #e0e0e0;
border-radius: 8px;
box-sizing: border-box;
background-color: white;
}
.card__header {
margin: -1.5rem -1.5rem 1 rem -1.5rem;
padding: 1 rem 1.5rem;
background-color: #f8f9fa;
border-bottom: 1px solid #e0eOe0;
box-sizing: border-box;
}
.card__content {
margin-bottom: 1rem;
}
.card__footer {
margin: 1 rem -1.5rem -1.5rem -1.5rem;
padding: 1 rem 1.5rem;
background-color: #f8f9fa;
border-top: 1px solid #е9ейеб;
box-sizing: border-box;
}
Почему это работает
Отрицательные margins используются для расширения дочерних элементов
за пределы padding родителя, создавая эффект полной ширины. Браузер вычис-
ляет margins после применения box-sizing, поэтому отрицательные значения
корректно взаимодействуют с border-box. Это создает визуальный эффект сек-
ций карточки при сохранении согласованного внутреннего отступа для основ-
ного содержимого.
Современные CSS-возможности
Логические свойства и блочная модель
Логические свойства (CSS Logical Properties) предоставляют альтернативу фи-
зическим направлениям для поддержки различных режимов письма:
.logical-box {
/* Вместо width/height */
inline-size: 300рх;
block-size: 200рх;
/* Вместо padding-top/right/bottom/left */
padding-block-start: 1rem;
padding-block-end. 1rem;
padding-inline-start: 1.5rem;
padding-inline-end: 1.5rem;
/* Вместо border-top/right/bottom/left */
border-block-start; 2px solid #333;
border-inline-start: 1px solid #666;
box-sizing: border-box;
}
/* Поддержка RTL/LTR и вертикального письма */
.text-container {
writing-mode: horizontal-tb; /* или vertical-rl */
direction: Itr; /* или rtl */
}
Контейнерные запросы (Container Queries) и блочная модель
Контейнерные запросы (Container Queries) позволяют применять стили на ос-
нове размеров контейнера:
.card-container {
container-type; inline-size;
container-name: card;
width: 100%;
max-width: 600px;
}
.card {
padding: 1rem;
border: Ipx solid #ddd;
box-sizing: border-box;
}
/* Адаптация на основе размера контейнера */
©container card (min-width: 400px) {
.card {
padding: 2rem;
display: grid;
grid-template-columns: Ifr 2fr;
gap: 1.5rem;
} '
}
Cascade Layers и управление специфичностью
©layer reset, base, components, utilities;
©layer reset {
* {
box-sizing; border-box;
}
©layer base {
input {
padding: 0.5rem;
border: Ipx solid #ccc;
}
}
©layer components {
.search-input {
padding: Irem;
border-radius: 4рх;
}
}
Современные CSS-функции для размеров
.responsive-box {
/* Гибкие размеры с ограничениями */
width: clamp(300px, 50vw, 8йирх);
height: с1ашр(20ирх, 30vh, 500рх);
/* Адаптивные отступы */
padding: max(1rem, 2vw);
/* Безопасные области для мобильных устройств */
padding-bottom: max(1rem, env(safe-area-inset-bottom));
box-sizing: border-box;
}
/* Новые viewport-единицы */
.full-height-section {
min-height: 160dvh; /* динамическая высота viewport */
box-sizing: border-box;
}
Селекторы :has() и условная стилизация
/* Адаптация блочной модели на основе содержимого */
.card:has(.card__image) {
padding-top: 0;
}
.card:has(.card__image) .card__content {
padding-top: 1rem;
}
/* Стилизация родителя на основе состояния дочерних элементов */
.form-group:has(input:invalid) {
border: 2px solid #dc3545;
box-sizing: border-box;
}
Производительность
Оптимизация перерасчета макета
Изменение свойств блочной модели может вызывать дорогостоящие опера-
ции layout (reflow):
/* Дорогие операции - вызывают layout */
.expensive {
width: 300рх; /* reflow */
height: 200px; /* reflow */
padding: 20px; /* reflow */
margin: i0px; /* reflow */
}
/* Дешевые операции - только compositing */
.cheap {
transform: translateX(10px); /* composite */
opacity: 0.8; /* composite ★/
}
Использование CSS Containment
.component {
/* Изолирует стилевое влияние */
contain: style;
box-sizing: border-box;
}
.card-list {
/* Оптимизирует layout для списков */
contain: layout style;
}
.image-gallery {
/* Полная изоляция */
contain: strict;
box-sizing: border-box;
}
Стратегии для will-change
.animated-box {
/* Предварительная оптимизация для анимируемых свойств */
will-change: transform;
box-sizing: border-box;
}
/* Удаление will-change после анимации */
,animated-box.animation-complete {
will-change: auto;
}
Почему это работает
Браузер выполняет рендеринг в несколько этапов: Layout - Paint -
Composite. Изменение размеров (width, height, padding, margin) требует пе-
ресчета макета для элемента и всех зависимых элементов. Свойство contain соз-
дает изолированный контекст форматирования, ограничивая область пересчета.
Свойство will-change подсказывает браузеру создать кошгозитный слой заранее.
Доступность (Ally)
Адаптивная типографика и блочная модель
.content {
/* Адаптивные размеры для улучшения читаемости */
max-width: 65ch; /* оптимальная длина строки */
padding: с1атр(1гет, 4vw, 2гет);
box-sizing: border-box;
/* Поддержка пользовательских настроек */
font-size: clamp(1rem, 1 rem + 0.5vw, 1.25rem);
line-height: 1.6;
}
/* Респект к настройкам пользователя */
@media (prefers-reduced-motion: reduce) {
.animated-box {
transition: none;
}
}
/* Улучшенный контраст в режиме высокого контраста */
@media (prefers-contrast: high) {
.card {
border-width: 2px;
border-color: currentcolor;
box-sizing: border-box;
}
}
Видимые области фокуса
.interactive-element {
padding' 0.75rem 1 rem;
border: 2px solid transparent;
box-sizing: border-box;
position: relative;
}
/* Видимый фокус для клавиатурной навигации */
.interactive-element:focus-visible {
outline: 2px solid #005fcc;
outline-offset: 2px;
}
/* Стили для focus-within (когда фокус внутри элемента) */
.form-group:focus-within {
border-color: #005fcc;
box-sizing: border-box;
}
Поддержка направления текста
.bilingual-component {
box-sizing: border-box;
/* Логические свойства для RTL поддержки */
padding-inline-start: 1rem;
padding-inline-end: 2rem;
border-inline-start: 3px solid #007acc;
}
/* Физические свойства как fallback */
.bilingual-component {
padding-left: 1rem;
padding-right: 2rem;
border-left: 3px solid #007acc;
/* Логические свойства переопределяют физические */
padding-inline-start: 1rem;
padding-inline-end: 2rem;
border-inline-start: 3px solid #007acc;
}
Отладка
Инструменты разработчика
Современные DevTools предоставляют мощные средства для отладки блоч-
ной модели:
/* Временные стили для отладки */
.debug-box-model * {
background-color: rgba(255, 0, 0, 0.1) iimportant;
border: 1px solid red iimportant;
box-sizing: border-Dox iimportant;
.debug-spacing * {
background-clip: content-box ’important;
background-color: rgba(0, 255, 0, 0.1) iimportant;
Методы диагностики размеров
/* Outline для визуализации без влияния на layout */
.debug-outline {
outline: 2рх solid red;
outline-offset: -ipx;
/* Использование box-shadow для отладки */
.debug-shadow {
box-shadow:
inset 0 0 1px red,
/* граница содержимого */
inset 000 21px rgba(0, 255, G, 0.1); /* padding */
}
/* CSS-переменные для отладки размеров */
.debug-sizes {
--debug-width: attr(data-width px, auto);
-debug-height: attr(data-height px, auto);
position: relative;
.debug-sizes::before {
content: 'W: var(--debug-width) H: var(--debug-height)' ;
position: absolute;
top: 0;
left: 0;
font-size: 12рх;
color: red;
pointer-events: поле;
}
Диагностика специфичности и каскада
/* Временное переопределение для тестирования */
.test-specificity {
box-sizing: content-box !important;
border: 5px solid orange 'important;
}
/* Использование CSS-переменных для отслеживания значений */
:root {
--debug-mode: 0;
}
.component {
box-sizing: border-box;
border: calc(var(--debug-mode) * 2px) solid red;
}
/* Активация через инспектор */
.debug :root {
--debug-mode: 1;
}
Частые ошибки и антипаттерны
Специфичность и ’important
Антипаттерн:
.sidebar {
width: 300рх !important;
box-sizing: content-box (important;
}
.sidebar.compact {
width: 200px (important; /* война важности */
}
Правильный подход:
.sidebar {
width: 300рх;
box-sizing: border-box;
}
.sidebar--compact {
width: 200px;
}
Смешивание единиц измерения без border-box
Антипаттерн:
.problematic-input {
width: 100%;
padding: 10px;
border: 2px solid #ccc;
/* box-sizing: content-box по умолчанию */
/* Общая ширина = 100% + 20px + 4px */
}
Правильный подход:
.proper-input {
width: 100%;
padding: 10px;
border: 2px solid #ccc;
box-sizing: border-box;
/* Общая ширина = 100% */
}
Неправильное использование margin для внутренних отступов
Антипаттерн:
.card-content {
margin: 20рх; /* может вызвать margin collapse */
}
.card-content:first-child {
margin-top: 0; /* хакерский подход */
}
Правильный подход:
.card {
padding; 20рх;
box-sizing: border-box;
}
.card-content + .card-content {
margin-top: 1rem; /* отступы только между элементами */
}
Z-index без контекста наложения
Антипатптерн:
.modal {
z-index: 9999; /* магическое число */
position: absolute;
}
.dropdown {
z-index: 100O0; /* еще больше магии */
position: relative;
}
Правильный подход:
/★ Создание управляемых контекстов наложения */
.page-layout {
position: relative;
z-index: 0; /* создает stacking context ★/
}
.modal-layer {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 100;
}
.dropdown {
position: relative;
z-index: 1; /* локальный контекст */
}
Архитектура и масштабирование
ВЕМ и блочная модель
/* Блок */
.card {
box-sizing: border-box;
border: 1px solid #ddd;
border-radius: 4px;
}
/* Элементы */
.card__header {
padding: 1rem;
border-bottom: 1px solid #eee;
box-sizing: border-box;
}
.card__body {
padding: 1rem;
box-sizing: border-box;
}
.card__footer {
padding: Irem;
border-top: Ipx solid #eee;
box-sizing: border-box;
}
/* Модификаторы */
.card--compact .card__header,
.card--compact .card__body,
.card--compact .card__footer {
padding: 6.5rem;
}
ITCSS и Cascade Layers
©layer settings, tools, generic, elements, objects, components,
utilities;
©layer generic {
* {
box-sizing: border-box;
}
}
©layer elements {
input,
button,
textarea {
padding: 9.5rem;
border: 1px solid #ccc;
box-sizing: border-box;
}
}
©layer objects {
.o-container {
max-width: 1200px;
margin: 0 auto;
padding: 0 Irem;
box-sizing: border-box;
}
}
©layer components {
.c-button j
padding: 0.75rem 1.5rem;
border: none;
border-radius: 4px;
box-sizing: border-box;
}
}
©layer utilities {
.u-box-border {
box-sizing: border-box ’important;
}
}
Дизайн-токены и кастомные свойства
’.root {
/* Размеры */
--space-xs: 025rem;
- -space-sm: 0 5rem;
- -space-md: 1rem;
- -space-lg: 1.5rem;
- -space-xl: 2rem;
/* Границы */
- -border-width-thin: 1 рх;
— border-width-thick: 2рх;
- “border-radius-sm: 4рх;
- -border-radius-md: 8рх;
/* Контейнеры */
--container-max-width: 1200рх;
- -container-padding: var(--space-md);
}
.component {
padding: var(--space-md);
border: var(--border-width-thin) solid #ddd;
border-radius: var(--border-radius-sm);
box-sizing: border-box;
}
/* Темная тема */
@media (prefers-color-scheme: dark) {
:root {
--border-color: #555;
}
}
Контейнерные стратегии
/* Система контейнеров */
.layout-ccntainer {
container-type: inline-size;
container-name: layout;
max-width: var(--container-max-width);
margin: 0 auto;
padding: 0 var(--container-padding);
box-sizing: border-box;
}
/* Адаптивные компоненты */
.adaptive-card {
padding: var(--space-md);
box-sizing: border-box;
}
(^container layout (min-width: 768px) {
.adaptive-card {
padding: var(--space-lg);
display: grid;
grid-template-columns: Ifr 2fr;
gap: var(--space-lg);
} '
}
Совместимость браузеров
Функция Chrome Firefox Safari Edge Примечания
box-sizing: border-box 10+ 29+ 5.1+ 12+ Универсальная поддержка
box-sizing’ content-box Все версии Все версии Все вер- сии Все версии Значение по умолчанию
Логические свойства (inline- size) 87+ 41+ 12.1+ 87+ Частичная под- держка в старых версиях
Container Queries 105+ 110+ 16+ 105+ Относительно новая функция
:has() се- лектор 105+ 103+ 15.4+ 105+ Не поддержи- вается в Firefox для Android
Cascade Layers (@layer) 99+ 97+ 15.4+ 99+ Прогрессивное улучшение
clampO, min(), max() 79+ 75+ 13.1+ 79+ Fallback для ста- рых браузеров
Новые viewport-еди- ницы (dvh) 108+ 101+ 15.4+ 108+ Эксперименталь- ная поддержка
env() функ- ция 69+ Нет 11.1 + 79+ В основном для iOS Safari
Стратегии прогрессивного улучшения
/* Fallback для старых браузеров */
.responsive-container {
/* Базовая поддержка */
max-width: 1200рх;
padding: 16рх;
box-sizing: border-box;
/* Прогрессивные улучшения */
max-width: min(1200px, 90vw);
padding: clamp(1rem, 4vw, 2rem);
}
/* Feature queries для современных возможностей */
@supports (container-type: inline-size) {
.container-query-component {
container-type: inline-size;
}
}
^supports selector(:has(*)) {
.conditional-layout:has(.sidebar) {
display: grid;
grid-template-columns: 250px 1fr;
}
}
/* Логические свойства c fallback */
.multilingual-box {
/* Физические свойства как базовая поддержка */
padding-left: 1rem;
padding-right: 2rem;
border-left: Зрх solid #007acc;
/* Логические свойства для современных браузеров */
padding-inline-start: 1rem;
padding-inline-end: 2rem;
border-inline-start: 3px solid #067acc;
box-sizing: border-box;
}
Практические упражнения
Упражнение 1. Адаптивная карточная система
Требования:
• Создайте компонент карточки, который адаптируется к размеру контейнера.
• Используйте Container Queries для изменения макета при ширине
контейнера более 400рх.
• Обеспечьте корректную работу в браузерах без поддержки Container
Queries.
• Размеры должны быть предсказуемыми независимо от содержимого.
Условия выполнения:
• Карточка имеет фиксированный padding в его или rem.
• При широком контейнере содержимое располагается в две колонки.
• Границы и отступы включены в общие размеры.
• Компонент работает корректно в Safari 15+.
Подсказки:
• Используйте container-type: inline-size.
• Реализуйте fallback через media queries.
• Примените box-sizing: border-box глобально.
• Измерьте производительность через DevTools.
Упражнение 2. Универсальная система форм
Требования:
• Создайте набор компонентов форм с единообразными размерами.
• Поля ввода должны корректно работать с процентной шириной.
• Реализуйте поддержку темной и светлой темы.
• Обеспечьте доступность для клавиатурной навигации.
Условия выполнения:
• Все элементы форм имеют одинаковую высоту при одинаковом размере
шрифта.
• Padding выражен в еш для масштабируемости.
• Фокусные стили видимы и не нарушают макет.
• Поддержка prefers-color-scheme.
Подсказки:
• Используйте логические свойства для международной поддержки.
• Примените : focus-visible для улучшения UX.
• Создайте CSS-переменные для согласованности.
• Протестируйте с различными размерами шрифта.
Упражнение 3. Производительный макет списка
Требования:
• Создайте виртуализированвый список с тысячами элементов.
• Каждый элемент должен иметь предсказуемые размеры.
• Минимизируйте количество reflow операций.
• Реализуйте lazy loading изображений.
Условия выполнения:
• Время первой отрисовки менее 16ms на современных устройствах.
• Прокрутка остается плавной при 60 FPS.
• Layout Shift отсутствует при загрузке контента.
• корректная работа с will-change.
Подсказки:
• Используйте contain: layout style.
• Избегайте вычислений размеров в JavaScript.
• Примените transform вместо изменения позиции.
• Измерьте с помощью Performance Timeline API.
Заключение
Блочная модель CSS остается фундаментальной концепцией для созда-
ния предсказуемых и производительных пользовательских интерфейсов.
Современные разработчики должны уверенно применять box-sizing:
border-box как стандартную практику, использовать логические свойства
для международной поддержки и интегрировать новые возможности, такие
как Container Queries и Cascade Layers, для создания адаптивных компонен-
тов.
Для безопасного внедрения в продакшен рекомендуется сосредоточить-
ся на универсально поддерживаемых функциях: box-sizing, базовых логиче-
ских свойствах (inline-size, block-size), современных CSS-функциях (clamp,
min, max) и селекторах (:focus-visible :is, :where). Экспериментальные воз-
можности, такие как новые viewport-единицы и математические CSS-функ-
ции, следует применять как прогрессивные улучшения с соответствующими
fallback-сгратегиями.
Крупные кодовые базы выиграют от систематического подхода к блочной мо-
дели через дизайн-токены, CSS-переменные и архитектурные методологии (ВЕМ,
ITCSS), дополненные современными инструментами управления каскадом. Кри-
тически важно поддерживать производительность через оптимальное исполь-
зование CSS Containment и понимание влияния различных свойств на этапы
рендеринга браузера.
Углубленное чтение
CSS Box Model Module Level 3 — официальная спецификация
W3C: https://w3.org/TR/css-box-3/.
CSS Box Model Module Level 4 — официальная спецификация
W3C: https://w3.org/TR/css-box-4/.
CSS Box Model — официальная документация MDN:
https//developer.mozilla.org/docs;'Web/CSS/CSS_Box_Model.
Box-sizing — официальная документация
https://developer.mozilla.org/docs/Web/CSS/box-sizing.
CSS J.ogical Properties — официальная документация MDN:
https://developer.mozilla.Org/docs./Web/CSS/CSS_Logical_Properties.
Глава 2. Продвинутые техники
компоновки
Современная веб-разработка требует глубокого понимания каскадных та-
блиц стилей (CSS) не только как инструмента для стилизации, но и как мощной
системы компоновки, способной решать сложные задачи пользовательского
интерфейса. Данная глава представляет собой комплексный обзор продвину-
тых техник CSS-компоновки, охватывающий как фундаментальные концепции
спецификации W3C, так и современные возможности, находящиеся на стадии
экспериментальной реализации.
Изучение материала главы позволит ведущим инженерам среднего и стар-
шего звена овладеть техниками создания устойчивых, производительных и до-
ступных интерфейсов. Особое внимание уделяется пониманию внутренних ме-
ханизмов браузерною движка, включая процессы каскадирования, вычисления
специфичности, формирования контекстов форматирования и композиции сло-
ев отрисовки.
Практический подход главы не только обеспечивает теоретическое понима-
ние концепций, ни и предоставляет готовые к применению паттерны, архитек-
турные решения и методологии отладки, необходимые для работы с крупномас-
штабными проектами в производственной среде.
Теория и терминология
Каскад (Cascade) представляет собой алгоритм разрешения конфликтов сти-
лей, определенный в CSS Cascading and Inheritance Level 4. Алгоритм устанав-
ливает приоритет объявлений на основе важности (importance), происхож-
дения (origin), специфичности (specificity) и порядка появления (order of
appearance).
Специфичность (Specifity) — числовое значение, вычисляемое для каждого
селектора и определяющее его приоритет при разрешении конфликтов. Вычис-
ляется по формуле (inline-styles, IDs, classes/attributes/pseudo-classes,
elements/pseudo-elements), образуя четырехкомпонентное значение.
Контекст форматирования (Formatting Context) определяет область, в ко-
торой элементы размещаются и взаимодействую!’ согласно определенным пра-
вилам. Основные типы: Block Formatting Context (BFC), Inline Formatting Context
(IFC), Flex Formatting Context (FFC), Grid Formatting Context (GFC).
Контекст наложения (Stacking Context)—трехмерная концепция, определя-
ющая порядок отрисовки элементов по оси Z. Создается элементами с position,
отличным от static, и z-index, отличным от auto, элементами с opacity < 1,
transform, filter и другими CSS-свойствами.
Композиция (Composite) — финальная стадия огрисовки, где браузер объе-
диняет все слои в итоговое изображение. Операции композиции выполняются
на GPU и являются наименее затратными для производительности.
Нормальный поток документа (normal document flow) — базовый алго-
ритм размещения элементов, где блочные элементы располагаются вертикаль-
но, а строчные - горизонтально.
Layout vs Paint vs Composite
• Layout (Reflow): вычисление позиций и размеров элементов
• Paint (Repaint): заполнение пикселей на слоях
• Composite: объединение слоев в финальное изображение
Быстрый пример
Рассмотрим создание адаптивной карточной сетки с использованием
CSS Grid:
html
«div class="card-grid">
«article class=''card">
<h3Заголовок карточки«/ЬЗ>
<р>Содержимое карточки«/р>
«/article:»
«article class=”card">
<ИЗ>Заголовок карточки«/ИЗ>
«р>Содержимое карточки«/р>
</article>
</div>
css
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, Ifr));
gap: clamp(1rem, 4vw, 2rem);
container-tvpe: inline-size;
}
.card {
padding: clamp(1rem, 3vw, 1.5rem);
border-radius: 8рх;
background: color(display-p3 0.98 0.98 1);
box-shadow: 0 2px 8px color(display-p3 000/ 0.1);
container-type: inline-size;
}
<®container (max-width: 320px) {
.card h3 {
font-size: 1.1 rem;
}
}
Почему это работает
1. display: grid создает Grid Formatting Context.
2. auto-fit c minmax() обеспечивает адаптивность без media queries.
3. clamp() создает fluid scaling.
4. container-type активирует Container Queries.
5. color(display-p3) использует расширенное цветовое пространство.
Основные техники и паттерны
Типы отображения (Display Types)
CSS Grid Layout
grid-container {
display: grid;
grid-template- areas:
"header header"
"sidebar main"
"footer footer";
grid-template-columns: minmax(200px, 1fr) 3fr;
grid-template-rows: auto Ifr auto;
} ’
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer ( grid-area: footer; }
Механизм работы
Grid создает двумерную систему компоновки с явным контролем над разме-
щением элементов. Браузер создает Grid Formatting Context, вычисляет размеры
треков и размещает элементы согласно grid-area.
Flexbox Layout
.flex-container {
display: flex;
flex-direction: column;
align-items: stretch;
justify-content: space-between;
gap. 1rem;
}
.flex-item {
flex: 1 1 auto; /* flex-grow: 1, flex-shrink: 1, flex-basis: auto */
}
.flex-container {
display: flex;
flex-direction: column;
align-items: stretch;
justify-content: space-between;
gap: 1rem;
}
.flex-item {
flex: 1 1 auto; /* flex-grow: 1, flex-shrink: 1, flex-basis: auto */
}
Dexbox эффективен для одномерных компоновок. Избегайте вложенных
flex-контейнеров для двумерных сеток.
Позиционирование (Sticky Positioning)
.sticky-header {
position: sticky;
top: 0;
z-index: 100;
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(ldpx);
}
Контекст наложения:
position: sticky создает stacking context только при «прилипании»,
что может вызывать неожиданное поведение z-index.
Современные возможности CSS
Cascade Layers (Экспериментальная функция)
©layer reset, base, components, utilities;
©layer reset {
* { margin: 0; padding- 0; }
}
©layer components {
.button {
padding: 0.5rem 1rem;
border: none;
border-radius: 4px;
}
}
Container Queries (Экспериментальная функция)
.component {
container-type: inline-size;
container-name: card;
}
©container card (min-width: 4ййрх) {
.component_title {
font-size: 2rem;
}
}
CSS Subgrid (Экспериментальная функция)
.parent-grid {
display: grid;
grid-template-columns: repeat(4, Ifr);
}
.child-grid {
display: grid;
grid-column: 2/4;
grid-template-columns: subgrid;
}
Селекторы :has(), :is(), :where()
/* :has() - parent selector */
.card:has(.card_image) {
display: grid;
gnd-template-columns: auto Ifr;
} '
/* :is() - селектор с обычной специфичностью */
:is(h1, h2, h3) {
margin-block: 1em 0.5em;
}
/* :where() - селектор с нулевой специфичностью */
:where(ul, ol) li {
margin-bottom: 0.5em;
}
CSS Nesting (Экспериментальная функция)
.component {
padding: 1rem;
& .title {
font-size: 1.5rem;
& + .subtitle {
color: #666;
)
}
©media (min-width: 768px) {
padding: 2rem;
}
}
Логические свойства
.block {
margin-inline: auto;
padding-block: 2rem;
border-inline-start: 3px solid blue;
inset-inline-start: 1rem;
}
Производительность
Стоимость селекторов
/* Дорогие селекторы */
.container * { } /* универсальный селектор */
.container > * > span { } /* сложная вложенность */
:nth-child(odd) { } /* структурные псевдоклассы */
/* Эффективные селекторы */
.component { } /* класс */
#unique-element { } /* ID */
.component_element { } /* BEM методология */
Оптимизация Reflow/Repaint/Composite
.animated-element {
/* Композитные ссойства - не вызывают reflow/repaint */
transform: translateX(100px);
opacity: 0.5;
/* Избегайте анимации layout-свойств */
/* width: 200px, X */
/* left: 100px; X */
}
,gpu-accelerated {
will-change: transform, opacity;
/* Удаляйте will-change после анимации */
}
Использование will-change
.element {
/* Применяйте перед анимацией ★/
will-change: transform;
}
.element.animating {
transform: translateX(10^px);
}
/* JavaScript */
element.addEventListener('animationend', () => {
element.style.willChange = 'auto';
});
Доступность
Стили фокуса
.button {
outline: none; /* Убираем только при замене */
}
.button:focus-visible {
outline: 2px solid #0066cc;
outline-offset: 2px;
}
©media (prefers-reduced-motion: reduce) {
.button {
transition: none;
}
}
Контрастность и пользовательские предпочтения
©media (prefers-color-scheme: dark) {
.component {
background: #1a1a1a;
color: #ffffff;
}
}
©media (prefers-contrast: high) {
.component {
border: 2px solid currentcolor;
}
}
©media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0 01ms !important;
animation-iteration-count: 1 !important;
}
}
Логические свойства для RTL
.navigation {
padding-inline-start: 1rem;
border-inline-end: 1px solid #ccc;
margin-inline, auto;
}
Отладка
Техники DevTools
/* Отладка специфичности */
.debug-specificity {
background: red [important; /* 1,0,0,1 */
}
/* Визуализация контекстов форматирования */
.debug-bfc {
outline: 2px dashed blue;
}
.debug-bfc: :before {
content: "BFC";
position: absolute;
background: blue;
color: white;
padding: 2px 4px;
font-size: I0px.;
}
/* Отладка Grid */
.debug-grid {
background:
linear-gradient(90deg, rgba(255,0,0.6.1) 0%, transparent 1%),
linear-gradient(180deg, rgba(255,0,0,0.1) 0%, transparent 1%);
background-size: Irem Irem;
}
Диагностика специфичности
/* Используйте инструменты для вычисления специфичности */
/* #content .sidebar ul li a:hover = 0,1,2,3 */
/* .nav-link:hover = 0,0,2,0 */
/* Второй селектор не переопределит первый */
/* Решение: повышение специфичности */
.nav .nav-link:hover { } /* 0,0,3,0 X все еще меньше */
tfcontent .nav-link:hover { } /* 0,1,2,0 X все еще меньше */
.nav-link:hover:where(a) { } /* 0,0,2,0 X where() не добавляет спе-
цифичность */
:is(#content .sidebar ul li) .nav-link:hover { } /* 0,1,2,0 X */
/* Правильное решение */
#content .sidebar .nav-link:hover { } /* 0,1,2,0 + приоритет по по-
рядку */
Типичные ошибки и антипаттерны
Проблемы специфичности
/* Антипаттерн: слишком специфичные селекторы */
.page .content .sidebar .widget .title {
color: blue;
}
/* Лучше: используйте методологию BEM */
.widget_title {
color: blue;
}
/* Антипаттерн: iimportant для переопределения */
.title {
color: red iimportant;
}
/* Лучше: рефакторинг специфичности */
.widget .title {
color: red;
}
Проблемы z-index
/* Антипаттерн: z-index: 9999 */
.modal {
position: fixed;
z-index: 9999;
}
/* Лучше: система z-index */
:root {
--z-dropdown: 1009;
--z-sticky: 1010;
--z-fixed: 1020;
--z-mooal-backdrop: 1039;
--z-modal: 1040;
--z-tooltip: 1050;
}
.modal {
z-index: var(--z-modal);
}
Схлопывание margin
/* Проблема: неожиданное схлопывание margin */
.card {
margin: 20px 0;
}
.card p {
margin-top: 15px; /* Схлопнется c margin карточки */
}
/* Решение: создание 3FC */
.card {
margin: 20px 0;
padding: Ipx 0; /* или любое padding/border */
}
/* Альтернатива: использование gap в Grid/Flex */
.card-container {
display: flex;
flex-direction: column;
gap: 20px;
} ’
Архитектура и масштабирование
Методологии
/* BEM (Block Element Modifier) */
.navigation { } /* Block */
.navigation_item { } /* Element */
.navigation_item--active { } /* Modifier */
/* CUBE CSS */
/* Composition */
.stack {
display: flex;
flex-direction: column;
gap: var(--space-m);
}
/* Utilities */
.text-center { text-align: center; }
.visually-hidden {/*...*/}
/* Blocks */
.card { /* component styles */ }
/* Exceptions */
.card|data-theme=”dark"] { /* contextual overrides */ }
Cascade Layers для архитектуры
©layer reset, base, layout, components, utilities, overrides;
©layer reset {
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
}
}
©layer base {
html {
font-family: system-ui, sans-serif;
line-height: 1.5;
}
}
©layer layout {
.container {
max-width: 120Opx;
margin-inline: auto;
padding-inline: 1 rem;
}
}
©layer components {
.button {
padding: 0.5rem 1rem;
border: none;
border-radius: 4px;
cursor: pointer;
}
}
Система дизайн-токенов
:root {
/* Primitive tokens */
--color-blue-50: #eff6ff;
--color-blue-500: #3b82f6;
--color-blue-900: #1e3a8a;
--space-xs: 0.25rem;
--space-sm: 0.5rem;
--space-md: 1rem;
--space-lg: 1.5rem;
/* Semantic tokens */
--color-primary: var(--color-blue-500);
--color-surface: var(--color-blue-50);
--spacing-component-padding: var(--space-md);
}
©media (prefers-color-scheme: dark) {
:root {
--color-primary: var(--color-blue-400);
--color-surface: var(--color-blue-900);
}
}
Совместимость браузеров
Функция Chrome Firefox Safari Edge Примечания
CSS Grid 57+ 52+ - 10.1+ 16+ Полная поддержка
Flexbox Container Queries 29+ 28+ 4 105+ 110+ _L 9+ 12+ Полная поддержка
16+ r 105+ Экспериментальная
Cascade Layers 99+ 97+ 15.4+ 99+ -t- - 105+ Экспериментальная
1 :has() 105+ 103+ 15.4+ Экспериментальная
Subgrid X 71+ 16+ X Ограниченная поддержка
CSS Nesting 112+ X 16.5+ _ 112+ - Экспериментальная
color(display-p3) 58+ X 10+ 79+ Ограниченная поддержка
oklch() 111 + X 15.4+ 111 + Эксперимент альная
Стратегии fallback
/* Прогрессивное улучшение для Grid */
.layout {
display: flex; /* fallback */
flex-wrap: wrap;
}
©supports (display: grid) {
.layout {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
} '
}
/* Feature queries для современных функций */
©supports (container-type: inline-size) {
.component {
container-type: inline-size;
}
}
©supports not (container-type: inline-size) {
©media (max-width: 400px) {
.component {
/* media query fallback */
}
}
}
Практические упражнения
Упражнение 1. Адаптивная карточная сетка
Требования:
• Адаптивная сетка без media queries.
• Минимальная ширина карточки 280рх.
• Использование современных CSS-функций.
• Поддержка RTL.
Подсказки:
• Используйте grid-template-columns: repeat(auto-fit,
minmax(.. .)).
• Применяйте логические свойства.
• Добавьте container-type для будущих улучшений.
Упражнение 2. Сложная компоновка с Subgrid
Требования:
• Родительская Grid с 4 колонками.
• Дочерний элемент занимает 2-3 колонки.
• Subgrid для выравнивания содержимого.
Подсказки:
• Проверьте поддержку браузера.
• Используйте fallback-стратегию.
• Примените ©supports для progressive enhancement.
Упражнение 3. Оптимизированная анимация
Требования:
• Анимация должна использовать только композитные свойства.
• Поддержка prefers-reduced-motion.
• Правильное использование will-change.
Подсказки:
• Анимируйте только transform и opacity.
• Удаляйте will-change после анимации.
• Используйте CSS custom properties для timing.
Заключение
Продвинутые техники CSS-компоновки представляют собой мощный ин-
струментарий для создания современных веб-интерфейсов. Освоение этих
техник требует глубокого понимания не только синтаксиса, но и внутренних
механизмов браузерной отрисовки, принципов доступности и производитель-
ности.
Стабильные техники CSS Grid, Flexbox, логические свойства и современные
селекторы (:is, :where) готовы для широкого применения в производственных
проектах с соответствующими fallback-стратегиями.
Экспериментальные возможности Container Queries, Cascade Layers, :has(),
CSS Nesting следует использовать с осторожностью, обеспечивая полноценные
fallback-решения и тщательно тестируя совместимость.
Архитектурный подход: применение методологий (BEM, CUBE CSS) в соче-
тании с Cascade Layers и системой дизайн-токенов обеспечивает масштабируе-
мость и поддерживаемость крупных проектов.
Производительность: приоритет композитным анимациям, осознанное ис-
пользование will-change, оптимизация специфичности селекторов и мини-
мизация операций reflow/repaint критически важны для пользовательского
опыта.
Доступность: логические свойства, поддержка пользовательских предпочте-
ний и семантически корректная реализация интерактивных элементов должны
быть неотъемлемой частью любою решения компоновки.
Постоянное развитие CSS-спецификаций открывает новые возможности,
но фундаментальные принципы каскада, специфичности и контекстов форма-
тирования остаются основой профессионального владения технологией. Инве-
стиции в глубокое понимание этих концепций окупаются повышением каче-
ства кода, упрощением отладки и возможностью создания устойчивых решений,
адаптирующихся к будущим изменениям платформы.
Углубленное чтение
CSS Grid Layout — официальная документация MDN:
https://developer.mozilla.urg/en-US/docs/Web/CSS/CSS.grid_layout.
CSS Grid Layout — основы: https://developer.mozilla.org/en-US/
docs/Web/CSS/CSS_grid_layout/Basic_concepts_of_grid_layout.
CSS Container Queries — MDN: https://developer.mozilla.org/en-
US/docs/Web/CSS/CSS_containment/Container_queries.
Глава 3. Мастерство табличной верстки
и продвинутые техники
Данная глава посвящена глубокому изучению табличной верстки в CSS и про-
двинутых техник, которые можно отнести к категории CSS Magic. Табличная мо-
дель CSS представляет собой один из самых сложных и мощных алгоритмов
компоновки в веб-стаидартах, способный решать задачи, которые долгое время
казались невозможными без использования JavaScript или сложных хаков.
Мы рассмотрим принципы работы свойства table-layout, механизмы авто-
матического и фиксированного алгоритмов размещения столбцов, а также со-
временные подходы к созданию адаптивных табличных интерфейсов. Особое
внимание уделено интеграции традиционных табличных техник с современ-
ными возможностями CSS, такими как Container Queries, логические свойства
и каскадные слои.
Техники, описанные в этой главе, применимы при создании сложных ин-
терфейсов для отображения табличных данных, реализации сетчатых маке-
тов с точным контролем размеров и создания адаптивных компонентов, ко-
торые должны сохранять пропорции при различных размерах контейнера.
Понимание этих принципов критически важно для решения задач, где тре-
буется точный контроль над распределением пространства и выравнивани-
ем контента.
Теория и терминология
Табличная модель CSS (CSS Table Model) — алгоритм компоновки, опреде-
ленный в спецификации CSS 2.1, который описывает, как браузер вычисляет раз-
меры и позиционирование элементов с табличным отображением.
Алгоритм автоматической компоновки таблиц (Automatic Table Layout
Algorithm) — метод вычисления ширины столбцов, основанный на содержи-
мом ячеек и заданных ограничениях ширины.
Алгоритм фиксированной компоновки таблиц (Fixed Table Layout
Algorithm) — упрощенный метод вычисления ширины столбцов, основанный
исключительно на заданных значениях ширины первой строки.
Контекст форматирования таблицы (Table Formatting Context) — специ-
альный контекст форматирования, создаваемый элементами с display: table,
который определяет правила размещения дочерних табличных элементов.
Модель табличного блока (Table Box Model) — расширенная модель бло-
ка, включающая дополнительные отступы (border-spacing) между ячейками
и специальные правила схлопывания границ.
Исторически табличная верстка была единственным способом создания
сложных макетов до появления ПехЬох и Grid. Современный подход предпо-
лагает использование табличной модели исключительно для отображения та-
бличных данных, однако знание ее принципов остается важным для понимания
каскада и специфичности, а также для решения специфических задач выравни-
вания.
В процессе рендеринга табличная модель участвует на этапе Layout (вычис-
ление размеров и позиций), что делает ее одним из наиболее затратных типов
компоновки с точки зрения производительности.
Быстрый пример
Рассмотрим базовый пример, демонстрирующий фундаментальное разли-
чие между алгоритмами auto и fixed:
<table class="demo-table demo-auto'>
<tr>
<td>flBHHHbiM заголовок объекта</Тб>
<td>flencTBne</td>
</tr>
<tr>
<td>KopoTKMH</td>
<td>yflaanTb</td>
</tr>
</table>
<table class=“demo-table demo-fixed">
<tr>
<Тб>Длинный заголовок объекта</Чб>
<td>fleMCTBne</td>
</tr>
<tr>
<td>KopoTKi/w</td>
<td>yflaanTb</td>
</tr>
</table>
.demo-table {
width: 400px;
border-collapse: collapse;
border: 1px solid #ccc;
}
.demo-table td {
padding: 8px;
border: 1px solid #ddd;
}
.demo-auto {
table-layout: auto;
}
.demo-fixed {
table-layout: fixed;
}
Почему это работает
Браузер применяет различные алгоритмы вычисления ширины столб-
цов в зависимости от значения table-layout. При auto браузер анализи-
рует содержимое всех ячеек столбца для определения оптимальной ши-
рины, что приводит к пропорциональному распределению пространства.
При fixed браузер использует равномерное распределение (50%/50% в случае
двух столбцов без явно заданных ширин), игнорируя содержимое ячеек после
первой строки.
Алгоритм auto требует двухпроходной обработки: первый проход для анали-
за содержимого, второй для окончательного размещения. Алгоритм fixed вы-
полняется за один проход, что делает его более производительным для больших
таблиц.
Основные техники и паттерны
Контроль пропорций с table-layout: auto
Определение: использование автоматического алгоритма для созда-
ния адаптивных столбцов, которые масштабируются в соответствии с содер-
жимым.
Следует применять при отображении данных с неодинаковой длиной содер-
жимого в столбцах, когда важно оптимальное использование доступного про-
странства:
<table class='proportional-table">
<colgroup>
<col style="width: 20%">
<col style="width: 60%">
<col style="width: 20%">
</colgroup>
<thead>
<tr>
<th>ID</th>
<th>OnncaHne</th>
<th>CTaTyc</th>
</tr>
</thead>
<tbody>
<tr>
<td>001</td>
<td>04enb длинное описание задачи, которое может занимать не-
сколько CTpoK</td>
<td>AKTHBeH</td>
</tr>
<tr>
<td>002</td>
<td>KopoTKoe описание</гб>
<td>HeaKTHBeH</td>
</tr>
</tbody>
</table>
.proportional-table {
width: 100%;
table-layout: auto;
border-collapse: collapse;
}
.proportional-table th,
.proportional-table td {
padding: 12px;
text-align: left;
border-bottom: 1px solid #ddd;
}
.proportional-table th {
background-color: #f5f5f5;
font-weight: 600;
}
Почему это работает
Элемент <colgroup> с дочерними <col> предоставляет браузеру подсказ-
ки о желаемых пропорциях столбцов. Алгоритм auto использует эти значения
как относительные веса при распределении доступного пространства. Браузер
вычисляет минимальную и максимальную ширину каждого столбца на основе
содержимого, затем применяет заданные пропорции в пределах этих ограниче-
ний.
Процесс вычисления включает:
1. Определение минимальной ширины каждого столбца (самое длинное не-
разрывное слово).
2. Определение максимальной предпочтительной ширины (ширина содер-
жимого без переносов).
3. Распределение доступного пространства пропорционально заданным про-
центам.
4. Корректировку с учетом ограничений содержимого
Точное позиционирование с table-layout: fixed
Определение: использование фиксированного алгоритма для создания пред-
сказуемой структуры столбцов с точным контролем размеров.
Следует применять при создании интерфейсов с фиксированной структурой,
где важна предсказуемость отображения, особенно для больших таблиц с сотня-
ми строк:
<table class=”fixed-table">
<colgroup>
<col style="width: 80рх">
<col style=“width: 200рх ’>
<col style="width: 120рх ’>
<со!> <! — получит оставшееся пространство -->
</colgroup>
<thead>
<tr>
<th>ID</th>
<1Ь>Наименование</ТЬ>
<th>LJeHa</th>
<1Ь>Примечания</th>
</tr>
</thead>
<tbody>
<tr>
<td>12345</td>
<td>TnRap с очень длинным назпанием</1б>
<td>1 000 ₽</td>
«^Дополнительная информация может быть очень длинной</1б>
</tr>
</tbody>
</table>
.fixed-table {
width: 600px;
table-layout: fixed;
border-collapse: collapse;
}
.fixed-table th,
.fixed-table td {
padding: 8px;
border: 1px solid #ddd;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.fixed-table th:last-child,
.fixed-table td :last-child {
white-space: normal; /* позволяем перенос в последнем столбце */
}
Почему это работает
Алгоритм fixed использует только первую строку (или <colgroup>) для опре-
деления ширины столбцов. После установки этих ширин они не изменяются,
независимо от содержимого последующих строк. Это создает предсказуемое по-
ведение и улучшает производительность, так как браузеру не нужно пересчиты-
вать размеры при добавлении новых строк.
Вычисления выполняются пп формуле:
• Столбцы с заданной шириной получают точно указанное значение.
• Столбцы без заданной ширины равномерно делят оставшееся про-
странство.
• Если сумма заданных ширин превышает ширину таблицы, применяется
пропорциональное масштабирование.
Гибридный подход с Container Queries
Определение, современная техника, объединяющая табличную модель с кон-
тейнерными запросами для создания по-настоящему адаптивных табличных
интерфейсов.
Следует применять для таблиц, которые должны адаптироваться не только
к размеру экрана, но и к размеру родительского контейнера:
<div class="table-container >
<table class="adaptive-table">
<thead>
<tr>
<th class= col~primary">Ha3BaHne</th>
<th class="col-secondary">KaTeropnA</th>
<th class='col-tertiary">flaTa</th>
<th class= col-actions">flencTBMB</th>
</tr>
</thead>
<tbody>
<tr>
<td class=' col-primary' ^Важный документ с длинным названием<ЛЬ>
<td class= col-secondary' >Документы</хЬ>
<td class="col-tertiary‘>15.08.2024</td>
<td class= col-actions">
<button>PeflaKTnpoBaTb</button>
<button>yflannTb</button»
</td>
</tr>
</tbody>
</table>
</div>
.table-container {
container-type: inline-size;
container-name: table-wrapper;
width: 100%;
}
.adaptive-table {
width: 100%;
table-layout: auto;
border-collapse: collapse;
}
/* Базовые стили для широких контейнеров */
.adaptive-table th,
.adaptive-table td {
padding. 12px 8px;
border-bottom: Ipx solid #e0e0e@;
text-align: left;
}
/* Адаптация для средних размеров */
©container table-wrapper (max-width: 600px) {
.adaptive-table {
table-layout: fixed;
}
.col-secondary,
.col-tertiary {
display: none;
}
.col-primary {
width: 70%;
}
.col-actions {
width: 30%;
}
/* Адаптация для малых размеров */
©container table-wrapper (max-width: 4P8px) {
. adaptive-table,
.adaptive-table thead,
.adaptive-table tbody,
.adaptive-table tr,
.adaptive-table th,
.adaptive-table td {
display: block;
}
.adaptive-table thead {
display: none;
}
.adaptive-table tr {
margin-bottom: 16px;
padding: 12px;
border: Ipx solid #ddd;
border-radius: 4px;
}
.adaptive-table td::before {
content: attr(data-label) ": "
font-weight: bold;
}
}
Почему это работает
Container Queries позволяют таблице реагировать па размер ее прямого кон-
тейнера, а не всего viewport. Это создает более точный контроль над адаптив-
ностью. При широком контейнере используется table-layout: auto для
оптимального распределения пространства. При сужении контейнера пере-
ключаемся на fixed и скрываем менее важные столбцы. При критически ма-
лых размерах полностью меняем структуру отображения с табличной на блоч-
ную.
Браузер создает новый контекст для контейнерных запросов благода-
ря container-type: inline-size, что позволяет отслеживать изменения ши-
рины контейнера и применять соответствующие стили независимо от размеров
viewport.
Современные возможности CSS
Каскадные слои для организации табличных стилей
Табличные стили часто имеют высокую специфичность из-за селекторов
типа table th td. Каскадные слои помогают управлять этим:
©layer table-base, table-components, table-utilities;
©layer table-base {
table {
border-collapse: collapse;
width: 100%;
}
th, td {
padding: 8px;
text-align: left;
}
}
©layer table-components {
.data-table {
table-layout: fixed;
}
.data-table th {
background: var(--header-bg, #f5f5f5);
font-weight: 600;
}
}
©layer table-utilities {
.text-right { text-align: right ’important; }
.text-center { text-align: center Iimportant; }
}
Селектор :has() для контекстной стилизации
/* Подсветка строк с определенным содержимым */
tr:has(.status-error) {
background-color: #fff5f5;
border-left: 3px solid #e53e3e;
}
/* Адаптация таблицы при наличии действий */
table:has(.actions-cclumn) .main-content {
width: calc(100% - 120px);
}
/* Стилизация ячеек в зависимости от соседних */
td:has(+ td .priority-high) {
font-weight: bold;
}
Логические свойства для интернационализации
.table-responsive {
writing-mode: horizontal-tb;
direction: Itr; /* или rtl */
}
.table-cell {
padding-inline-start: 12px;
padding-inline-end: 8px;
padding-block: 10px;
text-align: start; /* вместо left */
border-inline-end: 1px solid #ddd;
}
/* Адаптация для вертикального письма */
©supports (writing-mode: vertical-rl) {
.vertical-table {
writing-mode: vertical-rl;
}
.vertical-table th,
.vertical-table td {
block-size: auto;
inline-size: 120px;
}
}
Современные функции для динамических размеров
.responsive-table {
/* Адаптивная высота с учетом viewport */
block-size: clamp(300px, 50vh, 600px);
/* Dynamic viewport units для мобильных устройств */
max-block-size: calc(100dvh - env(safe-area-inset-top) - env(safe-
area-inset-bottom) - 120px);
}
.adaptive-column {
/* Математические функции для точных зычислений */
inline-size: max(120px, min(25%, 200px));
/* Экспериментальная поддержка тригонометрических функций ★/
/* transform: rotate(calc(45deg * sin(var(--rotation-factor)))); */
}
Современные цветовые пространства
.modern-table {
--header-bg: oklch(0.95 0.02 240);
--row-hover: oklch(098 0,01 240);
--border-color: oklch(0.9 0.005 240);
/* Относительный синтаксис цвета (экспериментально) */
--accent-color: oklch(from var(--header-bg) calc(l - 0.1) c h);
}
©media (prefers-color-scheme: dark) {
.modern-table {
- -header-bg: oklch(0.15 0.92 240);
- -row-hover: oklch(0.12 0.01 240);
- -border-color: oklch(n,25 О 0И5 240);
}
}
/* Адаптация к предпочтениям пользователя по контрасту */
©media (prefers-contrast: high) {
.modern-table {
--border-color: oklch(0.1 0.01 240);
border-width: 2px;
}
}
Производительность
Стоимость селекторов в табличном контексте
Табличные селекторы имеют особую специфику влияния на производитель-
ность:
/* Дорогие селекторы - избегайте ★/
table tr:nth-child(even) td :first-child + td {
/* Требует обхода множества узлов */
}
/* Эффективная альтернатива */
.table-row-even .second-column (
/* Прямое обращение по классу */
}
/* Очень дорого для больших таблиц */
table tbody tr:hover td {
background: #f5f5f5;
}
/* Более эффективно c CSS containment */
.table-row {
contain: style;
}
.table-row:hover {
background: #f5f5f5;
}
Создание слоев компоновки для анимаций
.animated-row {
/* Принудительное создание слоя композитинга */
will-change: transform, opacity;
transform: translateZ(0); /* hack для создания слоя */
}
.animated-rowzhover {
transform: translateY(-2px);
transition: transform 0.2s ease-out;
}
/* После анимации убираем will-change */
.animated-row.animation-complete {
will-change: auto;
}
Оптимизация перерисовки
.performance-table {
/* Создаем контекст содержания */
contain: layout style paint;
}
.performance-table tbody {
/* Ограничиваем область перерисовки */
contain: layout paint;
}
/* Избегаем дорогих свойств в больших таблицах */
.large-table td {
/* box-shadow может вызывать репаинт всей таблицы */
/* box-shadow: 0 1рх Зрх rgba(0,0,п,0.1); */
/* Используем border для имитации тени ★/
border-bottom: 1рх solid rgba(0,0,0,0.1);
}
Доступность(ally)
Семантическая разметка и навигация
<table class="accessible-table role="table" aria-label= "Список
задач ">
<сар1юп>Активные задачи проекта (обновлено 30 08,2025)</caption>
<thead>
<tr role="row">
<th role="columnheader‘' scope='col' aria-sort="ascending">
<button class=' sort-button" апа-1аЬе1='Сортировать по назва-
НиЮ">
Название
<span ana-hidden='true">t</span>
</button>
</th>
<th role=“columnheader" зсоре='‘со1">Приоритет</1Ь>
<th role="columnheader' scope='со1">Действия</1Н>
</tr>
</thead>
<tbody>
<tr role="row">
<td го1е="дг1Ьсе11">Реализовать новую функциональность<ЛЬ>
<td role="gridcell'>
<span class="pnority priority-high аг1а-1аЬе1="Высокий прио-
ритет'^
Высокий
</span>
</td>
<td role="gridcell">
<button аг1а-1аЬе1="Редактировать задачу: Реализовать новую
функциональность >
Редактировать
</button>
</td>
</tr>
</tbody>
</table>
Стили фокуса и навигации
.accessible-table {
/* Обеспечиваем видимость границ таблицы для программ чтения с экра-
на */
border: 1рх solid #ddd;
}
/* Управление фокусом */
.accessible-table th button:focus-visible,
.accessible-table td button:focus-visible {
outline: 2px solid #005fcc;
outline-offset: 2px;
border-radius: 2px;
}
/* Подсветка строки при фокусе элемента внутри */
.accessible-table tr:focus-within {
background-color: #f0f7ff;
outline: 2px solid #005fcc;
outline-offset: -2px;
}
/* Адаптация к предпочтениям пользователя */
©media (prefers-reduced-motion; reduce) {
.accessible-table * {
transition: none !important;
animation: none 1 important;
}
}
/* Обеспечение контраста */
©media (prefers-contrast: high) {
.accessible-table {
border-width: 2px;
border-color: #000;
}
.accessible-table th,
.accessible-table td {
border-width: Ipx;
border-color: #000;
}
}
Адаптивная типографика
.accessible-table {
/* Относительные единицы для масштабируемости */
font-size: clamp(0.875rem, 0.8rem + 0.5vw, Irem);
line-height: 1.5;
}
/* Логические свойства для RTL поддержки */
.accessible-table th,
.accessible-table td {
text-align: start;
padding-inline-start: 1rem;
padding-inline-end' 0.5rem;
}
/* Адаптация к направлению письма */
[dir="rtl"] .accessible-table .numeric-column {
text-align: start; /* в RTL start означает справа */
font-variant-numeric: tabular-nums;
}
Отладка
Техники визуальной отладки
/* Отладочные стили для понимания структуры */
.debug-table * {
outline: 1px solid rgba(255, 0, 6, 0.3);
background: rgba(0, 255, 0, 0.1);
}
.debug-table table { outline-color: blue; }
.debug-table thead { outline-color: green; }
.debug-table tbody { outline-color: orange; }
.debug-table tr { outline-color: purple; }
.debug-table th { outline-color: red; }
.debug-table td { outline-color: yellow; }
/* Визуализация table-layout алгоритма */
.debug-layout-auto::before {
content: "AUTO LAYOUT";
position: absolute;
top: -20px;
left: 0;
font-size: 10px;
color: red;
font-weight: bold;
}
.debug-layout-fixed:rbefore {
content: "FIXED LAYOUT";
position: absolute;
top: -20px;
left: 0;
font-size: 10px;
color: blue;
font-weight: bold;
}
Диагностика специфичности и каскада
/* Временные стили для диагностики специфичности */
.debug-specificity table { background: red ’important; }
.debug-specificity .table { background: blue Iimportant; }
.debug-specificity #specific-table { background: green ’important; }
/* Визуализация унаследованных свойств */
.debug-inheritance * {
border: 1рх dotted currentcolor;
)
.debug-inheritance table {
color: red;
}
.debug-inheritance tbody {
color: blue; /* наследуется ячейками */
}
Методология бинарного поиска проблем
/* Пошаговое отключение стилей для изоляции проблемы */
/* Шаг 1: Отключаем все табличные стили */
.debug-step-1 table,
.debug-step-1 th,
.debug-step-1 td {
all: unset;
display: table;
}
.debug-step-1 th { display: table-cell; }
.debug-step-1 td { display: table-cell; }
/* Шаг 2: Восстанавливаем только базовые стили */
.debug-step-2 table {
border-collapse: separate;
border-spacing: 0;
table-layout: auto;
}
/* Шаг 3: Добавляем стили компонентов */
.debug-step-3 {
/* Постепенно восстанавливаем стили */
}
Распространенные ошибки и антипаттерны
Специфичность и злоупотребление 'important
Проблема: эскалация специфичности в табличных селекторах.
/* ПЛОХО: специфичность становится неуправляемой */
table.data tbody tr.row td.cell {
color: black;
}
table.data tbody tr.row.highlighted id.cell {
color: blue ’important;
}
table.data tbody tr.row.highlighted.important td.cell {
color: red “important;
}
Решение: использование каскадных слоев и методологии ВЕМ.
/* ХОРОШО, управляемая специфичность */
©layer components {
.table__cell {
color: black;
}
.table__cell--highlighted {
color: blue;
}
.table__cell--important {
color: red;
}
}
Утечки z-index и нежелательные контексты наложения
Проблема: неконтролируемое создание stacking context в ячейках.
/* ПЛОХО: создает stacking context без необходимости */
.table-cell {
position: relative;
z-index: 10;
transform: translateZ(0);
}
.dropdown-in-cell {
position: absolute;
z-index: 999; /* не работает как ожидается */
}
Решение: осознанное управление stacking context.
/* ХОРОШО контролируемые контексты */
.table-container {
position: relative;
z-index: 0;
}
.table_cell-with-dropdown { /* Не создаем stacking context без необ-
ходимости */ position: static; }
.table__dropdown { position: fixed; /* или portal pattern */ z-index:
var(--z-dropdown, 1660); }
Схлопывание margin и негативные отступы как костыли
Проблема: использование негативных ma г gin для «исправления» табличной
разметки.
/* ПЛОХО: попытка "исправить" табличную модель */
.broken-table {
margin: -10рх;
}
.broken-table td {
margin: 10px -5px;
padding: 0;
}
Решение: правильное использование табличной модели или альтернатив-
ных подходов.
/* ХОРОШО: корректное использование border-spacing */
.proper-table {
border-collapse: separate;
border-spacing: 10px 5px;
}
/* Или использование современных альтернатив */
.grid-alternative {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 10px;
} '
Переиспользование табличных хаков при доступности
современных решений
Проблема: использование табличной верстки для центрирования и вырав-
нивания.
/* УСТАРЕЛО: табличное центрирование */
.old-centering {
display: table;
width: 1Q0%;
height: lOOvh;
}
.old-centering-cell {
display: table-cell;
vertical-align: middle;
text-align: center;
}
Решение: современные методы Layout.
/* СОВРЕМЕННО: Grid для центрирования */
.modern-centering {
display: grid;
place-items: center;
min-height: I00vh;
}
/* Или Flexbox */
.flex-centering {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
}
Архитектура и масштабирование
Методологии организации табличных стилей
Современный подход к организации табличных компонентов предполагает
использование методологии ITCSS (Inverted Triangle CSS) в сочетании с каскад-
ными слоями:
/* Слой настроек */
©layer settings {
root {
- -table-cell-padding: 0.75rem;
- -table-border-color: #e2e8f0;
- -table-header-bg: #f7fafc;
- -table-stripe-bg: #f9fafb;
- -table-hover-bg: #edf2f7;
}
}
/* Слой инструментов */
©layer tools {
©function table-spacing($multiplier: 1) {
©return calc(var(--table-cell-padding) * #{$multiplier});
}
}
/* Базовый слой */
©layer base {
table {
border-collapse: collapse;
width: 100%;
}
th, td {
text-align: start;
vertical-align: top;
}
}
/* Слой объектов */
©layer objects {
.o-table {
border-collapse: collapse;
width: 100%;
}
.o-table__cell {
padding: var(--table-cell-padding);
}
}
/* Слой компонентов */
©layer components {
.c-data-table {
table-layout: fixed;
border: Ipx solid var(--table-border-color);
}
.c-data-table__header {
background-color: var(--table-header-bg);
font-weight: 600;
position: sticky;
top: 0;
z-index: 10:
}
.c-data-table__row:nth-child(even) {
background-color: var(--table-stripe-bg);
}
.c-data-table__row:hover {
background-color: var(--table-hover-bg);
}
}
/* Слои утилит */
©layer utilities {
.u-table-layout-auto { table-layout: auto ‘important; }
.u-table-layout-fixed { table-layout: fixed ‘important; }
.u-text-numeric {
font-variant-numeric: tabular-nums;
text-align: end;
}
}
Design tokens и кастомные свойства для тематизации
:root {
/* Базовые токены размеров */
--table-cell-padding-xs: 0.25rem;
--table-cell-padding-sm: 0.5rem;
--table-cell-padding-md: 0.75rem;
--table-cell-padding-lg; 1rem;
--table-cell-padding-xl: 1,25rem;
/* Цветовые токены */
--table-color-border: oklch(0.9 S.005 240);
--table-color-header: oklch(0.97 0.01 240);
--table-color-stripe: oklch(0.99 0.005 240);
--table-color-hover: oklch(0.95 0.01 240);
--table-color-focus: oklch(0.7 0.15 240);
/* Типографические токены */
--table-font-size-sm: 0.875rem;
--table-font-size-md: 1rem;
--table-font-size-lg: 1.125rem;
--table-line-height: 1.5;
}
/* Темная тема */
©media (prefers-color-scheme: dark) {
:root {
--table-color-border: oklch(0.2 0.005 240);
--table-color-header: oklch(0 12 0.01 240);
—table-color-stripe: oklch(0.08 0.005 240);
--table-color-hover: oklchl.0.15 0.01 240);
--table-color-focus: oklch(0.4 0.15 240);
}
}
/* Стратегии скопинга */
.theme-corporate {
--table-color-header: oklch(0.95 0.02 210);
--table-color-focus: oklch(0.6 0.2 210);
}
.theme-brand {
--table-color-header: oklch(0.95 0.02 30);
--table-color-focus: oklch(0.6 0.2 30);
}
/* Компонентный скопинг */
.c-financlal-table {
--table-font-variant-numeric: tabular-nums;
--table-text-align-numeric: end;
}
.c-financial-table .numeric-cell {
font-variant-numeric: var(--table-font-variant-numeric);
text-align: var(--table-text-align-numeric);
}
Паттерны композиции и переиспользования
/* Базовый миксин для табличных компонентов */
%table-base {
border-collapse: collapse;
width: 100%;
font-variant-numeric: normal;
}
%table-responsive {
container-type: inline-size;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
/* Композитные классы */
.c-admin-table {
©extend %table-base;
©extend %table-responsive;
table-layout: fixed;
font-size: var(--table-font-size-sm);
}
.c-report-table {
©extend %table-base;
table-layout: auto;
font-size: var(--table-font-size-md);
.numeric-column {
font-variant-numeric: tabular-nums;
text-align: end;
}
}
/* Модификаторы */
.c-data-table--compact {
--table-cell-padding: var(--table-cell-padding-sm);
font-size: var(--table-font-size-sm);
}
.c-data table--spacious {
--table-cell-padding: var(--table-cell-padding-xl);
font-size: var(--table-font-size-lg);
}
.c-data-table--striped {
.c-data-table__row:nth-child(even) {
background-color: var(--table-color-stripe);
}
}
Совместимость браузеров
Функциональность Chrome Firefox Safari Edge IE Примечания
table-layout 14+ 1+ 1+ 12+ 5+ Полная поддержка
border-collapse 1+ 1+ 1.2+ 12+ 5+ Различия в ренде- ринге границ
Container Queries 105+ 110+ 16+ 105+ 15.4+ 105+ X Требует полифилла для старых версий
:has() 105+ 121+ X Прогрессивное улуч- шение
Нативная поддержка, полифилл доступен
CSS Nesting 112+ 117+ 16.5+ 112+ X
@layer 99+ 97+ 15.4+ 99+ X Критично для боль- ших проектов
oklch() 111+ 113+ 15.4+ 111+ X Fallback на rgbO обя- зателен
dvh/lvh/svh 108+ 101+ 15.4+ 108+ X Fallback на vh реко- мендуется
Фу hki щональио сть Chrome Firefox Safari Edge IE Примечания
prefers-contrast 96+ 101 + 14.1+ 15.4+ 96+ X Прогрессивное улуч- шение
focus-visible 8G+ 85+ J 86+ k J X Полифилл доступен
env() 69+ X 11.1+ 79+ X Критично для мо- бильной верстки
clamp() 79+ 75+ 13.1+ 79+ X Fallback с min/max
Субгриды X 71+ 16+ X X Экст гери м ентальная функция
Стратегии fallback и прогрессивного улучшения
/* Базовые fallback для Container Queries */
.table-container {
/* Fallback: используем медиазапросы */
overflow-х: auto;
}
©media (max-width: бййрх) {
.adaptive-table .secondary-column {
display: none;
}
}
/* Прогрессивное улучшение при поддержке Container Queries ★/
©supports (container-type: inline-size) {
.table-container {
container-type: inline-size;
}
©container (max-width: 606px) {
.adaptive-table .secondary-column {
display: none;
}
}
}
/* Fallback для современных цветов */
.modern-table {
--header-bg: #f7fafc; /* RGB fallback */
--header-bg: oklch(0.97 0.01 240); /* Современный формат */
}
/* Fallback для viewport units */
.table-wrapper {
height: 50vh; /* Fallback */
height: 50dvh; /* Прогрессивное улучшение */
}
/* Прогрессивное улучшение с :has() */
.table-row {
/* Базовые стили */
}
©supports selector(:has(*)) {
.table-row:has(.error-indicator) {
background-color: #fff5f5;
}
}
Практические упражнения
Упражнение 1. Адаптивная таблица данных (средняя
сложность)
Задача: создайте адаптивную таблицу для отображения списка сотрудников,
которая корректно работает на всех размерах экрана.
Требования:
• Минимум пять столбцов: ФИО, Должность, Отдел, Телефон, Email.
• На экранах шире 800рх показывать все столбцы.
• На экранах 400-800рх скрывать столбцы Email и Телефон.
• На экранах уже 400рх переключиться на карточную верстку.
• Обеспечить доступность и поддержку клавиатурной навигации.
Условия выполнения:
• Таблица корректно адаптируется под размер контейнера.
♦ Сохраняется читаемость на всех размерах экрана.
• Присутствуют все необходимые ARlA-атрибуты.
• Стили фокуса соответствуют стандартам доступности.
Подсказки:
• Используйте Container Queries, если поддерживается.
• Примените логические свойства для международной поддержки.
♦ Измерьте производительность в DevTools при большом количестве строк.
Упражнение 2. Сложная финансовая таблица (высокая
сложность)
Задача: реализуйте таблицу финансовых данных с возможностью сортиров-
ки, группировки и фиксированными заголовками.
Требования:
• Фиксированная шапка при прокрутке.
• Числовые данные выровнены по правому краю с табличными цифрами.
• Возможность группировки строк (сворачивание/разворачивание).
• Подсветка отрицательных значений красным цветом.
• Итоговая строка с суммами.
Условия выполнения:
• Шапка остается видимой при вертикальной прокрутке.
• Группировка работает без JavaScript (используя details/summary).
• Числа корректно выравниваются и форматируются.
• Производительность остается приемлемой при 1000+ строк.
Подсказки:
• Используйте position: sticky для фиксации заголовков.
• Примените font-variant-numeric: tabular-nums.
• Создайте stacking context для правильного z-index.
• Используйте CSS containment для оптимизации.
Упражнение 3. Табличный дашборд (высокая сложность)
Задача: создайте дашборд с несколькими связанными таблицами, которые
реагируют на изменение размера общего контейнера.
Требования:
• Три таблицы в одном контейнере (2+1 компоновка).
• Каждая таблица адаптируется независимо.
• Общая тематизация через CSS custom properties.
• Темная и светлая темы.
• Респект к пользовательским предпочтениям (prefers-reduced-motion,
prefers-contrast).
Условия выполнения:
• Таблицы корректно перестраиваются при изменении размера конгейнера.
• Темы переключаются корректно.
• Анимации отключаются при prefers-reduced-motion: reduce.
• Код организован по методологии ITCSS с каскадными слоями.
Подсказки:
• Используйте CSS Grid для общей компоновки.
• Примените Container Queries для адаптации каждой таблицы.
• Создайте систему design tokens.
• Измерьте влияние на Core Web Vitals.
Заключение
Табличная верстка в современной веб-разработке представляет собой мощ-
ный, но специализированный инструмент, требующий глубокого понимания
алгоритмов компоновки браузера. Основные техники, которые можно безопас-
но применять в продакшене уже сегодня, включают правильное использова-
ние table-layout для контроля производительности, семантическую разметку
для обеспечения доступности и интеграцию с современными CSS-возможностя-
ми через прогрессивное улучшение.
Что следует внедрять в продакшен немедленно:
• Корректное использование table-layout: fixed для больших таблиц
(>100 строк).
• Сем антическую разметку с ARIA-атрибутами для программ чтения
с экрана.
• Каскадные слои для организации табличных стилей в больших проектах.
• CSS Containment для оптимизации производительности.
Что использовать с осторожностью:
♦ Container Queries (требуют fallback для IE и старых браузеров).
* Современные цветовые пространства oklch/lch (обязательны RGB
fallback).
• Селектор :has() (прогрессивное улучшение обязательно).
• Viewport units dvh/lvh/svh (критично тестировать на мобильных
устройствах).
Стратегии безопасного внедрения в крупных кодовых базах:
• Начинайте с создания isolated компонентов, использующих
каскадные слои для предотвращения конфликтов стилей. Применяйте
feature queries ©supports для прогрессивного улучшения. Создайте
всестороннюю систему design tokens для табличных компонентов,
обеспечивающую консистентность и возможность тематизации.
• Особое внимание уделите производительности: табличная модель
может стать узким местом при работе с большими объемами данных.
Используйте CSS Containment, избегайте сложных селекторов с nth-child
и рассмотрите виртуализацию для экстремально больших таблиц.
* Доступность должна быть приоритетом: корректная семантическая
разметка, управление фокусом и респект к пользовательским
предпочтениям критически важны для создания инклюзивных
интерфейсов. Современные возможности CSS предоставляют мощные
инструменты для адаптации к потребностям пользователей без ущерба
для дизайна.
Помните: табличная верстка — это не устаревшая технология, а специализи-
рованный инструмент для конкретных задач. Правильное применение этих зна-
ний позволит создавать производительные, доступные и «ремонтопригодные»
интерфейсы для работы с табличными данными.
Углубленное чтение
CSS Table Layout Algorithm (W3C CSS 2.1 Specification) —
https://www.w3.org/TR/CSS21/tables.html.
MDN: CSS Table concepts and layout — https://developer.
mozilla.org/en-US/docs/Web/CSS/CSS_Table.
CSS Containment Module Level 1 (W3C) — https://www.w3.org/
TR/css-contain-1/.
CSS Container Queries Module Level 1 (W3C) — https://www.
w3.org/TR/css-contain-3/.
Глава 4. Цвет и современные техники
стилизации
Цвет в веб-разработке — не просто эстетический инструмент, это мощная си-
стема коммуникации, которая влияет на пользовательский опыт, доступность
и производительность приложений. Данная глава исследует глубинные меха-
низмы работы с цветом в CSS, от фундаментальных принципов цветовых про-
странств до современных возможностей CSS Color Module Level 4 и новых еди-
ниц измерения.
В отличие от поверхностных руководств по подбору цветовых схем, мы сосре-
доточимся на технических аспектах: изучим, как браузеры обрабатывают цве-
та, рассмотрим влияние различных цветовых функций на производительность
рендеринга, стратегии управления цветом в масштабируемых системах дизай-
на и интеграцию современных возможностей CSS, таких как каскадные слои (@
layer), контейнерные запросы и логические свойства.
Техники, представленные здесь, применимы в продакшен-системах любого
масштаба — от простых landing pages до сложных веб-приложений с динами-
ческими темами, поддержкой темного режима и адаптацией к предпочтениям
пользователей п<) доступности.
Цветовые пространства и рендеринг
Современные браузеры поддерживают несколько цветовых пространств:
sRGB — стандартное цветовое пространство для веба (цветовой охват -35%
видимого спектра)
Display РЗ — расширенное пространство для современных дисплеев (-45%
видимого спектра)
Rec2020 — пространство для HDR-контеита (-75% видимого спектра)
Этапы рендеринга цвета
Layout (Reflow) — вычисление позиций элементов
Paint — растеризация цветов и текстур
Composite — объединение слоев с учетом z-inoex, opacity, blend-mode
Быстрый пример
Рассмотрим базовую систему цветовых токенов с поддержкой темных тем:
CSS
:root {
/* Семантические цветовые токены */
--color-text-primary: oklch(20% 0 0);
--color-text-secondary: oklch(40% б 0);
--color-surface-primary: oklch(98% 0 0);
--color-accent: oklch(60% 0.15 220);
}
©media (prefers-color-scheme: dark) {
:root {
--color-text-primary: oklch(90% 0 0);
--color-text-secondary: oklch(70% 0 0);
--color-surface-primary: oklch(15% 0 0);
--color-accent: oklch(70% 0.15 220);
}
}
.card {
background-color: var(--color-surface-primary);
color: var(--color-text-primary);
border: 1px solid var(--color-accent);
}
html
<div class="card">
<И2>Заголовок карточки</Ь2>
<р>Текст с автоматической адаптацией к темной теме</р>
</div>
Почему это работает
Браузер сначала разрешает значения custom prope г ties в : root, затем при-
меняет медиазапрос ©media (prefers-color-scheme: dark), перезаписывая то-
кены при соответствующих системных настройках пользователя. oklch() обе-
спечивает перцептивно равномерную интерполяцию между светлой и темной
темами.
Основные техники и паттерны
Управление прозрачностью без цветовых конфликтов
Проблема: использование серых цветов (#ссс) вместо прозрачных черных
(rgba) создает визуальные конфликты на цветных фонах.
CSS
/* Неправильно - фиксированный серый цвет */
.shadow-bad {
box-shadow: 0 4рх 8рх #сссссс;
}
/* Правильно - прозрачный черный */
.shadow-good {
box-shadow: 0 4рх 8рх rgba(0, 0, 0, 0.15);
}
/* Современный подход с относительными цветами */
.shadow-modern {
box-shadow: 0 4рх 8рх rgb(from black г g b / 0.15);
}
html
<div style= background: linear-gradient(45deg, #ff6b6b, #4ecdc4);
padding: 2rem;">
<div class="shadow-bad" style="background: white; padding: 1rem;
margin: 1rem;">
Серая тень конфликтует с фоном
</div>
<div class="shadow-good" style= background: white; padding: 1rem;
margin: 1rem;">
Прозрачная тень адаптируется к фону
</div>
</div>
Почему это работает
rgba (0, 0, 0, 0.15) создает реальную полупрозрачность, позволяя базово-
му цвету проходить через слой тени. Браузер выполняет alpha-blending в про-
цессе композитинга, смешивая цвета математически корректно.
Семантическая система цветов
:root {
/* Базовая палитра */
-blue-50: oklch(95% 0.02 220);
-blue-500: oklch(60% G.15 220);
--blue-900: oklch(25% 0.10 220);
/* Семантические токены */
--color-primary: var(--blue-500);
--color-success: oklch(65% 0.15 140);
--color-warning: oklch(70% 0.15 80);
--color-danger: oklch(60% 0.18 30);
/* Статусные цвета (Bootstrap-совместимые) */
--bs-primary: #0d6efd;
--bs-success: #198754;
--bs-info: #0dcaf0;
--bs-warning: #ffc107;
--bs-danger: #dc3545;
}
/* Адаптивные статусные компоненты */
.alert {
padding: 0.75rem 1rem;
border: 1px solid;
border-radius: 0.375rem;
}
.alert-success {
background-color: rgb(from var(--color-success) r g b / 0.1);
border-color: var(--color-success);
color: rgb(from var(--color-success) calc(r * 0.3) calc(g * 0.3)
calc(b * 0.3));
}
Почему это работает
Семантические токены создают уровень абстракции между ди зайн-системой
и компонентами. oklch() обеспечивает предсказуемую яркость, а относитель-
ный синтаксис rgb(f rom color ...) позволяет генерировать вариации без ду-
блирования значений.
Контрастные пары и доступность
/* Функция для автоматического контраста */
.adaptive-text {
--bg-lightness: 50%;
background-color: oklch(var(--bg-lightness) 0.1 280);
color: oklch(calc(100% - var(--bg-lightness)) 0 0);
}
/* Контейнер с автоматической адаптацией */
.theme-container {
--primary-hue: 220;
--primary-chroma: 0.15;
background-color: oklch(15% var(--pnmary-chroma) var(--primary-
hue));
color: oklch(90% 0 0);
}
@container style(--theme: light) {
.theme-container {
background-color: oklch(95% var(--primary-chroma) var(--primary-
hue) );
color: oklch(20% 00);
}
}
Почему это работает
oklch() позволяет манипулировать яркостью независимо от оттенка
и цветности. Са1с() в цветовых функциях создает математически точные ин-
версии яркости, обеспечивающие достаточный контраст.
Современные возможности CSS
Каскадные слои для цветовых систем
/* Базовый слой - токены дизайн-системы */
©layer tokens {
:root {
--color-neutral-50: oklch(98% 0 0);
--color-neutral-900: oklch(i5% 0 0);
--color-brand-primary: oklch(55% 0.15 250);
}
}
/* Слой компонентов ★/
©layer components {
.btn {
background-color: var(--color-brand-primary);
color: var(--color-neutral-50);
}
.btn-secondary {
background-color: transparent;
color: var(—color-brand-primary);
border: 2рх solid var(--color-brand-primary);
}
}
/* Слой утилит - самый высокий приоритет */
©layer utilities {
.text-primary { color: var(--color-brand-primary) ’important; }
.bg-primary { background-color: var(—color-brand-primary) !important; }
}
Почему это работает
©layer создает управляемую иерархию каскада, где utilities всегда пере-
крывают components, независимо от специфичности селекторов. Это решает
проблему «войны специфичности» в масштабных системах.
Контейнерные запросы для адаптивных цветовых схем
.card-container {
container-type; inline-size;
container-name: card;
}
.card {
background: var(--color-neutral-50);
color: var(--color-neutral-900);
padding: 1rem;
}
/* Изменение цветовой схемы в зависимости от размера контейнера */
©container card (min-width: 400рх) {
.card {
background: linear-gradient(135deg,
oklch(95% 0.02 250),
oklch(97% 0.01 250));
box-shadow: 0 4px 20px rgb(from var(--color-brand-primary) r g b
/ 0-1);
}
}
/* Экспериментальные style queries */
©container style(--variant: premium) {
.card {
background: linear-gradient(135deg,
oklch(20% 0.08 45),
oklch(15% 0.12 30));
color: oklch(95% 00);
}
}
Почему это работает
Контейнерные запросы позволяют компонентам адаптироваться к своему
контексту, а не только к размеру вьюпорта. Style queries (эксперименталь-
ные) дают возможность создавать условную стилизацию на основе CSS custom
properties.
Новые цветовые функции и пространства
/* Современные цветовые функции */
.color-modern {
/* oklch - перцептивно равномерное пространство */
background. oklch(65% 0.15 180);
/* Ich - альтернатива oklch с другой яркостной функцией */
border-color: lch(50% 40 180);
/* Относительные цвета - генерация вариаций */
--base-color: oklch(60% 0.12 240);
— lighter: oklch(from var(--base-color) calc(l + 20%) c h);
- darker: oklch(from var(--base-color) calc(l - 20%) c h);
- -desaturated: oklch(from var(--base-color) 1 calc(c * 0.5) h);
/* HDR-готовые цвета для wide-gamut дисплеев */
- -hdr-red: color(display-p3 1 80);
--hdr-green: color(rec2020 01 0);
}
/* Прогрессивное улучшение для старых браузеров */
.progressive-color {
/* Fallback для старых браузеров */
color: #3366сс;
/* Современная цветовая функция */
color: oklch(55% 0.15 250);
/* Для HDR-дисплеев */
color: color(display-p3 0.2 0.4 0.8);
}
Почему это работает
oklch() и lch() обеспечивают перцептивно равномерную интерполяцию —
изменение яркости на постоянную величину дает визуально равномерные шаги
яркости. Относительный синтаксис позволяет создавать математические вариа-
ции базового цвета без пересчета значений вручную.
Логические свойства для интернационализации
.internationalized-card {
/* Логические цветовые свойства */
border-inline-start: 4рх solid var(--color-accent);
border-inline-end: ipx solid var(--color-border);
/* Градиенты с логическими направлениями */
background: linear-gradient(to inline-end,
oklch(95% 0.02 220),
oklch(98% 0.01 220));
/* Тени с учетом направления письма */
box-shadow: 0 25rem 0 1 rem rgb(from black r g b / 0.1);
}
/* RTL-адаптация через логические свойства */
[dir="rtl“] .internationalized-card {
/* Автоматическая адаптация благодаря логическим свойствам */
/* border-inline-start станет border-right */
/* linear-gradient изменит направление */
}
Почему это работает
Логические свойства автоматически адаптируются к направлению письма
и режиму письма (horizontal/vertical). inline-start в LTR-языках означает
left, в RTL — right.
Производительность
Оптимизация селекторов и инвалидация
/* Медленно - сложный селектор с цветовыми вычислениями */
.container .card:nth-child(even) .title:hover {
color: oklch(from var(--base-color) calc(l + ’0%) c calc(h + 30deg));
}
/* Быстро - простой класс с лредвычисленными значениями */
.card-title-hover {
color: var(--color-title-hover);
}
/* Оптимизация через CSS containment */
.card-optimized {
contain: style layout;
color: var(--col.jr-text);
background: var(--color-bg);
}
Почему это работает
Сложные селекторы и цветовые вычисления в реальном времени замедляют
рендеринг. CSS containment ограничивает область инвалидации при изменении
стилей, ускоряя перерендеринг.
GPU-композитинг и стекинг
gpu-optimized-color-transition {
/* Принудительное создание слоя композитинга */
will-change: background-color;
/* Эффективные для GPU трансформации цвета */
background: var(--color-base);
transition: background-color 0.3s ease-out;
}
.gpu-optimized-color-transition:hover {
background: var(--color-hover);
}
/* Альтернатива через opacity для лучшей производительности */
.overlay-color-change {
position: relative;
background: var(--color-base);
}
.overlay-color-change::after {
content: '';
position: absolute;
inset: 0;
background: var(--color-overlay);
opacity: 0;
transition: opacity 0.3s ease-out;
pointer-events: none;
}
.overlay-color-change:hover::after {
opacity: 1;
}
Почему это работает
will-change: background-color сообщает браузеру о предстоящих измене-
ниях, создавая композитный слот! заранее. Альтернатива с opacity использует
более эффективный для GPU канал прозрачности вместо перерисовки цвета.
Оптимизация градиентов и фильтров
/* CPU-интенсивные эффекты */
.heavy-effects {
background:
radial-gradient(circle at 20% 20%, oklch(60% 0.15 240) 0%,
transparent 50%),
radial-gradient(circle at 80% 80%, oklch(60% 0.15 300) 0%,
transparent 50%),
linear-gradient(135deg, oklch(95% 0.02 220), oklch(85% 0.05 240));
filter:
blur(0.5px)
drop-shadow(ki 4px 20px rgb(from var(--color-shadow) r g b / 0.2));
}
/* Оптимизированная альтернатива */
.optimized-effects {
background: var(--optimized gradient);
box-shadow: 0 4px 20px var(--optimized-shadow);
}
:root {
/* Преднычисленные значения */
--optimized-gradient: linear-gradient(135deg, #f9f4ff, #e1ecff);
--optimized-shadow: rgba(66, 139, 202, 0.15);
}
Почему это работает
Сложные градиенты и фильтры вызывают дорогое операции растеризации.
Предвычисление значений и минимизация слоев эффектов снижает нагрузку
на GPU/CPU.
Доступность
Контраст и цветовые предпочтения пользователя
/* Базовые контрастные пары */
.accessible-text {
/* WCAG АА: минимум 4.5:1 для обычного текста */
background: oklch(95% 0 02 220);
color: oklch(25% 0 0); /* Коэффициент контраста -7.2:1 */
}
.accessible-large-text {
/* WCAG АА: минимум 3:1 для крупного текста (18pt+) */
font-size: 1.25reni;
font-weight: 600;
background: oklch(90% 0.05 200);
color: oklch(35% 0 0); /* Коэффициент контраста -4.1:1 */
}
/* Адаптация к предпочтениям пользователя */
©media (prefers-contrast: high) {
.accessible-text {
background: oklch(100% 0 0);
color: oklch(0% 00);
border: 2px solid oklch(50% 0 0);
}
}
©media (prefers-contrast: low) {
.accessible-text {
background: oklch(92% 0.01 220);
color: oklch(40% 0 0);
}
}
/* Респект к предпочтению уменьшенного движения */
©media (prefers-reduced-motion: reduce) {
.color-transition {
transition: none;
}
}
©media (prefers-reduced-motion: no-preference) {
.color-transition {
transition: background-color 0.2s ease-out, color 0.2s ease-out;
}
}
Почему это работает
oklch () позволяет точно контролировать яркость для достижения требуемо-
го контраста. Медиазапросы prefers-* дают пользователям контроль над визу-
альным опытом согласно их потребностям.
Цветонезависимая индикация
/* Проблема - только цветовая индикация */
.status-bad {
color: #dc3545; /* Красный для ошибок */
}
.status-good {
color: #198754; /* Зеленый для успеха */
}
/* Решение - дополнительные визуальные индикаторы */
.status-enhanced {
position: relative;
padding-left: 1.5rem;
}
.status-enhanced::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateV(-50%);
width: Irem;
height: Irem;
border-radius. 50%;
}
.status-error {
color: oklch(50% 0.15 30);
}
.status-error::before {
background: radial-gradient(circle, currentcolor 30%, transparent
30%);
background-size: 3px 3px;
background-color: currentcolor;
}
.status-success {
color: oklch(50% 0.15 140);
}
.status-success::before {
background:
linear-gradient(45deg, transparent 35%, currentcolor 35%,
currentcolor 50%, transparent 50%),
linear-gradient(-45deg, transparent 35%, currentcolor 35%,
currentColor 50%, transparent 50%);
background-size: 6px 6px;
background-position: center;
}
Почему это работает
Дополнительные паттерны и формы обеспечивают получение информации
независимо от цветового восприятия. currentColor наследует цвет текста, под-
держивая единообразие при изменении цветовых схем.
Отладка
DevTools и инструменты диагностики
/* Отладочные утилиты для цветовой системы */
.debug-colors * {
outline: 1рх solid hsl(calc(var(--debug-hue, 0) + 120deg * var(--
debug-index, 0)) 70% 50%);
outline-offset: -Ipx;
}
/* Визуализация наследования цветов */
.debug-inheritance {
--debug-color: currentColor;
border: 2px dashed var(--debug-color);
}
.debug-inheritance * {
--debug-color: inherit;
position: relative;
}
.debug-inheritance *::after {
content: attr(class);
position: absolute;
top: -l.5rem;
left: 0;
font-size: 0.75rem;
background: var(--debug-color);
color: white;
padding: 0.125rem 0.25rem;
border-radius: 2px;
white-space: nowrap;
z-index: 1000;
}
Почему это работает
CSS-переменные и calc() позволяют создавать динамические системы от-
ладки. hsl() с вычисляемым hue генерирует уникальные цвета для каждого
уровня вложенности.
Диагностика проблем специфичности
/* Система диагностики каскада */
.cascade-debug {
/* Базовый цвет - зеленый */
color: green iimportant;
}
.cascade-debug[data-specificity=' id"J {
/* ID селектор - синий */
color: blue iimportant;
}
.cascade-debug.class-selector {
/* Класс - красный */
color: red iimportant;
}
/* Визуальная индикация источника правила */
.cascade-debug::before {
content: Cascade source: " attr(data-source);
display: block;
font-size: £.8em;
opacity: 0.7;
}
Почему это работает
Использование ! important с различными уровнями специфичности помога-
ет выявить, какие правила действительно применяются, data-атрибуты сохраня-
ют информацию об источнике для отладки.
Распространенные ошибки и антипаттерны
Проблемы специфичности
/* АНТИПАТТЕРН: Гонка специфичности */
.btn { color: blue; }
.btn btn-primary { color: red; }
.btn,btn-primary.btn-large { color: green; }
.btn.btn-primary.btn-large.btn-special { color: purple; }
/* РЕШЕНИЕ: Использование каскадных слоев */
©layer base, components, variants, utilities;
©layer base {
.btn { color: var(--color-text); }
}
©layer components {
.btn-primary { color: var(--color-pnmary); }
}
©layer variants {
.btn-large { font-size: 1.25rem; }
}
©layer utilities {
.text-special { color: var(--color-special) ’important; }
}
Злоупотребление 'important
/* АНТИПАТТЕРН: Избыточное использование ’important */
.override-everything {
color: red ’important;
background: blue 'important;
border: Ipx solid green !important;
}
/* РЕШЕНИЕ: Структурированная система приоритетов */
©layer utilities {
.□-color-primary { color: var(--color-primary); }
.u-bg-surface { background: var(—color-surface); }
.u-bcrder-accent { border: 1px solid var(--color-accent); }
}
Архитектура и масштабирование
Организация цветовых токенов
/* Базовый слой - основные (primitive) цвета ★/
©layer primitives {
:root {
/* Нейтральная шкала */
- -neutral-50: oklch(98% 0 0);
- -neutral-160: oklch(95% 0 0);
- -neutral-200: oklch(90% 0 0);
- -neutral-300: oklch(80% 0 0);
- -neutral-400: oklch(65% 0 0);
- -neutral-500: oklch(59% и 0);
- -neutral-600: oklch(40% 0 0);
- -neutral-700: oklch(30% 0 0);
- -neutral-800: oklch(20% 0 0);
- -neutral-900: oklch(10% 0 0);
/★ Цветные шкалы */
- -blue-300: oklch(70% 0.10 220);
- blue-500: oklch(55% 0.15 220);
- blue-700: oklch(40% 0.12 220);
}
}
/* Семантический слой */
©layer semantic {
:root {
- -color-text-primary: var(—neutral-900) ;
- -color-text-secondary: var(—neutral-600);
- -color-surface-primary: var(--neutral-50);
- -color-border-default: var(—neutral-300);
- -color-accent-primary: var(—blue-500);
}
}
/* Компонентный слой */
©layer components {
.button {
background-color: var(--color-accent-primary);
color: var(--color-surface-primary);
border: 1px solid transparent;
}
.button--secondary {
background-color: transparent;
color: var(--color-accent-primary);
border-color: currentColor;
}
}
Темизация и области видимости
/* Глобальная темная тема */
©layer themes {
[data-theme="dark"] {
--color-text-primary: var(--neutral-109);
--color-text-secondary: var(--neutral-400);
--color-surface-primary: var(—neutral-900);
--color-border-default: var(--neutral-700);
}
/* Локальная область с измененной темой */
.theme-scope-light {
--color-text-primary: var(—neutral-900);
--color-text-secondary: var(--neutral-600);
--color-surface-primary: var(--neutral-50);
}
/* Бысококонтрастная тема */
[data-theme=”high-contrast"] {
--color-text-primary: oklch(0% 0 0);
--color-text-secondary: oklch(20% 0 0);
--color-surface-primary: oklch(100% 0 0);
--color-border-default: oklch(0% 0 0);
--color-accent-primary: oklch(30% 0.20 220);
}
}
Интеграция с методологиями CSS
/* ВЕМ с современными CSS-возможностями */
.card {
background: var(--card-bg, var(--color-surface-primary));
color: var(--card-color, var(--color-text-primary));
border: 1px solid var(--card-border, var(--color-border-default));
}
.card--featured {
--card-bg: linear-gradient(135deg,
oklch(from var(--color-accent-primary) calc(l + 10%) calc(c * 0.3)
h).
oklch(from var(—color-accent-primary) calc(l - 5%) calc(c * 0.5)
h));
--card-color: var(--color-surface-primary);
--card-border: transparent;
}
.card__title {
color: inherit; /* Наследует от .card */
font-weight: 600;
}
.card__title--accent {
color: var(--color-accent-primary);
}
/* ITCSS совместимость */
©layer settings, tools, generic, elements, objects, components,
utilities;
©layer settings {
:root { /* Токены дизайн-системы */ }
}
©layer tools {
/* Миксины через ©apply или CSS-переменные */
.focus-ring {
--focus-color: oklch(60% 0.15 220);
--focus-width: 3px;
--focus-offset: 2px;
}
}
©layer utilities {
.u-color-accent { color: var(--color-accent-primary) iimportant; }
.u-bg-surface { background: var(--color-surface-primary) iimportant; }
}
Почему это работает
Каскадные слои решают конфликты специфичности между методологиями. Се-
мантические токены создают единую точку управления цветами во всей системе.
Совместимость браузеров
Функция Chrome Firefox Safari Edge Поддержка Примечания
oklch() 111 + 113+ 15.4+ 111+ Полная Прогрессивное улучшение
lch() 111+ 113+ 15.4+ 111+ Полная Прогрессивное улучшение
colorf) 99+ 100+ 15+ 99+ Полная Display-РЗ с 99+
Относи- тельные цвета 119+ 120+ 16.4+ 119+ Новая Нужны fallbacks
@1ауег 99+ 97+ 15.4+ 99+ Полная -
Container Queries 105+ 110+ 16 + 105+ Полная -
Style Queries 118+ X X 118+ Экспери- мент Только Chromium
:has() 105+ 103+ 15.4+ 105+ Полная -
CSS Nesting 112+ 117+ 16.5+ 112+ Полная -
Cascade Layers в ^import 109+ 104+ 15.4+ 109+ Полная -
prefers- 964 101 + 14.1+ 96+ Полная -
contrast
Функция Chrome Firefox Safari Edge Поддержка Примечания
Логи-
ческие
89+
66+
12.1+ 89+ Полная
Частичная
с G6+/12.1+
свойства
Стратегии прогрессивного улучшения
/* Безопасные fallbacks для новых цветовых функций */
.progressive-enhancement {
/* Базовый fallback */
background: ЯЗЗббсс;
/* Современные браузеры */
background: oklch(55% 0.15 250);
/* HDR-дисплеи */
background’ color(display-p3 0.2 0.4 о.8);
/* Проверка поддержки через ©supports */
©supports (color: oklch(50% 0.1 180)) {
.modern-colors {
--primary: oklch(60% 0 15 220);
--secondary: oklch(from var(--primary) calc(l + 20%) calc(c * 0.7)
h);
©supports not (color: oklch(50% 0.1 180)) {
.modern-colors {
--primary: #3366cc;
--secondary: #6699ff;
Практические упражнения
Упражнение 1. Адаптивная цветовая система
Сложность: средняя
Задача: создайте цветовую систему с поддержкой светлой/темной темы, ав-
томатическим контрастом и респектом к предпочтениям пользователя.
Требования:
• Минимум пять семантических цветовых токенов.
• Автоматическое переключение по prefers-color-scheme.
• Поддержка prefers-contrast: high.
• Коэффициент контраста не менее 4.5:1 для обычного текста.
Условия выполнения:
• Все цвета проходят проверку WCAG ЛА.
• Плавные переходы между темами (где уместно).
• Корректная работа в Chrome DevTools с эмуляцией предпочтений.
Подсказки:
• Используйте oklch() для равномерной интерполяции.
• Тестируйте в DevTools: Rendering Emulate CSS media prefers-color-
scheme.
Упражнение 2. Система статусных индикаторов
Сложность: средняя
Задача: разработайте систему цветовых индикаторов, доступную для людей
с цветовой слепотой.
Требования:
• Четыре статуса: success, warning, error, info.
• Только цветовая индикация недостаточна.
• Дополнительные паттерны/иконки.
• Поддержка высокого контраста.
Условия выполнения:
• Различимость без цветового восприятия.
• Соответствие семантике Bootstrap-статусов.
• Корректная работа в режиме высокого контраста.
Упражнение 3. Производительная анимация цветов
Сложность: высокая
Задача: создайте компонент с цветовыми переходами, оптимизированный
для 60 FPS.
Требования:
• Hover-эффекты на цвете фона.
• Анимация должна использовать GPU.
• Респект к prefers-reduced-motion.
• Измеримая производительность в DevTools.
Условия выполнения:
• 60 TPS в Chrome DevTools Performance.
• Отсутствие layout/paint в анимациях.
• Graceful degradation для медленных устройств.
Подсказки:
• Используйте opacity/transform вместо background-color.
• will-change для предварительной оптимизации.
• DevTools: Rendering - Paint flashing.
Заключение
В наши дни работа с цветом в CSS выходит далеко за рамки простого подбора
приятных сочетаний. Это комплексная система, включающая техническое по-
нимание цветовых пространств, производительность рендеринга, доступность
и масштабируемость архитектуры.
В крупных кодовых базах начинайте с внедрения семантических токенов
и каскадных слоев — это создаст фундамент для постепенного перехода к совре-
менным цветовым функциям без нарушения существующего кода. Измеряйте
влияние изменений на Core Web Vitals и проводите А/В-тестирование критиче-
ских интерфейсных элементов.
Цвет остается одним из самых мощных инструментов в арсенале frontend-раз-
работчика, но теперь у нас есть технологии для его профессионального приме-
нения в проектах любых масштабов.
Углубленное чтение
OKLCH Color Function — подробное руководство CSS-Tricks
с практикумами и сравнением с lch(): https://css-tricks.com/
almanac/functions/o/oklch/.
CSS Color Value — официальная документация MDN
с описанием всех современных цветовых типов и функций:
https://developer.mozilla.org/en-US/docs/Web/CSS/color_value.
Prefers Color Scheme — официальная документация MDN
о медиафичах для цветовых предпочтений пользователей:
https://developer.mozilla.org/en-US/docs/Web/CSS/(&)media/prefers-
color-scheme.
Глава 5. CSS-типографика:
продвинутые техники и современные
возможности
CSS-типографика представляет собой фундаментальный аспект веб-разра-
ботки, определяющий визуальную иерархию, читаемость и пользовательский
опыт интерфейсов. В отличие от традиционной полиграфической типографики,
веб-типографика функционирует в динамической среде с переменными разме-
рами экранов, различными устройствами вывода и интерактивными состояни-
ями элементов.
В данной главе рассматриваются современные техники CSS-типографики, вы-
ходящие за рамки базовых свойств font-family и font-size. Освещаются про-
двинутые возможности каскадных таблиц стилей: логические свойства для мно-
гоязычных интерфейсов, контейнерные запросы для адаптивной типографики,
каскадные слои для организации стилей, а также современные функции и еди-
ницы измерения. Особое внимание уделяется производительности рендеринга,
доступности и методологиям отладки.
Техники, представленные в главе, применимы в производственных системах
дизайна, компонентных библиотеках и крупномасштабных веб-приложениях,
где типографика должна поддерживать согласованность, масштабируемость
и техническую стабильность.
Теория и терминология
Контекст форматирования (formatting context) — область документа, в ко-
торой элементы располагаются согласно определенным правилам. Типы кон-
текстов: блочный (BFC), строчный (IFC), флекс (FFC), грид (GFC).
Контекст наложения (stacking context) — трехмерное представление
HTML-элементов относительно оси Z, определяющее порядок отображения пе-
рекрывающихся элементов.
Этапы рендеринга типографики
Браузер обрабатывает типографические стили в следующей последователь-
ности:
Layout (Reflow) — вычисление геометрических параметров текстовых бло-
ков
Paint — растеризация глифов и применение эффектов
Composite — композиция слоев с аппаратным ускорением
Понимание данной последовательности критично для оптимизации произ-
водительности типографических анимаций и эффектов.
Быстрый пример
Рассмотрим базовую реализацию адаптивной типографической системы
с использованием современных CSS-возможностей:
html
«article class="content">
<h1 class='heading-primary">3aronoBOK статьи</Ь1>
<p class="text-body‘‘>
Основной текст статьи с оптимальной длиной строки
и контрастностью для комфортного чтения.
</р>
«/article^
css
.content {
container-type: inline-size;
container-name: article;
max-inline-size: 65ch;
margin-inline: auto;
}
.heading-primary {
font-size: clamp(1.5rem, 4vw + 1rem, 3rem);
font-weight: 700;
line-height: 1.2;
letter-spacing: -0.02em;
color: oklch(20% 0.05 270);
}
.text-body {
font-size: clamp(1rem, 2.5vw + 0.5rem, 1.125rem);
line-height: 1.6;
color: oklch(30% 0.02 270);
text-wrap: pretty;
}
©container article (inline-size > 768px) {
.heading-primary {
letter-spacing: -0.04em;
}
}
©media (prefers-reduced-motion: no-preference) {
heading-primary (
transition: letter-spacing 200ms ease;
}
}
Почему это работает
Данный пример демонстрирует несколько ключевых принципов:
1. Контейнерные запросы создают адаптивность на уровне компонента,
а не только области просмотра.
2. Функция clamp() обеспечивает плавное масштабирование размеров
в заданных границах.
3. Логические свойства (inline-size, margin-inline) поддерживают
различные направления письма.
4. Цветовое пространство oklch() обеспечивает перцептивно
однородную контрастность.
5. Свойство text-wrap: pretty улучшает качество переносов строк.
Основные техники и паттерны
Адаптивное масштабирование типографики
Это техника создания типографических размеров, автоматически
адаптирующихся к размеру контейнера или области просмотра без медиаза-
просов.
Ее следует применять в компонентных системах, требующих консистентного
масштабирования типографики в различных контекстах.
.text-fluid {
font-size: clamp(
Item, /* минимальный размер */
0.875rem + 2vw, /* предпочтительное значение */
1.5rem /* максимальный размер */
);
}
/* Расширенная система масштабирования */
.typescale-sm { font-size: clamp(0 875rem, 0.8rem + 1vw, Item); }
.typescale-base { font-size: clamp(1rem, 0.875rem + 2vw, 1.125rem); }
.typescale-lg { font-size: clamp(1.125rem, 1 rem + 3vw, 1.5rem); }
. typescale-xl { font-size: clamp(1.5rem, 1.25rem + 4vw, 2.25rem); }
Почему это работает
Функция clamp() вычисляется браузером на каждом кадре, обеспечивая
плавное масштабирование между минимальным и максимальным значениями
на основе предпочтительного выражения.
Оптические корректировки межбуквенных интервалов
.text-optical {
/* Базовый межбуквенный интервал */
letter-spacing. -и.01ет;
}
.text-optical--uppercase {
text-transform: uppercase;
/* Компенсация визуальной плотности заглавных букв */
letter-spacing: 0.1em;
/* Компенсация асимметрии при центрировании */
padding-inline-start: 0.1em;
}
.text-optical--large {
font-size: clamp(2rem, 5vw, 4rem);
/* Оптическое уменьшение интервалов в крупных размерах */
letter-spacing: -0.й4ет;
}
Почему это работает
Межбуквенные интервалы по умолчанию оптимизированы для текста сред-
него размера. Крупная типографика требует оптических корректировок для под-
держания визуальной плотности.
Контрастная типографическая иерархия
.hierarchy-primary {
font-weight: 800;
font-size: clamp(1.75rem, 4vw, 3rem);
line-height: 1.1;
color: oklch(15% 0.1 270);
}
.hierarchy-secondary {
font-weight: 400;
font-size: clamp(1rem, 2vw, 1.25rem);
font-style: italic;
line-height: 1.4;
color: oklch(45% 0.05 270);
margin-block-start: 0 5em;
}
.hierarchy-accent {
font-weight: 600;
font-size: 0.875rem;
text-transform: uppercase;
letter-spacing: 0.15em;
color: oklch(60% 0.2 45);
}
Почему это работает
Контрастность создается через различия в весе шрифта, размере, стиле и цве-
те. Логические свойства (margin-block-start) обеспечивают корректное пове-
дение в различных режимах письма.
Современные возможности CSS
Каскадные слои для типографических систем
©layer typography.base {
:root {
--font-size-scale: 1.25;
--font-base-size: 1rem;
--line-height-base: 1.6;
}
body {
font-family: system-ui, sans-serif;
font-size: var(--font-base-size);
line-height: var(--line-height-base);
}
}
©layer typography.components {
.card,.title {
font-size: calc(var(--font-base-size) * var(--font-size-scale));
font-weight: 690;
}
}
©layer typography.utilities {
.text-center { text-align: center; }
.text-uppercase { text-transform: uppercase; }
}
Почему это работает
Каскадные слои позволяют управлять специфичностью независимо от по-
рядка селекторов, создавая предсказуемую архитектуру стилей.
Контейнерные запросы для адаптивной типографики
.card {
container-type: inline-size;
container-name: card-container;
}
.card__content {
padding: 1rem;
}
©container card-container (inline-size > 400px) {
.card__title {
font-size: 1.5rem;
line-height: 1.3;
}
.card__text {
font-size: 1rem;
columns: 2;
column-gap: 1.5rem;
}
}
©container card-container (inline-size > 600px) {
.card__title {
font-size: 2rem;
letter-spacing: 0.02em;
}
}
Почему это работает
Контейнерные запросы реагируют на размер родительского элемента, а не об-
ласти просмотра, обеспечивая истинную компонентную адаптивность.
Продвинутые селекторы и состояния
/* Улучшенные фокусные состояния */
.button {
outline: 2рх solid transparent;
outline-offset: 2px;
}
.button:focus-visible {
outline-color: oklch(60% 0.2 270);
}
/* Адаптивная типографика на основе содержимого */
.article:has(> .article__image) .article__title {
font-size: clamp(1,25rem, 3vw, 2rem);
}
.article:not(:has(> .article__image)) .article___title {
font-size: clamp(1.5rem, 4vw, 2.5rem);
}
/* Сложные состояния фокуса */
.nav-item.focus-within {
background: oklch(95% 0.02 270);
}
Почему это работает
Селектор :has() позволяет стилизовать родительские элементы на основе
дочерних, а : focus-visible активируется только при навигации с клавиатуры.
Новые единицы измерения области просмотра
.hero-text {
/* Dynamic viewport units */
font-size: clamp(2rem, 8dvh, 5rem);
line-height: 1.1;
}
.mobile-header {
/* Large viewport units (без учета интерфейса браузера) */
min-block-size: 101vh;
}
.sticky-footer-text {
/* Small viewport units (с учетом интерфейса браузера) */
margin-block-end: 5svh;
}
/* Безопасные области для мобильных устройств */
.content-safe-area {
padding-inline: max(1rem, env(safe-area-lnset-left));
padding-block-start: max(1rem, env(safe-area-inset-top));
}
Почему это работает
Динамические единицы области просмотра (dvh/dvw) адаптируются к из-
менениям интерфейса браузера, обеспечивая более предсказуемое поведение
на мобильных устройствах.
Производительность
Оптимизация селекторов
Стоимость селекторов в порядке возрастания:
1. ID-селекторы (#element)
2. Классы (.class)
3. Селекторы атрибутов (|attr-"value"])
4. Псевдоклассы (:hover, :focus)
5. Селекторы элементов (div, р)
6. Универсальные селекторы (*)
/* Эффективно */
.text-heading { font-weight: 700; }
/* Менее эффективно */
div > р first-child + span.highlight { font-weight: 700; }
/* Избегайте глубокой вложенности */
.article .content .text .paragraph .emphasis {
/* Триггерит множественные проверки DOM */
}
Управление перерисовками
.textanimated {
/* Создает новый слой композиции */
will-change: transform;
/* Анимируем только transform и opacity */
transition: transform 209ms ease;
}
.text-animated:hover {
/* Только композиция, без layout/paint */
transform: translateY(-2px);
}
/* Избегайте анимации свойств, вызывающих reflow */
.text-bad-animation {
/* Вызывает layout на каждом кадре */
transition: font-size 20ums ease;
}
Почему это работает
Свойства transform и opacity обрабатываются на уровне композиции, ми-
нуя этапы layout и paint.
Оптимизация загрузки шрифтов
@font-face {
font-family: 'OptimizedFont’;
src: url('font.woff2') format('woff2');
font-display: swap; /* Показывает fallback до загрузки */
font-weight: 400;
font-style: normal;
}
.text-optimized {
font-family: 'OptimizedFont', system-ui, sans-serif;
/* Предотвращает layout shift */
size-adjust: 95%;
}
Доступность
Фокусные состояния
.interactive-text {
outline: 2px solid transparent;
outline-offset: 2px;
border-radius: 4px;
}
.interactive-text:focus-visible {
outline-color: oklch(60% 0.2 270);
background: oklch(98% 0.01 270);
}
.interactive-text:focus:not(:focus-visible) {
outline: none;
}
Адаптивная типографика для различных режимов письма
.text-multilingual {
/* Базовые логические свойства */
text-align: start;
margin-inline-start: 1rem;
}
[dir="rtl ] .text-multilingual {
/* Автоматически адаптируется */
}
©supports (writing-mode: vertical-rl) {
[lang="ja ] .text-multilingual {
writing-mode: vertical-rl;
text-orientation: mixed;
}
}
Отладка
Визуализация типографических метрик
/* Отладочные стили для разработки */
.debug-typography {
/* Показывает границы текстовых блоков */
outline: 1рх solid red;
/* Визуализирует line-height */
background: linear-gradient(
to bottom,
transparent 0%,
rgba(255, 0, 0, 0.1) 0%,
rgba(255, 0, 0, 0.1) 100%,
transparent 100%
);
}
.debug-baseline {
/* Показывает базовую линию */
background-image:
repeating-linear-gradient(
transparent,
transparent calc(1.5rem - 1px),
rgba(e, 255, 0, 0.5) calc(1.5rem - 1px),
rgba(0, 255, 0, 0.5) 1.5rem
);
}
Диагностика каскада и специфичности
/* Временные стили для выявления проблем специфичности */
.debug-specificity {
font-size: 1 rem iimportant;
background: yellow iimportant;
}
/* Поиск конфликтов через исключение */
* {
font-family: 'Comic Sans MS’ iimportant;
}
Методология бинарного поиска
1. Закомментируйте половину CSS-правил.
2. Проверьте, сохраняется ли проблема.
3. Повторите для оставшейся половины.
4. Изолируйте проблемное правило.
Распространенные ошибки и антипаттерны
Злоупотребление отрицательными отступами
/* Антипаттерн */
.text-hack {
margin-top: -20рх; /* Хрупкое решение */
}
/* Правильный подход */
.text-proper {
transform: translateY(-20px);
/* или использование flexbox/grid */
}
Архитектура и масштабирование
Организация каскадных слоев
©layer reset, base, tokens, components, utilities, overrides;
©layer tokens {
:root {
--font-family-primary: 'Inter', system-ui, sans-serif;
--font-size-scale: 1.2;
--line-height-base: 1.6;
}
}
©layer base {
body {
font-family: var(--font-family-primary);
line-height: var(--line-height-base);
}
}
©layer components {
.card-title {
font-size: calc(var(--font-base-size) * var(--font-size-scale));
}
}
Система дизайн-токенов
:root {
/* Типографическая шкала */
--font-size-xs: 0.75rem;
--font-size-sm: 0.875rem;
--font-size-base: Irem;
--font-size-lg: 1.125rem;
--font-size-xl: 1,25rem;
/♦ Весовые значения */
--font-weight-normal: 40u;
--font-weight-medium: 500;
--font-weight-semibold• 600;
--font-weight-bold: 700;
/* Межстрочные интервалы */
--line-height-tight: 1,2;
--line-height-base: 1.6;
--line-height-loose: 1.8;
}
/* Тематизация */
[data-theme="dark’‘] {
--color-text-primary: oklch(90% I1.05 270);
--color-text-secondary: oklch(70% 0.03 270);
}
Модульная архитектура (BEM + современный CSS)
/* Блок */
.article {
container-type: inline-size;
}
/* Элементы */
.article__header {
margin-block-end: 2rem;
}
.article__title {
font-size: clamp(1.5rem, 4vw, 2.5rem);
font-weight: var(--font-weight-bold);
line-height: var(--line-height-tight);
}
/* Модификаторы */
.article__title--featured {
color: var(--color-accent);
letter-spacing: -0.02em;
}
/* Контейнерные варианты */
©container (inline-size > 768px) {
.article__title--featured {
font-size: clamp(2rem, 6vw, 4rem);
}
}
Совместимость браузеров
Функция Chrome Firefox Safari Edge Примечания
с lamp{) 79+ 75 + 13.1+ 79+ Полная поддержка
Container Queries 105+ 110+ oklchQ 111+ 113+ 16+ 105+ Стабильная поддержка
15.4+ 111+ Про1рессивное улучшение
:has() 105+ 121 + 15.4+ 105+ Полифил не рекомендуется
Cascade Layers n 99+ 108+ 97+ 15.4+ 99+ Полная поддержка
dvh/lvh/svh 101+ 15.4+ 108+ Фоллбэк на vh
text-wrap: pretty 117+ Нет 16.4+ 117+ Эксперименталь- ная
Subgrid 117+ 1 71+ J 85+ 16+ 117+ IIpoipeccHBHoe улучшение
ifocus-visible 86+ 15.4+ 86+ Полифил доступен
Logical Properties 87+ 66+ 12.1+ 87+ Полная поддержка
Практические упражнения
Упражнение 1. Адаптивная типографическая система
Требования: создайте систему заголовков (hl-h6) с плавным масштабирова-
нием между 320рх и 1200рх.
Условия выполнения:
• Использование функций min() /max () /clamp ().
• Оптические корректировки для крупных размеров.
• Поддержка темной гемы.
Подсказка: используйте Custom Properties для центрального управления мас-
штабом.
Упражнение 2. Компонентная типографика
Требования: реализуйте карточный компонент с адаптивной типографикой
на основе контейнерных запросов.
Условия выполнения:
• Минимум три контрольные точки размера.
• Логические свойства для интернационализации.
• Accessibility-совместимые состояния фокуса.
Подсказка: комбинируйте container queries с clamp() для плавных перехо-
дов.
Упражнение 3. Производительная анимация текста
Требования: создайте анимированный заголовок без влияния на layout
и paint.
Условия выполнения:
• Использование только свойств transform и opacity.
• Респект к prefers-reduced-motion.
• Измерение производительности в DevTools.
Подсказка: используйте will-change с осторожностью и удаляйте после ани-
мации.
Заключение
Современная CSS-типографика предоставляет мощный инструментарий
для создания масштабируемых, доступных и производительных интерфейсов.
К стабильным технологиям, готовым для немедленного внедрения в производ-
ственные системы, относятся:
• Базовые возможности — включают функции clamp(), min(), тах() для
адаптивного масштабирования, логические свойства для интер-
национализации, каскадные слои для архитектурной организации
стилей. Эти функции поддерживаются всеми современными браузерами
и обеспечивают значительные преимущества в поддержке и развитии
кодовой базы.
• Контейнерные запросы — революционизируют подход к компонент-
ной разработке, позволяя создавать истинно переиспользуемые
интерфейсные блоки. При правильном применении они снижают
количество медиа-запросов на уровне области просмотра и упрощают
адаптивную логику компонентов.
• Селекторы нового поколения (:has(), :is(), :where())—расширяют
возможности стилизации без JavaScript, но требуют осторожного
применения из-за потенциального влияния на производительность
в сложных DOM-структурах.
Долгосрочная перспектива
Эволюция CSS-типографики направлена на сближение с возможностями
традиционной полиграфии при сохранении интерактивности и адаптивности
веб-среды. Ключевые направления развития включают улучшенную поддержку
переменных шрифтов, расширение математических функций, развитие контей-
нерных запросов для стилевых условий и дальнейшую стандартизацию логиче-
ских свойств.
Типографика остается одним из наиболее влиятельных аспектов поль-
зовательского опыта, и инвестиции в современные CSS-техники окупаются
через улучшение читаемости, доступности и общего качества интерфейсов.
Однако технологический прогресс должен балансироваться с принципа-
ми надежности, производительности и широкой совместимости, особенно
в контексте глобальных продуктов с разнообразной аудиторией пользова-
телей.
Мастерство в CSS-типографике требует не только технических знаний,
но и понимания принципов визуального дизайна, психологии восприятия
и культурных особенностей различных языков и систем письма. Только ком-
плексный подход позволяет создавать интерфейсы, которые не просто функци-
онируют, но и обеспечивают комфортное взаимодействие для всех категорий
пользователей.
Углубленное чтение
CSS Typography Reference — официальная документация
MDN по всем CSS-свойствам шрифтов: https://developer.mozilla.
org/en-US/docs/Web/CSS/font.
CSS-Tricks Typography — коллекция практических статей
по современным CSS-техникам типографики: hups://css-tricks.
сот/.
Can 1 Use Typography Features — проверка поддержки совре-
менных типографических возможностей браузерами: https://
caniusc.com/.
Глава 6. CSS-переходы и магия
анимации
CSS-переходы (transitions) представляют собой фундаментальный меха-
низм для создания плавных анимационных эффектов между состояниями
элементов. В отличие от ключевых кадров (keyframes), переходы обеспечи-
вают автоматическую интерполяцию значений CSS-свойств при их измене-
нии, создавая естественные и производительные анимации без необходимо-
сти применения JavaScript
В данной главе рассматриваются переходы как инструмент современной
веб-разработки, охватывающий спектр от базовых принципов до сложных ком-
позиционных техник. Мы изучим механизмы работы переходов в контексте
каскада, специфичности и циклов рендеринга браузера, а также рассмотрим
их интеграцию с современными CSS-возможностями, такими как слои каскада,
контейнерные запросы и логические свойства.
Практическое применение охватывает создание микровзаимодействий
пользовательского интерфейса, состояний компонентов, адаптивных макетов
и доступных анимаций. Особое внимание уделяется производительности, отлад-
ке и архитектурным решениям для масштабируемых кодовых баз.
Теория и терминология
CSS-нереход — это автоматическая анимация изменения значения CSS-свой-
ства от начальном к конечному состоянию в течение заданного времени с при-
менением функции плавности (easing function).
Переходное свойство (transitionable property) — CSS-свойство, значения ко-
торого могут быть интерполированы браузером. К таким свойствам относятся
числовые значения, цвета, размеры, позиции и трансформации.
Интерполяция — процесс вычисления промежуточных значений между на-
чальным и конечным состояниями свойства на каждом кадре анимации.
Функция плавности (timing function) — математическая функция, опреде-
ляющая скорость изменения анимированного значения во времени. Основана
на кубических кривых Безье.
Переходное событие (transition event) — DOM-событие, возникающее
при начале, окончании или отмене перехода (transilionstart, transitionend,
transitioncancel).
В контексте рендеринга браузера переходы выполняются на этапе компо-
зитинга, что позволяет аппаратному ускорению обрабатывать большинство
трансформаций и изменений прозрачности без повторного вычисления макета
или перерисовки.
CSS-переходы впервые появились в спецификации CSS Transitions Module
Level 1 (2009) как решение для создания простых анимаций без использования
JavaScript. Современная реализация основана на Web Animations API и интегри-
рована с циклом событий браузера для оптимальной производительности.
Быстрый пример
Рассмотрим фундаментальный пример перехода, демонстрирующий основ-
ные принципы работы:
html
<button class=‘magic-button">HaBefli/iTe Kypcop</button>
css
.magic-button {
background-color: #3498db;
color: white;
padding: 12px 24px;
border: none;
border-radius: 6px;
cursor: pointer;
transform: scale(l);
transition: all 300ms cubic-bezier(o.4, 0, 0.2, 1);
}
.magic-button:hover {
background-color: #2980b9;
transform: scale(1.05);
box-shadow: 0 8px 25px rgba(52, 152, 219, 0.3);
}
Пошаговое объяснение
1. Базовое состояние: кнопка имеет начальные значения для цвета фона,
трансформации и отсутствует тень.
2. Декларация перехода: transition: all 309ms cubic-bezier(0.4, 0,
0.2, 1) указывает браузеру анимировать все изменяемые свойства в течение
300 миллисекунд.
3. Целевое состояние: при наведении : hove г изменяются три свойства.
4. Автоматическая интерполяция: браузер вычисляет промежуточные зна-
чения для каждого кадра.
Почему это работает
когда псевдокласс : hover становится активным, браузер обнаруживает изме-
нения в вычисленных значениях свойств. Поскольку на элементе объявлен пе-
реход для всех свойств, движок CSS создает анимационные объекты для каждого
изменившегося переходного свойства. Функция плавности cubic-bezier(0.4,
0, 0.2, 1) определяет ускорение в начале и замедление в конце, создавая есте-
ственное движение.
Трансформации и изменения прозрачности обрабатываются на композит-
ном слое, что позволяет GPU выполнять анимацию независимо от основного по-
тока JavaScript.
Основные техники и паттерны
Базовый синтаксис и свойства
CSS-переходы управляются четырьмя основными свойствами;
.element {
transition-property: transform, opacity;
transition-duration: 500ms;
transition-timing-function: ease-out;
transition-delay: 100ms;
/* Краткая запись */
transition: transform 500ms ease-out 100ms,
opacity 3G0ms ease-in 200ms,
}
Стоит применять для простых состояний компонентов (hove г, focus, active),
микровзаимодействий и плавных изменений свойств при адаптивных измене-
ниях.
Почему это работает
Браузер создает внутреннюю структуру данных для каждого объявленного
перехода. При изменении вычисленного значения свойства запускается процесс
интерполяции. Значение transition-delay добавляется к временной метке на-
чала анимации, a transition-timing-f unction влияет на распределение проме-
жуточных значений во времени.
Техника поэтапной задержки
Создание сложных последовательных анимаций через управление задерж-
ками:
html
<div class="letter-reveal">
<span>M</span><span>A</span><span>r </span><span>M</span><span>fl</
span>
</div>
css
.letter-reveal span {
display: inline-block;
opacity 0;
transform: translateY(20px);
transition: opacity 400ms ease-out,
transform 40(ims ease-out;
}
.letter-reveal:hover span:nth-child(1) {
transition-delay: 0ms, 0ms;
}
.letter-reveal:hover span:nth-child(2) {
transition-delay: 100ms, 80ms;
}
,letter-reveal:hover span:nth-child(3) {
transition-delay: 200ms, 160ms;
}
.letter-reveal:hover span:nth-child(4) {
transition-delay: 300ms, 240ms;
}
.letter-reveal:hover span:nth-child(5) {
transition-delay: 408ms, 320ms;
}
.letter-reveal:hover span {
opacity: 1;
transform: translateY(O);
}
Почему это работает
Каждый элемент span получает индивидуальную задержку для двух свойств.
Разные значения задержки для opacity и transform создают более сложную
хореографию движения. Браузер независимо обрабатывает каждый переход,
что позволяет создавать волновые эффекты.
Вариации и граничные случаи:
• Использование CSS-переменных для динамического вычисления
задержек.
• Применение :nth-child(an+b) для математических последователь-
ностей.
• Комбинирование с CSS Grid для двумерных эффектов.
Паттерн accordion без JavaScript
Реализация интерактивных компонентов через состояния форм:
html
<div class= accordion">
«input type='radio" id="section-1 1 name=’accordion" class="accordion-
input'>
«label for="section-1" class="accordion-label">Pa3flen 1</label>
<div class="accordion-content">
«р^Содержимое перзого раздела .. .</p=>
</div>
«input type="radio id="section-2 name='accordion class="accordion-
input'>
«label for- section-2 class="accordion-label’=>Раздел 2</label>
<div class='accordion-content">
<р>Содержимое второго раздела...</p>
</div>
«/div>
css
.accordion-input {
position: absolute;
opacity: 0;
pointer-events: none;
}
.accordion-content {
max-height: 0;
overflow: hidden;
transition: max-height 400ms cubic-bezier(0.4, 0, 0.2, 1),
padding 460ms cubic-bezier(0.4, 0, 0.2, 1);
padding: 0 20px;
}
.accordion-input:checked + .accordion-label + .accordion-content {
max-height: 500px; /* Достаточно для содержимого */
padding: 20px;
}
.accordion-label {
display: block;
cursor: pointer;
padding: 15рх 20рх;
background: #f8f9fa;
border: 1рх solid #dee2e6;
transition: background-color 200ms ease;
}
.accordion-label:hover •{
background-color: ffe9ecef;
}
Почему это работает
Элементы input[type="radio’] с одинаковым именем образуют груп-
пу взаимоисключающих состояний. Селектор .accordion-input:checked +
.accordion-label + .accordion-content использует комбинатор смежных
элементов для выбора содержимого после активированной радиокнопки. Пе-
реход max-height от 0 до фиксированного значения создает эффект раскрытия,
a overflow: hidden обрезает содержимое.
Совместимость и ограничения:
• Требует предварительного знания максимальной высоты содержимого.
• Альтернатива: использование grid-template-rows с fr единицами
в современных браузерах.
ЗО-трансформации с переходами
Создание пространственных эффектов:
html
<div class='‘card-3d">
<div class="card-inner">
<div class="card-fгоп!">Лицевзя cTopoHa</div>
<div class="card-back">O6paTHaB сторона^/div>
</div>
</div>
css
,card-3d {
perspective: 1000px;
width: 200px;
height: 120px;
}
.card-inner {
position: relative;
width: 1 '0%;
height: 100%;
transform-style: preserve-3d;
transition: transform 600ms cubic-bezier(0.4, 0, 0.2, 1);
}
.card-3d:hover .card-inner {
transform: rotateY(180deg);
}
.card-front,
.card-back {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: lf0%;
backface-visibility: hidden;
display: flex;
align-items: center;
justify-content: center;
border-radius: 8px;
background: linear-gradient(45deg. #667eea 0%, #764ba2 100%);
color: white;
}
.card-back {
transform: rotateYf180deg);
background: linear-gradient(45deg, #f093fb 0%, #f5576c 100%);
}
Почему это работает
Свойство perspective на родительском элементе создает точку обзо-
ра для ЗЛ-пространства. transform-style: preserve-3d указывает бра-
узеру сохранять ЗЛ-позиционирование дочерних элементов, backface-
visibility: hidden скрывает обратные стороны плоскостей, a transform:
rotateY(180deg) на .card-back предварительно поворачивает его
При hover поворот .card-inner на 180° вокруг оси Y создает эффект перево-
рота карточки. Браузер интерполирует промежуточные углы поворота, создавая
плавную ЗЛ-анимацию.
Современные CSS-возможности
Интеграция с каскадными слоями
Организация переходов через ©layer для предсказуемой специфичности:
©layer base, components, utilities;
©layer base {
* {
transition: none; /* Сброс по умолчанию */
}
}
©layer components {
.button {
transition: background-color 200ms ease,
transform 200ms ease,
box-shacow 200ms ease;
}
.card {
transition: transform 300ms cubic-bezier(0.4, 0, 0.2, 1);
}
}
©layer utilities {
.transition-none {
transition: none ‘important;
}
.transition-fast {
transition-duration: 150ms ‘important;
}
}
Почему это работает
Стой каскада определяют порядок применения стилей независимо
от специфичности селекторов внутри слоя. Это позволяет utilny-классам
в слое utilities переопределять компонентные стили из слоя components,
даже если компонентные селекторы имеют более высокую специфичность.
Слой base обеспечивает согласованные базовые значения для всех переходов.
Контейнерные запросы и адаптивные переходы
Изменение поведения переходов на основе размеров контейнера:
.card-container {
container-type: inline-size;
container-name: card;
}
.card {
transition: transform 300ms ease;
}
©container card (min-width: 400px) {
.card {
transition-duration: 500ms;
transition-timing-function: cubic-bezier^.4, 0, 0.2, 1);
}
.card:hover (
transform: scale(1.08);
}
}
©container card (max-width; 399px) {
.card:hover {
transform: translateY(-4px);
}
}
Почему это работает
Контейнер с container-type: inline-size создает контекст запроса по шири-
не. Медиазанросы ©container реагируют на размеры контейнера, а не viewport.
Это позволяет компонентам адаптировать анимации к доступному пространству:
масштабирование для широких контейнеров и простое смещение для узких.
Современные селекторы с переходами
Использование :has(), :is(), : whe re () для сложной логики:
.form-group {
transition: all 200ms ease;
}
.form-group:has(input:focus) {
transform: translateX(4px);
box-shadow: -4px 0 0 #007bff;
}
button:is('hover, ;focus-visible) {
transition: transform 159ms cubic-bezier(0.4, 0 0.2, 1),
box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
/* Низкая специфичность для переопределения */
:where(.card, .panel, .modal) {
transition: opacity 200ms ease,
transform 200ms ease;
}
Почему это работает
Селектор :has() позволяет родительскому элементу реагировать на состо-
яние дочерних элементов. :is() группирует селекторы с одинаковой специ-
фичностью, a :where() обнуляет специфичность, упрощая переопределение
стилей.
CSS Nesting с переходами
Вложенная структура для организации связанных состояний:
navigation {
.nav-item {
transition: color 2&0ms ease;
&: hover {
color: #007bff;
.nav-icon {
transition: transform 150ms ease;
transform: rotate(5deg);
}
}
&:has(.nav-dropdown) {
&:hover ,nav-dropdown {
transition: opacity 200ms ease,
visibility 200ms ease,
transform 200ms ease;
opacity: 1;
visibility: visible;
transform: translateY(O);
}
}
}
.nav-dropdown {
opacity: 0;
visibility: hidden;
transform: translateY(-Wpx);
transition: opacity 200ms ease,
visibility 200ms ease,
transform 200ms ease;
}
}
Почему это работает
CSS Nesting создает область видимости для селекторов, улучшая читаемость
кода. Комбинатор & ссылается на родительский селектор, позволяя описывать
состояния компонента в одном блоке. Вложенность не влияет на каскад или спе-
цифичность — браузер разворачивает правила в обычные селекторы.
Производительность
Оптимизация селекторов и инвалидация
Эффективные селекторы для переходов минимизируют работу движка
стилей:
/* Оптимальный подход */
.button {
transition: transform 20h'ms ease;
}
.button:hover {
transform: translateY(-2px);
}
/* Избегайте сложных селекторов для часто изменяемых состояний */
.container .sidebar .menu .item:nth-child(oda):hover {
/* Дорогой селектор для анимации */
transition: background-color 200ms ease;
}
/* Лучше использовать прямые классы */
.menu-item {
transition: background-color 200ms ease;
}
.menu-item:hover {
background-color: #f8f9fa;
}
Управление перерасчетом макета
/* Свойства, вызывающие reflow */
.expensive-transition {
transition: width 309ms ease, /* Перерасчет макета */
height 300ms ease, /* Перерасчет макета */
padding 300ms ease; /* Перерасчет макета */
}
/* Оптимизированная альтернатива */
.optimized-transition {
transition: transform 300ms ease, /* Только композитинг */
opacity 309ms ease; /* Только композитинг */
}
.optimized-transition:hover {
transform: scale(1.1); /* Визуальное увеличение без reflow */
}
Композитные слои и GPU-ускорение
Принудительное создание композитных слоев для сложных анимаций:
.complex-animation {
/* Создание композитного слоя */
will-change: transform, opacity;
/* Или альтернативный способ */
transform: translateZ(O); /* Hack для создания слоя */
transition: transform 309ms cubic-bezier(0.4, 0, 0.2, 1),
opacity 300ms cubic-bezier(0.4, 0, 0.2, 1);
}
.complex-animation:hover {
transform: translateZ(0) scale(1.G5) rotate(2deg);
opacity: 0.9;
}
/* Очистка will-change после анимации */
.complex-animation {
transition: transform 309ms ease,
opacity 309ms ease;
}
.complex-animation:not(:hover) {
will-change: auto; /* Освобождение ресурсов GPU */
}
Почему это работает
Свойство will-change сообщает браузеру о намерении анимировать эле-
мент, позволяя заранее создать композитный слой. Трансформации и измене-
ния прозрачности на композитном слое выполняются GPU без блокировки ос-
новного потока. Важно очищать will-change после анимации для экономии
памяти.
Управление производительностью через containment
Изоляция областей перерисовки:
.animation-container {
contain: layout style paint;
/* Изолирует изменения внутри контейнера */
.animated-cards {
contain: layout;
/* Предотвращает влияние на внешний макет */
}
.animated-cards .card {
transition: transform 209ms ease;
contain: paint;
/* Ограничивает область перерисовки */
}
Почему это работает
CSS Containment API позволяет браузеру оптимизировать рендеринг, ограни-
чивая влияние изменений определенными областями DOM. contain: paint пре-
дотвращает выход визуального содержимого за границы элемента, contain:
layout изолирует изменения макета, a contain: style ограничивает влияние
изменений стилей.
Доступность
Доступные фокусные состояния
Четкие визуальные индикаторы фокуса:
.interactive-element {
transition; outline 150ms ease,
box-shadow 150ms ease;
}
.interactive-element:focus {
outline: 2px solid #007bff;
outline-offset: 2px;
}
.interactive-element:focus:not(:focus-visible) {
outline: none;
}
.interactive-element:focus-visible {
outline: 2px solid #B07bff;
outline-offset: 2px;
box-shadow: 000 4px rgba(0, 123, 255, 0.25);
}
/* Расширенные индикаторы для комплексных компонентов */
.form-group {
transition: all 200ms ease;
}
.form-group:focus-within {
transform: translateX(4px);
border-left: Зрх solid #007bff;
padding-left: 17рх; /* Компенсация сдвига */
}
Почему это работает
:focus-visible активируется только при клавиатурной навигации, избегая
нежелательных эффектов при клике мышью. :focus-within позволяет роди-
тельским элементам реагировать на фокус дочерних элементов. Анимирован-
ные изменения делают переходы фокуса более заметными для пользователей
программ чтения с экрана.
Контрастность и цветовые переходы
Обеспечение достаточного контраста во всех состояниях:
.text-button {
color: #495057;
background-color: transparent;
transition: color 200ms ease,
background-color 200ms ease;
}
.text-button:hover {
color: #212529; /* Увеличенный контраст */
background-color: #f8f9fa;
}
.text-button:focus-visible {
color: #ffffff;
background-color: #007bff;
/* Контраст 4.5:1 или выше */
}
/* Проверка поддержки высокого контраста */
©media (prefers-contrast: high) {
.text-button:hover {
color: #000000;
background-color: #ffffff;
border: 2px solid #000000;
}
}
Отладка
Визуализация слоев композитинга
/* Временный код для отладки */
.debug-layers * {
outline: 1рх solid red !important;
}
.debug-layers *[style*=‘'transform" ],
.debug-layers *[style*="opacity"],
.debug-layers .will-change {
outline: 3px solid lime ’important;
}
Диагностика производительности
/* Индикаторы проблемных переходов */
©keyframes performance-warning {
0%, 100% { outline: Зрх solid red; }
50% { outline. 3px solid yellow; }
}
.debug expensive-transitions {
animation: performance-warning 1s infinite;
}
/* Применение через DevTools или временно в коде */
[style*="width"][style*="transition"],
[style*="height"][style*=Mtransition"],
[style*="padding“][style*="transition"] {
animation: performance-warning 1s infinite;
}
Распространенные ошибки и антипаттерны
Гонка специфичности
Проблематичный код:
.button { transition: all 200ms ease; }
.primary-button { transition: all 300ms ease ’important; }
.header .primary-button { transition: all 150ms ease ’important; }
.header .navigation .primary-button { transition: all 400ms ease
^important; }
Правильное решение:
©layer components {
.button {
transition: background-color 200ms ease.
transform 2i'-0ms ease;
}
}
©layer variants {
.button--primary {
transition-duration: 3U0ms;
}
}
©layer utilities {
.transition-fast {
transition-duration: 150ms iimportant;
}
}
Утечки z-index и непредвиденные контексты наложения
Проблема:
.modal {
z-index: 1000;
transition: opacity 300ms ease;
}
.dropdown {
z-index: 999;
transform: translateY(ldpx); /* Создает stacking context */
transition: transform 200ms ease;
}
.tooltip {
z-index: 1001;
will-change: opacity; /* Создает stacking context */
transition: opacity 150ms ease;
}
Решение:
:root {
--z-dropdown: 100;
--z-modal: 200;
--z-tooltip: 300;
}
.dropdown {
z-index: var(--z-dropdown);
/* Избегаем создания stacking context без необходимости */
}
.modal {
z-index: var(--z-modal);
/* Явно создаем stacking context когда нужен z-index */
position: relative;
}
.tooltip {
z-index: var(--z-tooltip);
position: relative;
}
Злоупотребление хаками вместо современных решений
Устаревший подход:
.clearfix::after {
content: ;
display: table;
clear: both;
}
.sidebar {
float: left;
width: 250px;
transition: margin-left 300ms ease;
}
.sidebar.collapsed {
margin-left: -250px;
}
Современный подход:
.layout {
display: grid;
grid-template-columns: var(--sidebar-width, 250px) If r;
transition: grid-template-columns 300ms ease;
}
.layout[data-sidebar-collapsed] {
--sidebar-width: 0px;
}
.sidebar {
overflow: hidden;
transition: opacity 300ms ease;
}
.layout[data-sidebar-collapsed] .sidebar {
opacity: O;
}
Архитектура и масштабирование
Методологии и организация переходов
ВЕМ с переходами:
/* Блок */
.card {
transition: transform 204ms ease,
box-shadow 200ms ease;
}
/* Модификаторы */
.card--interactive {
cursor: pointer;
}
.card--interactive:hover {
transform: translateY(-4px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
}
.card--large {
transition-duration: 300ms;
}
/* Элементы */
.card__image {
transition: transform 250ms ease;
}
.card--interactive:hover .card_image {
transform: scale(1.05);
}
ITCSS с каскадными слоями:
©layer settings, tools, generic, elements, objects, components,
utilities;
©layer settings {
:root {
--transition-fast: 150ms;
--transition-base: 200ms;
--transition-slow: 304ms;
--transition-ease: cubic-bezier(0.4, 0, 0.2, 1);
}
}
©layer generic {
*, *::before, *:rafter {
transition: none;
}
}
©layer elements {
button {
transition: background-color var(--transition-base) ease;
}
}
©layer objects {
.o-layout {
transition: grid-template-columns var(--transition-slow) var(--
transition-ease);
}
}
©layer components {
.c-button {
transition: background-color var(--transition-base) ease,
transform var(--transition-base) ease;
}
}
©layer utilities {
.u-transition-none {
transition: none 'important;
}
}
Дизайн-токены и темизация
Системный подход к переходам:
:root {
/* Длительность */
--duration-instant: 0ms;
--duration-fast: 150ms;
--duration-base: 200ms;
--duration-slow: 300ms;
- -duration-slower: 400ms;
/* Функции плавности */
- -ease-linear: linear;
- -ease-in: cubic-bezier(0.4, 0, 1, 1);
- -ease-out: cubic-bezier(0, 0, 0.2, 1);
- -ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
- -ease-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55);
/* Составные переходы */
--transition-fade: opacity var(--duration-base) var(--ease-out);
--transition-slide: transform var(--duration-base) var(--ease-out);
--transition-scale: transform var(--duration-fast) var(--ease-out);
}
/* Темная тема - более быстрые переходы */
[dara-theme='dark"] {
--duration-base: 150ms;
--duration-slow: 250ms;
}
/* Режим уменьшенного движения */
©media (prefers-reduced-motion: reduce) {
:root {
- -duration-fast: 1ms;
- -duration-base: 1ms;
- -duration-slow: 1ms;
}
}
/* Применение системы токенов */
.button {
transition: background-color var(--duration-base) var(--ease-out),
transform var(--duration-fast) var(--ease-out);
}
.modal {
transition: var(--transition-fade), var(--transition-scale);
}
Композиция и повторное использование
Миксины через CSS custom properties:
:root {
/* Базовые миксины */
--mixin-fade-in: opacity var(--duration-base) var(--ease-out);
--mixin-slide-up: transform var(--duration-base) var(--ease-out);
--mixin-scale-hover: transform var(--duration-fast) var(--ease-out);
/* Сложные композиции */
--mixin-card-hoveг:
var(--mixin-scale-hover),
box-shadow var(--duration-base) var(--ease-out);
--mixin-modal-enter:
var(—mixin-fade-in),
var(--mixin-scale-hover);
}
.card {
transition: var(--mixin-card-hover);
}
.modal {
transition: var(--mixin-modal-enter);
}
/* Контекстные переопределения */
.card--large {
--duration-fast: 200ms;
--duration-base: 300ms;
}
Совместимость браузеров
Функция Chrome Firefox Safari Edge Примечания
Базовые пере- ходы 26+ 16+ Г 9+ 12+ Полная поддержка
transition- behavior X X ^*1 X X 117+ В разработке
Переходы с display 117+ X X Экспериментальная
Переходы логиче- ских свойств 89+ 66+ 14.1+ 89+ Полная поддержка
CSS Nesting 112+ 117+ 16.5+ 1 112+ Полная поддержка
:has()в перехо- дах 105+ 121+ 15.4+ 105+ Полная поддержка
©layer 99+ 97+ 15.4+ 99+ Полная поддержка Полная поддержка
Container Queries 105+ 110+ 16+ 105+ 111 +
oklch() цвета 111+ 113+ 15.4+ Частичная под- держка
prefers- reduced-motion 74+ 63+ 10.1+ - 79+ Полная поддержка 96+ Полная поддержка
prefers- contrast 96+ 101+ 14.1+
Стратегии прогрессивного улучшения
/* Базовая поддержка для всех браузеров */
.button {
background-color: #007bff;
transition: background-color 200ms ease;
}
.button:hover {
background-color: #0056b3;
}
/* Расширенные возможности для современных браузеров */
©supports (color: oklch(0 7 0.15 240)) {
.button {
background-color: oklch(0.6 0.2 240);
transition: background-color 200ms ease;
}
.button:hover {
background-color: oklch(0.5 0.25 240);
}
}
/* Полифилы и резервные варианты */
©supports not (selector(:has(*))) {
.form-group.has-focus {
transform: translateX(4px);
}
}
Практические упражнения
Упражнение 1. Адаптивная карточка товара
Требования:
• Создайте карточку товара с изображением, заголовком и ценой.
• Реализуйте hover-эффекты: подъем карточки, масштабирование
изображения, изменение цены.
• Обеспечьте адаптивность: разные анимации для мобильных и десктопных
устройств.
• Соблюдайте принципы доступности.
Условия выполнения:
• Все переходы должны выполняться на композитном слое.
• Время переходов не должно превышать 300 ms.
• Анимации отключаются при prefers-reduced-motion: reduce.
Подсказки:
• Используйте transform вместо изменения top/left.
• Примените will-change для сложных hover-состояний.
• Рассмотрите контейнерные запросы для адаптивности.
Упражнение 2. Accordion с плавными переходами высоты
Требования:
• Создайте accordion без JavaScript, используя радиокнопки.
• Реализуйте плавные переходы открытия/закрытия секций.
• Поддержите произвольную высоту содержимого.
Условия выполнения:
• Переходы должны работать без знания конечной высоты.
• Анимация должна быть плавной при любом количестве содержимого.
• Компонент должен быть доступным с клавиатуры.
Подсказки:
• Исследуйте возможности grid-template-rows : 0fr и 1fr.
• Рассмотрите комбинирование с max-height как резервный вариант.
• Обратите внимание на overflow: hidden и его влияние на доступность.
Упражнение 3. Система уведомлений с анимацией
Требования:
• Создайте компонент для показа уведомлений.
• Реализуйте анимации появления (slide-in) и исчезновения (fade-out).
• Поддержите стекирование нескольких уведомлений.
Условия выполнения:
• Уведомления должны появляться из угла экрана.
• При удалении уведомления остальные должны плавно сдвигаться.
• Анимации должны учитывать prefers-reduced-motion.
Подсказки:
• Используйте CSS Grid или Flexbox для управления расположением.
• Примените каскадные слои для организации стилей.
• Рассмотрите использование CSS custom properties для координации
анимаций.
Заключение
CSS-переходы представляют собой мощный инструмент современной веб-раз-
работки, обеспечивающий баланс между выразительностью пользовательского
интерфейса и производительностью. Освоение техник, представленных в дан-
ной главе, позволяет создавать интуитивные и доступные интерфейсы без ком-
промиссов в отношении производительности.
Готово для продакшена сейчас:
• Базовые переходы для hover, focus и active состояний.
• Адаптация анимаций под пользовательские предпочтения через р ref е rs-
reduced-motion.
• Логические свойства для интернационализации.
• Каскадные слои для организации переходов в больших кодовых базах.
• Современные селекторы :is(), :where(), :has() в поддерживающих
браузерах.
Требует осторожного внедрения:
• Переходы с display (экспериментальная поддержка в Chrome).
• Цветовые пространства OKLCH/LCH (ограниченная поддержка).
• Сложные backdrop -filter эффекты (влияние на производительность).
• Переходы с контейнерными запросами (новая функциональность).
Стратегии безопасного внедрения в крупных проектах
Начните с аудита существующих переходов и их влияния на произво-
дительность. Внедряйте систему дизайн-токенов для централизованного
управления длительностью и функциями плавности. Используйте каскад-
ные слои для предсказуемого переопределения анимаций в различных кон-
текстах.
Обязательно тестируйте переходы на мобильных устройствах и при медлен-
ных соединениях. Предусматривайте резервные варианты для эксперименталь-
ных возможностей и всегда учитывайте пользовательские предпочтения до-
ступности.
Помните, лучшая анимация — та, которую пользователь не замечает как пре-
пятствие, но которая делает интерфейс более отзывчивым и приятным в исполь-
зовании.
Углубленное чтение
CSS Transitions — официальная документация MDN
по CSS-переходам: https://developer.mozilla.org/en-US/docs/Web/
CSS/CSS_Transitions.
Animations and Performance — технический гайд Web.dev
по производительности анимаций: https://web.dev/animations-
guide/.
CSS Functions Guide — comprehensive руководство CSS-Tricks
по всем CSS-функциям: https://css-tricks.com/complete-guide-tu-
css-functions/.
Заключение
CSS в наше время представляет собой зрелую, мощную технологию, способ-
ную решать сложные задачи компоновки, визуального дизайна и пользователь-
ского взаимодействия без компромиссов в производительности или досзупно-
сти. Современный frontend-разработчик работает не просто со стилевым языком,
а с комплексной системой, требующей глубокого понимания алгоритмов брау-
зерной отрисовки, принципов архитектуры кода и особенностей пользователь-
ского восприятия.
Фундаментальные принципы остаются незыблемыми.
Блочная модель CSS, каскадирование, специфичность и контексты формати-
рования составляют теоретический фундамент, на котором строятся все продви-
нутые техники. Универсальное применение box-sizing: border-box как стан-
дартной практики, понимание влияния различных свойств на этапы layout,
paint и composite, осознанное управление специфичностью через архитектур-
ные методологии — эти базовые концепции определяют качество и «ремонто-
пригодность» кода независимо от используемых возможностей.
Критический вывод: инвестиции в глубокое понимание фундаментальных
механизмов CSS окупаются возможностью эффективно применять любые новые
функции и диагностировать сложные проблемы производительности.
CSS в наше время — это и магия, и инженерная дисциплина, требующая си-
стематического подхода, глубоких теоретических знаний и практического опы-
та применения. Мастерство достигается не запоминанием синтаксиса новых
функций, а пониманием принципов их взаимодействия с браузерными движка-
ми, потребностями пользователей и архитектурными требованиями проектов.
Истинная магия современного CSS заключается в способности создавать ин-
терфейсы. которые работают для всех пользователей на всех устройствах, оста-
ваясь при этом «ремонтопригодными», производительными и совместимыми
с предыдущими версиями. Это достижимо только через профессиональное при-
менение представленных в данной книге принципов, техник и архитектурных
подходов.
Технологии развиваются, но фундаментальные принципы качественного
CSS-кода остаются неизменными: семантичность, производительность, доступ-
ность и архитектурная чистота. Освоение этих принципов — единственный
путь к созданию веб-интерфейсов, способных адаптироваться к любым будущим
изменениям платформы.
Справочное издание
Аныцтамалык, басылым
Серия «Учимся программировать»
КЛИМОВИЧ Александр Дмитриевич
МАГИЯ CSS — САМОЕ ГЛАВНОЕ
В КРАТКОМ ИЗЛОЖЕНИИ
Ответственный за выпуск: И. В Резько
Ответственный редактор: А. В. Родионова
Оформление обложки: А. Н. Забора
Подписано в печать 13.10.2025
Формат 70x100'/]6. Бумага офсетная. Печать офсетная.
Гарнитура Noto Serif SemiCondensed.
Усл. печ. л. 11.7 Тираж 1500 экз. Заказ №
Общероссийский классификатор продукции ОК-034-2014 (КПЕС 2008);
58 11.1 — книги, брошюры печатные.
Изготовлено в 2026 г.
Произведено в Российской Федерации
Изготовитель: ООО «Издательство АСТ».
129085, Российская Федерация, г Москва, Звездный бульвар, дом 21,
строение 1, комната 705, пом. I, 7 этаж.
Адрес места осуществления деятельности по изготовлению продукции:
123112, Российская Федерация, г. Москва, Пресненская набережная, д, 6, стр. 2,
Деловой комплекс «Империя», 14, 15 этаж.
Наш электронный адрес: ask@ast.ru
Наш сайт: www.ast.ru
Интернет-магазин; www.buok24.ru
вндгрушг «Издательство АСТ» ЖШК, 129085, Ресей Федерациясы,
Мэскеу, Звездный бульвары, 21 -уй, 1-к.урылыс, 705-бел ме, I уй-жай, 7-кабат.
0н1м енд!ру к,ызмет!н жузеге асыру мекенжайы: 123112, Ресей Федерациясы, Мэскеу,
Пресненская жаг., 6-уй, 2-кур., «Империя» 1СкерЛ1к кешен1, 14, 15-к.абат.
Бздщэлектрондыкмекенжаймыз. www.ast.ru Е mail: ask@ast.ru
Интернет-магазин: www.book24.ru Интернет-дукен: www.book24.kz
Импортер в Республику Казахстан, дистрибьютор и представитель по приему претензий
на продукцию в Республике Казахстан: ТОО «РДЦ-Алматы».
г. Алматы, ул Домбровского. 3«а», литер Б, офис 1.
К,азак,стан Республикасына импорттаушы дистрибьютор жэне Казахстан Республикасында
нн1мге шагымдар к;абылдау жен1ндеп экш «РДЦ-Алматы» ЖШС.
Алматы к,., Домбровский кеш., 3«а», Б литере офис 1.
Тел.: 8(727) 2 51 59 90.91, факс: 8 (727) 251 59 92 iiiJKi 107;
E-mail: RDC-Almaty@eksmo.kz, www.book24.kz
Онд|р1лген жылы: 2025. Qhimhih жарамдылык, мерз!м! шектелмеген.
Сертификаттауга жатпайды.
Ресей Федерациясында енд|р!лген.
Создаете интерфейсы, но понимаете, что используете лишь ма-
лую часть возможностей CSS? Хотите понять внутреннюю логику
браузеров и применять ее в своих проектах — от аккуратной ти-
пографики до сложных анимаций?
Данное руководство расскажет и покажет, как CSS превраща-
ется из простого инструмента оформления в архитектурную осно-
ву современных неб-приложений.
В книге подробно рассматриваются:
• пошаговый путь от основ блочной модели до продвинутых
техник анимации и зизуальных эффектов;
• современные спецификации: контейнерные запросы, каскад-
ные слои, субгриды, логические свойства;
• практика и теория в балансе — примеры, тесты совместимо-
сти и проверенные подходы для реальных проектов.
На чем конкретно сосредоточено внимание?
• На блочной модели и принципе компоновки.
• На продвинутой работе с сетками и таблицами.
• На цвете, типографике и современных техниках стилизации.
• На переходах, анимациях, оживляющих интерфейс.
• На оптимизации, кросс-браузерности и устойчивости к изме-
няющимся требованиям.
Для кого эта книга?
• Для новичкое. — благодаря ей они начнут свой путь с прочно-
го фундамента.
• Для верстальщиков и фронтенд-разработчиков — издание
поможет им расширить инструментарий и научиться строить
масштабируемые интерфейсы.
• Для Fullslack-разработчиков — с помощью этого руководства
они лучше поймут фронтенд и смогут уверенно работать с ви-
зуальной частью приложения.
CSS — это не хаос из множества правил, а строгая система.
Освоим ее основные принципы, вы сможете создавать
интерфейсы, которые будут красивы,
удобны и предсказуемы.
книги для любого настроения здесь
ИЗДАТЕЛЬСКАЯ ГРУППА АСГ
www.ast.ru | www.book24.ru
□ vk.com/izdatelstvoast
О ok.ru/izdatelstvoast
ISBN 978-5-17-174758-9