Основы CSS верстки для веб-разработчиков
Содержание
- Фундаментальные принципы
- Нормальный поток: основа основ
- Блочная модель: из чего сделан бокс
- Особенности инлайн-боксов и схлопывание отступов
- Позиционирование: вывод элементов из потока
- Контекст наложения (Stacking Context) и z-index
- Flexbox и Grid: современные системы компоновки
- Логические свойства и адаптация к языкам
- Часто задаваемые вопросы о CSS верстке
- Как системно изучать CSS-верстку
Многие разработчики, особенно те, кто пришел в веб из других областей программирования, сталкиваются с парадоксом CSS. С одной стороны, его синтаксис кажется предельно простым: селекторы, декларации, правила и т.д.. С другой — создание даже базовых, устойчивых макетов часто превращается в хаотичное перебирание свойств и значений в надежде, что «вот сейчас заработает».
Причина этой боли кроется в фундаментальном непонимании. Нас часто учат что делать (какие свойства использовать), но почти никогда не объясняют как и почему это работает. CSS-верстка — это не язык разметки, а система взаимосвязанных алгоритмов компоновки.
Представьте, что вы пытаетесь выучить JavaScript, только глядя на синтаксис переменных и циклов, не понимая концепций замыканий, контекста выполнения или прототипов. Это обречено на провал. Данная статья — попытка построить тот самый фундамент, на котором можно уверенно строить любые интерфейсы.
Фундаментальные принципы
Первый и самый важный принцип, который нужно усвоить раз и навсегда:
В CSS всё является боксом (коробкой).
Каждый элемент на странице, будь то заголовок, параграф, ссылка или изображение, генерирует прямоугольную область (бокс). Весь процесс верстки можно свести к трем простым шагам: браузер получает множество этих боксов, затем располагает их на экране, следуя определенным алгоритмам компоновки.
Этот подход унаследован от полиграфии и вёрстки документов, где элементы тоже имеют свою область. Однако ключевое отличие веба в том, что процесс происходит динамически, «на лету», по правилам, заложенным в браузере. Исходный алгоритм, который управляет этим процессом по умолчанию, называется «нормальным потоком» (Normal Flow). Именно с него начинается любая вёрстка.
Пример 1
Свёрстанная страница в нормальном потоке.
<h1>Заголовок</h1>
<p>Параграф текста с <span>выделенным элементом</span> внутри.</p>
<ul>
<li>Элемент списка 1</li>
<li>Элемент списка 2</li>
</ul>
Нормальный поток: основа основ
Когда вы не применяете к элементам специальные свойства для изменения их поведения (вроде display: flex), они располагаются согласно нормальному потоку. Это базовый алгоритм, созданный для отображения текстовых документов. Его логика проста и соответствует чтению: в западных языках элементы выстраиваются слева направо и сверху вниз.

В CSS эти направления имеют специальные имена:
- Инлайн-направление (inline direction): основное направление текста (по умолчанию — слева направо). В этом направлении выстраиваются так называемые инлайн-элементы (текст, картинки,
<span>,<strong>). - Блочное направление (block direction): направление, в котором блоки «падают» под действием силы тяжести документа (по умолчанию — сверху вниз). В этом направлении располагаются блочные элементы (заголовки, параграфы
<p>, разделы<div>).
Браузеры поставляются со встроенной таблицей стилей, которая определяет, какие теги по умолчанию являются блочными, а какие — строчными. Именно поэтому семантически правильный HTML-документ без единой строчки CSS уже выглядит как структурированная страница.
Пример 2
Стилизация в рамках нормального потока
p {
/* Блочный элемент: имеет ширину, margin сверху/снизу */
margin-bottom: 1em;
width: 80%;
max-width: 600px;
}
strong {
/* Инлайн-элемент: обтекает текст, не ломает поток */
color: #d35400;
font-weight: bold;
}
Блочная модель: из чего сделан бокс
Понимание того, что всё — это бокс, приводит нас к ключевой концепции: блочной модели (Box Model). Она описывает, как вычисляются размеры каждого бокса. Он состоит из нескольких концентрических слоев, начиная от центра:

- Контент: внутренняя область, где отображается текст или дочерние элементы. Её размеры можно задать через
widthиheight. - Внутренний отступ: прозрачная область вокруг контента, отделяющая его от границы. Задаётся свойством
padding. - Граница: линия (или стиль), окружающая padding и контент. Задаётся свойством
border. - Внешний отступ: прозрачная область вне границы, которая отталкивает соседние элементы. Задаётся свойством
margin.
Здесь кроется историческая сложность: по умолчанию в браузерах используется модель content-box. В ней свойство width: 200px задаёт ширину только области контента. padding и border добавляются к ней снаружи, в итоге реальная ширина элемента становится больше.
Пример 3
Использование модели content-box (в браузерах по умолчанию).
.box-content {
box-sizing: content-box; /* Значение по умолчанию */
width: 200px;
padding: 20px;
border: 5px solid blue;
/* Фактическая ширина = 200px + 20px (левый паддинг) + 20px (правый паддинг) + 5px (левая граница) + 5px (правая граница) = 250px */
}
Для упрощения жизни разработчиков появилась модель border-box. В ней width: 200px задаёт ширину всего бокса целиком, включая padding и border. Область контента при этом сжимается, чтобы уместить эти значения. Эта модель интуитивно понятнее и стала стандартом де-факто.
Пример 4
Использование модели border-box (у разработчиков де-факто).
.box-border {
box-sizing: border-box; /* Рекомендуемое значение */
width: 200px;
padding: 20px;
border: 5px solid green;
/* Фактическая ширина остаётся 200px! */
/* Ширина контента = 200px - 20px - 20px - 5px - 5px = 150px */
}
Всегда добавляйте в начало ваших стилей правило, которое сбрасывает модель для всех элементов на border-box. Это сэкономит вам массу нервов.
Пример 5
Фиксируем модель border-box для всех элементов на странице.
*,
*::before,
*::after {
box-sizing: border-box;
}
Особенности инлайн-боксов и схлопывание отступов
Поведение инлайн-боксов существенно отличается от блочных. Поскольку они существуют внутри строк текста, их вертикальные отступы (margin-top, margin-bottom) и явные высоты не работают. Их границы и отступы также ведут себя неочевидно: если инлайн-элемент переносится на несколько строк, его бокс визуально «разрывается».

Пример 6
«Странное поведение» инлайн-элементов.
<p>Это длинный текст, и вот <span class="highlight">этот выделенный инлайн-элемент</span> может вести себя странно при переносе.</p>
.highlight {
background-color: yellow;
padding: 0 5px; /* Работает */
margin: 0 10px; /* Работает по горизонтали */
/* margin-top: 20px; НЕ РАБОТАЕТ! */
border-left: 2px solid red;
border-top: 2px solid red; /* Визуально разорвётся при переносе */
}
Схлопывание вертикальных отступов
Ещё одна «магия» нормального потока — схлопывание вертикальных отступов (Margin Collapse). Когда два блочных элемента расположены друг под другом, вертикальное пространство между ними определяется не суммой их отступов (margin-bottom первого + margin-top второго), а большим из этих двух значений. Это поведение унаследовано от типографики для равномерного распределения абзацев.

Пример 7
Схлопывание вертикальных отступов.
.block-a {
margin-bottom: 40px;
background: lightblue;
}
.block-b {
margin-top: 20px; /* Этот отступ СХЛОПНЕТСЯ с margin-bottom: 40px сверху */
background: lightcoral;
}
/* Итоговое расстояние между элементами — 40px, а не 60px. */
Схлопывание также происходит между родителем и первым/последним дочерним элементом, если между ними нет «преграды» (границы, внутреннего отступа или контента). Чтобы его предотвратить, можно:
- Добавить родителю
padding-top: 1pxилиborder-top: 1px solid transparent. - Использовать более современный и чистый способ: создать новый контекст форматирования с помощью
display: flow-root.
Пример 8
Предотвращаем схлопывание вертикальных отступов.
.parent {
display: flow-root; /* Лучший способ предотвратить схлопывание */
background: #eee;
}
.child {
margin-top: 30px; /* Теперь отступ останется внутри родителя */
}
Собери свой код. Запусти сайт!
От наброска на салфетке до первого работающего лендинга. Наш онлайн-курс «Веб-верстка с нуля и до профессионала» — это интенсивный трек, где ты не будешь зубрить теорию, а с первого дня начнешь превращать идеи в чистый HTML и CSS.
Собери свой первый проект под руководством практикующих разработчиков.
Позиционирование: вывод элементов из потока
Алгоритм позиционирования (Positioning) позволяет нам вручную управлять расположением боксов, вплоть до полного вывода их из нормального потока. Это ключ к созданию сложных, многослойных интерфейсов. Активируется свойством position.
| Значение | Находится в потоке? | Точка отсчёта | Основное назначение |
|---|---|---|---|
| static (по умолчанию) | Да | Не применимо | Обычное поведение в потоке. |
| relative | Да | Его обычное место в потоке | Создание контекста для абсолютно позиционированных детей. Смещение элемента относительно себя самого (свойства top, left). |
| absolute | Нет | Ближайший предок с position не static | Точное позиционирование внутри заданной области (например, иконка внутри кнопки). |
| fixed | Нет | Окно просмотра (viewport) | Элементы, закреплённые на экране (шапка, модальные окна). |
| sticky | Да (до «прилипания») | Ближайший прокручиваемый предок | Гибридная модель: элемент ведёт себя как relative, пока не достигнет заданной позиции на экране, затем «прилипает» как fixed. |
Знание того, как работает margin в связке с фиксированной шириной, позволяет легко центрировать блочный элемент.
Пример 9
Центрирование элемента по горизонтали.
.centered-block {
width: min(600px, 100%); /* Фиксированная или процентная ширина */
margin-left: auto; /* Браузер вычисляет отступ слева */
margin-right: auto; /* Браузер вычисляет отступ справа */
/* Доступное пространство по горизонтали делится поровну между двумя auto-отступами. */
}
Контекст наложения (Stacking Context) и z-index
Когда мы начинаем двигать элементы с помощью позиционирования, они могут начать перекрывать друг друга. Так мы входим в третье измерение CSS — глубину, управляемую свойством z-index. Однако z-index работает не в вакууме, а внутри контекстов наложения (Stacking Context).
Контекст наложения — это изолированный слой. z-index элемента влияет только на его положение внутри контекста наложения своего родителя. Самый распространённый способ создать новый контекст — задать элементу position (кроме static) и z-index (кроме auto). Это же делают opacity < 1, transform, filter и другие свойства.
Проблема
Элемент с z-index: 1000 может быть перекрыт элементом с z-index: 1, если первый находится внутри контекста наложения с низким z-index, а второй — в контексте с более высоким.
Пример 10
Особенности наложения элементов.

<div class="parent-a" style="position: relative; z-index: 1;">
<div class="child" style="position: absolute; z-index: 1000;">Я внутри parent-a</div>
</div>
<div class="parent-b" style="position: relative; z-index: 2;">
<div class="child" style="position: absolute; z-index: 1;">Я внутри parent-b</div>
</div>
В этом примере синий блок (z-index: 1) будет поверх фиолетового (z-index: 1000), потому что контекст наложения parent-b (z-index: 2) находится выше parent-a (z-index: 1).
Для явного создания контекста без побочных эффектов позиционирования используйте isolation: isolate.
Пример 11
Применение нового контекста наложения с помощью isolation: isolate.
.modal-overlay {
isolation: isolate; /* Создаёт новый контекст наложения */
/* Теперь z-index детей модального окна не будет «конкурировать» с z-index элементов вне этого оверлея */
}
Flexbox и Grid: современные системы компоновки
Если нормальный поток и позиционирование решали задачи вёрстки документов, то Flexbox и Grid были созданы для построения сложных, адаптивных интерфейсов веб-приложений. Они представляют собой принципиально иные, более мощные и предсказуемые алгоритмы компоновки.
Flexbox (одномерная компоновка) фокусируется на распределении пространства и выравнивании элементов вдоль одной оси (горизонтальной или вертикальной). Его философия — дать контейнеру возможность гибко управлять размерами и порядком своих непосредственных детей.
Пример 12
Применение одномерной компоновки.
.flex-container {
display: flex; /* Включаем алгоритм Flexbox */
justify-content: space-between; /* Распределяем дочерние элементы по главной оси */
align-items: center; /* Выравниваем элементы по поперечной оси по центру */
flex-wrap: wrap; /* Позволяем перенос на новую строку */
}
.flex-item {
flex: 1 1 200px; /* Сочетание роста, сжатия и базового размера */
}
CSS Grid (двумерная компоновка) позволяет вам сначала определить сетку (строки и колонки), а затем точно размещать элементы в созданных областях. Это делает Grid идеальным для макетов всего сайта.
Пример 13
Применение двумерной компоновки.
.grid-container {
display: grid; /* Включаем алгоритм Grid */
grid-template-columns: 1fr 2fr 1fr; /* Определяем три колонки */
grid-template-rows: auto 1fr auto; /* Определяем три строки */
gap: 20px; /* Расстояние между элементами сетки */
grid-template-areas:
"header header header"
"sidebar main ads"
"footer footer footer";
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
Ключевое отличие от старой модели: и Flexbox, и Grid используют современную, единую систему выравнивания (align-items, justify-content), которая больше не зависит от свойств шрифта (как vertical-align) и работает предсказуемо, ориентируясь на границы боксов.
Логические свойства и адаптация к языкам
CSS развивается в сторону независимости от физического направления. Не все языки пишутся слева направо (арабский, иврит), а некоторые — сверху вниз (классический китайский, японский). Логические свойства заменяют физические понятия («верх», «низ», «лево», «право») на логические, связанные с режимом письма (writing-mode).
- Вместо
width/height—inline-size/block-size. - Вместо
margin-left—margin-inline-start. - Вместо
top/bottomпри позиционировании —inset-block-start/inset-block-end.
Использование логических свойств делает ваш код более устойчивым и адаптируемым.
Пример 14
Применяем логические свойства.
.card {
/* Физические свойства */
margin-left: 1rem;
padding-top: 2rem;
border-right: 2px solid;
/* Логические эквиваленты (рекомендуется) */
margin-inline-start: 1rem;
padding-block-start: 2rem;
border-inline-end: 2px solid;
}
/* Если поменять writing-mode родителя, логические свойства адаптируются автоматически. */
Часто задаваемые вопросы о CSS верстке
Почему margin-top дочернего элемента «выпадает» из родителя?
Это происходит из-за схлопывания вертикальных отступов. Если между margin-top первого дочернего элемента и margin-top родителя нет «преграды» (границы, внутреннего отступа или контента), браузер объединяет эти отступы, применяя результат за пределами родительского блока. Чтобы этого избежать, создайте новый контекст форматирования для родителя с помощью display: flow-root или добавьте ему padding-top: 1px.
Когда использовать Flexbox, а когда Grid?
Используйте Flexbox для выравнивания и распределения элементов вдоль одной оси (горизонтальной или вертикальной), например, для навигационной панели, списка карточек или центрирования содержимого. CSS Grid выбирайте, когда вам нужен контроль над компоновкой по двум осям одновременно — создание сложных макетов страниц, сеток карточек с выравниванием по строкам и колонкам. Они отлично дополняют друг друга: Grid может задавать общую структуру макета, а Flexbox — управлять содержимым внутри его ячеек.
Что такое «содержащий блок» (containing block) и почему это важно?
Содержащий блок — это прямоугольная область, относительно которой вычисляются размеры и положение текущего элемента. Например, процентная ширина width: 50% берётся от ширины содержащего блока. Понимание этого критично для работы с процентами и абсолютным позиционированием: для position: absolute содержащим блоком становится ближайший предок с position, отличным от static, а не просто родительский div.
Почему z-index иногда не работает?
Свойство z-index действует только в пределах одного контекста наложения (stacking context). Если ваш элемент находится внутри контекста с низким z-index, он никогда не сможет «перепрыгнуть» элемент из контекста с более высоким z-index, даже если его собственное значение огромно. Контекст создают не только position и z-index, но и свойства вроде opacity (меньше 1) или transform. Решение — вынести элементы в один контекст или явно управлять созданием контекстов с помощью isolation: isolate.
В чём разница между box-sizing: content-box и border-box?
Это два разных алгоритма расчёта размеров элемента. При box-sizing: content-box (значение по умолчанию) свойства width и height задают размер только области контента, а padding и border добавляются к нему снаружи. В модели border-box свойства width и height определяют размер всего бокса целиком (включая padding и border), что делает расчёты интуитивно понятнее. Именно поэтому * { box-sizing: border-box; } стало стандартом для большинства CSS-сбросов.
Как правильно центрировать элемент по вертикали в современном CSS?
Самый простой и универсальный современный способ — использование place-content: center на контейнере, у которого задана высота. Это работает для элементов с display: grid, display: flex и даже для display: block (при поддержке браузером). Альтернативно, во Flexbox можно использовать комбинацию align-items: center и justify-content: center, а в Grid — place-items: center. Главное — помнить, что для вертикального центрирования у контейнера должна быть явно заданная высота.
Зачем нужны логические свойства в CSS?
Логические свойства (например, margin-inline-start вместо margin-left) привязывают стили не к физическим сторонам экрана («левый», «правый»), а к началу и концу контекста письма (writing mode). Это делает ваш код адаптивным не только к разным размерам экрана, но и к разным языкам и направлениям письма (слева-направо, справа-налево, сверху-вниз). Использование логических свойств — это шаг к созданию по-настоящему интернациональных и доступных интерфейсов.
Как системно изучать CSS-верстку
Освоение CSS-верстки — это не заучивание сотен свойств, а понимание нескольких ключевых систем и их взаимодействия. Начните с прочного фундамента: боксовая модель и нормальный поток. Затем освойте механизмы выхода из потока — позиционирование. Только после этого переходите к мощным инструментам компоновки — Flexbox и Grid. Понимание контекстов наложения и логических свойств станет завершающим штрихом, который превратит вас из того, кто «подбирает стили», в того, кто уверенно проектирует макеты.
Хотите перейти от теории к практике и научиться применять эти концепции для создания современных, адаптивных и сложных интерфейсов под руководством опытных наставников? Запишитесь на наш интенсивный онлайн-курс по продвинутому CSS и вёрстке в нашей веб-студии. Мы разберём реальные кейсы, выстроим чёткую систему знаний, и вы начнёте не бояться макетов, а управлять ими.