CSS позиционирование
Организация расположения элементов – одна из ключевых задач CSS. За годы развития CSS появилось несколько подходов к созданию макетов страниц и выравниванию блоков.
HTML-элементы делятся на блочные (block) и строчные (inline) по типу отображения по умолчанию. Блочные элементы формируют прямоугольный блок, занимают всю доступную ширину контейнера и начинаются с новой строки. Например, абзацы <p>, заголовки <h1>-<h6>, блоки <div> – они автоматически размещаются один под другим. Строчные элементы, напротив, не разрывают поток текста, их ширина подстраивается под содержимое, и они располагаются в строке друг за другом. К ним относятся: <span>, <a>, <strong>, <em>, <img> и др.
Свойство CSS display управляет этим поведением. Можно переключать элемент из блочного в строчный и наоборот: display: block; заставит элемент вести себя как блок (новая линия, можно задавать ширину/высоту), а display: inline; – как строчный (не имеет собственных переносов строки, игнорирует свойства ширины/высоты).
Также существует промежуточный вариант
display: inline-block;– элемент ведёт себя как строчный (располагается в ряд), но при этом остается прямоугольным блоком по содержимому, принимая размеры и допуская внешние отступы.
Кроме этих, display имеет и другие значения. В современном CSS используются Flexbox и Grid, которые позволяют выстроить расположение компонентов на странице.
Flexbox
Flexbox (Flexible Box Layout) – это модуль CSS, предлагающий гибкий способ расположения элементов вдоль одной оси (горизонтально или вертикально) с автоматическим распределением пространства. Он отлично подходит для выравнивания элементов внутри контейнера, создания адаптивных рядов элементов (например, меню, панели инструментов, карточек) и т.д. Чтобы использовать Flexbox, нужно объявить у контейнера display: flex;.
Дочерние элементы этого контейнера автоматически становятся flex-элементами и располагаются по следующим правилам:
- Оси: основная ось (main axis) по умолчанию горизонтальная (вдоль строки), перекрёстная ось (cross axis) – вертикальная. Их можно поменять, задав
flex-direction: column;(тогда основная ось станет вертикальной); - Свойство
justify-contentуправляет выравниванием элементов вдоль основной оси: можно прижать их к левому/верхнему краю (flex-start), правому/нижнему (flex-end), центрировать (center), равномерно распределить свободное пространство между элементами (space-between,space-around, …); - Свойство
align-itemsуправляет выравниванием по перекрёстной оси: например,align-items: center; выровняет все элементы по центру поперёк контейнера (вертикально, если flex-ряд горизонтальный); - Элементы внутри могут растягиваться или сжиматься. Свойства гибкости (
flex-grow,flex-shrink,flex-basisили краткоflex) задают, как элемент тянется при наличии пространства. Например,flex: 1;заставит все дочерние поделить место поровну.
Например, ранее созданный вами navbar с использованием flexbox мог быть организован следующим образом:
<header class="navbar">
<div class="logo">Мой сайт</div>
<nav class="menu">
<a href="#">Главная</a>
<a href="#">О нас</a>
<a href="#">Контакты</a>
</nav>
</header>.navbar {
display: flex;
justify-content: space-between; /* Раздвинуть содержимое по краям */
align-items: center; /* Вертикально центрировать элементы */
padding: 1rem;
background: #333;
}
.navbar .logo {
color: #fff;
font-size: 1.5rem;
}
.navbar .menu a {
color: #fff;
margin-left: 1rem;
text-decoration: none;
}Если бы все пункты в меню не помещались в одну строку, тогда можно было бы добавить дополнительные обработчики. Например, можно добавить свойство flex-wrap: wrap; чтобы меню переносилось на новую строку при нехватке места.
Flexbox хорошо подходит для однострочных или одностолбцовых наборов элементов, чья суммарная ширина неизвестна заранее (например, меню с пунктами, которые должны равномерно распределяться).Современные страницы часто строятся как комбинация flex-контейнеров для структурных блоков (header, панели, галереи и т.п.).
Для закрепления необходимо будет ознакомиться с интерактивной шпаргалкой: Типичный верстальщик: Шпаргалка по Flexbox CSS. В ней представлены все основные свойства использующиеся в Flexbox.
Также на выбор необходимо будет пройти одну из интерактивных игр:
- Более интрересное визуальное оформление, больше информации. Единственный нюанс, что поддерживается только английский язык. Ссылка: Flex Box Adventure.
- Чуть более упрощенный вариант. Есть поддержка русского языка. Ссылка: Flexbox Froggy.
Grid
СSS Grid Layout – ещё более мощный модуль для создания макетов. Если Flexbox ориентирован на размещение по одному направлению, то Grid – на двумерную сетку, позволяя управлять размещением элементов по строкам и столбцам одновременно. Чтобы применить grid, у контейнера задаётся display: grid;. Далее с помощью свойств описывают структуру колонок и строк:
-
grid-template-columnsиgrid-template-rows– определяют размеры колонок и строк сетки. Можно задать фиксированные величины или относительные. Например:grid-template-columns: 200px 1fr 1fr;– первая колонка 200px, а две следующие делят остальное пространство поровну (fractions – доли свободного места).Единица fr удобна для адаптивных макетов.
Можно использовать функцию repeat() для краткости. Например, grid-template-columns: repeat(3, 1fr); создаст три равные колонки по 1fr каждая.
-
gap(или отдельноcolumn-gap/row-gap) задаёт расстояние между ячейками сетки (аналог отступов между колоночками).
Дочерние элементы (grid items) могут управляться автоматически или явно позиционироваться на сетке. По умолчанию элементы заполняют сетку по порядку слева направо, сверху вниз. Но мы можем указать конкретному элементу занимать, например, две колонки или две строки (через CSS-свойства у grid-элемента: grid-column: 1 / span 2; – занять 2 колонки начиная с первой, grid-row: 1 / 3; – занять строки 1 по 2).
Предположим, у нас раздел страницы с карточками товаров, который должен показывать по 3 карточки в ряд на широком экране, по 2 на планшете и 1 на мобильном:
<div class="products-grid">
<div class="product">Товар 1</div>
<div class="product">Товар 2</div>
<div class="product">Товар 3</div>
<div class="product">Товар 4</div>
<!-- ... -->
</div>CSS:
.products-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1rem; /* Отступ между карточками */
}
.product {
background: #f0f0f0;
padding: 1rem;
}Здесь свойство grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)) означает: “создай столько колонок, сколько помещается по ширине (auto-fit), минимальный размер колонки 250px, а максимальный – 1fr (распределить оставшееся пространство)”. Таким образом, на широком экране карточки выстроятся в несколько колонок, при сужении экрана число колонок автоматически уменьшится (grid сам перестроится), вплоть до одной колонки на очень узком экране. Grid – основа современного CSS-макета, обеспечивающая две оси размещения. По состоянию на середину 2020-х, Grid поддерживается всеми современными браузерами и широко применяется в производственных проектах.
Интерактивная шпаргалка от тех же авторов, что и по Flexbox: Типичный верстальщик: Шпаргалка по Grid CSS.
Для изучения Grid также есть интерактивные игры, которые позволяют глубже понять и закрепить принципы позиционирования контента с её использованием:
- Ссылка на более интересный и обширный вариант на английском языке: Grid Attack.
- Вариант на русском языке от создателей Flexbox Froggy: Grid Garden.
Flex vs Grid: Flexbox лучше использовать для одномерного размещения (например, центрирование блока, расположение элементов меню в ряд, выравнивание элементов внутри карточки), а Grid – для макетов 2D (табличные сетки, страничные шаблоны).
Поток элементов
По умолчанию браузер размещает элементы в нормальном потоке страницы: блоки сверху вниз, строчные слева направо (для языков с письмом слева-направо), с учётом переносов строк. CSS позволяет изменять этот поток.
Исторически, для создания колонок и обтекания текста вокруг изображений применялось свойство float. Например, картинке можно задать float: left;, и она «всплывёт» влево, а следующий за ней текст обтечёт её справа. Сейчас float чаще используется для обтекания текста вокруг небольших блоков (например, изображения в статье).
Позиционирование в CSS — это механизм, который позволяет точно указывать, где элементы будут располагаться на странице. В CSS позиционирование управляет расположением элементов относительно других элементов или родительских контейнеров. Свойство position задаёт способ позиционирования элемента на странице, а свойства top, right, bottom и left определяют точное смещение элементов на странице.
К основным можно отнести следующие стили позиционирования:
Static (Статическое позиционирование)
Значение по умолчанию. Элементы, у которых установлено это значение, располагаются в потоке документа по мере их появления в HTML-разметке. Свойства top, left, right, и bottom не применяются.
- Элемент находится в нормальном потоке документа.
- Свойства смещения не оказывают влияния.
- Не создаёт новый контекст наложения (stacking context).
В данном примере блок с классом
.staticбудет располагаться в потоке документа на своём обычном месте.
Relative (Относительное позиционирование)
Относительное позиционирование позволяет смещать элемент относительно его исходного положения в нормальном потоке документа. Элемент остаётся в потоке, и место под него сохраняется, но визуально он может быть смещён.
- Элемент остаётся на своём месте в потоке.
- Свойства
top,right,bottom, иleftсмещают элемент относительно его исходного положения. - Создаёт новый контекст наложения, если установлен
z-index.
В этом примере блок с классом
.relativeсмещён вниз на 20px и вправо на 30px, при этом место под ним остаётся неизменным.
Absolute (Абсолютное позиционирование)
Абсолютное позиционирование позволяет полностью удалить элемент из нормального потока документа. Элемент позиционируется относительно ближайшего родителя, у которого установлено значение position, отличное от static. Если такого родителя нет, элемент будет позиционироваться относительно окна браузера.
- Элемент удаляется из нормального потока.
- Позиционируется относительно ближайшего позиционированного родителя.
- Создаёт новый контекст наложения, если установлен
z-index.
Здесь элемент с классом
.absoluteбудет позиционироваться относительно его родителя с классом.relativeи смещён на 50px вниз и на 20px вправо. Родитель остаётся в потоке, но дочерний элемент — нет.
Fixed (Фиксированное позиционирование)
Фиксированное позиционирование удаляет элемент из потока и закрепляет его относительно окна браузера. Элемент остаётся на одном месте на экране при прокрутке страницы.
- Элемент позиционируется относительно окна браузера.
- Не изменяет своё положение при прокрутке.
- Создаёт новый контекст наложения, если установлен
z-index.
Элемент с классом
.fixedбудет закреплён в правом верхнем углу и останется на одном месте при прокрутке страницы.
Sticky (Липкое позиционирование)
Липкое позиционирование совмещает поведение статического и фиксированного позиционирования. Элемент сначала ведёт себя как обычный, но при прокрутке “залипает” на экране, если достигается определённая точка.
- Элемент ведёт себя как обычный, пока не достигнет порога прокрутки.
- После достижения порога элемент фиксируется в пределах родителя или экрана.
- Создаёт новый контекст наложения, если установлен
z-index.
В этом примере элемент с классом
.stickyбудет оставаться на месте, пока не достигнет верхней границы окна браузера, а затем “прилипнет” к ней при дальнейшей прокрутке.
Адаптивность
Адаптивный (Responsive Web Design) дизайн обозначает, что веб-страница корректно выглядит и функционирует на устройствах с разными размерами экрана. CSS предоставляет различные инструменты для создания адаптивности, основными из которых долгое время были медиазапросы.
Обычно стили для мобильных устройств определяют первыми (mobile-first подход) – то есть CSS пишется под маленький экран по умолчанию, а затем медиазапросами
min-widthдобавляют улучшения для больших экранов. Это считается хорошей практикой, так как мобильные устройства получают минимально необходимый CSS, а десктопам загружается добавочный, при этом каскад удобнее контролировать. Однако возможен и обратный подход (desktop-first, используяmax-widthкак в примере выше). Главное – поддерживать читаемость и логичность кода.
CSS Media Queries (медиазапросы)
Медиазапросы позволяют применять CSS-правила только при выполнении определённых условий, чаще всего – условий по размеру экрана (viewport). Синтаксис медиазапроса использует директиву @media. Например:
/* Базовый стиль для всех экранов */
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
/* Медиазапрос для экранов шириной <= 768px (планшеты, мобильные) */
@media (max-width: 768px) {
.container {
grid-template-columns: 1fr 1fr; /* 2 колонки вместо 3 */
}
}
/* Медиазапрос для экранов <= 480px (мобильные) */
@media (max-width: 480px) {
.container {
grid-template-columns: 1fr; /* 1 колонка на маленьких экранах */
}
}Изначально контейнер делится на 3 колонки по умолчанию. Далее, медиазапросы изменяют шаблон колонок при определённых ширинах экрана: на планшетах (768px и меньше) будет 2 колонки, на смартфонах (480px и меньше) – 1 колонка.
Медиазапросы могут проверять разные свойства среды, помимо ширины. Например: min-width/max-width (самые распространённые), orientation (ориентация устройства: портрет/альбом), prefers-color-scheme (темная/светлая тема предпочтительна), resolution (плотность пикселей, для ретины) и многие другие. Можно объединять условия (операторы and, or и not). Современные браузеры даже поддерживают особенности, вроде pointer: coarse (сенсорный экран) или hover: none (нет возможности наведения мышью) – полезно, чтобы, например, отключить эффекты hover на сенсорных устройствах или увеличить интерактивные элементы для пальцев.
Container Queries (контейнерные запросы)
Относительно недавно в CSS появились контейнерные запросы – новый механизм, позволяющий применять стили в зависимости от размеров родительского контейнера, а не всего экрана. Это делает компоненты более автономными и отзывчивыми к своему окружению. Контейнерные запросы вводятся правилом @container. Чтобы элемент стал контейнером, на него нужно повесить свойство container-type. Например:
.card-container {
container-type: inline-size;
}Значение inline-size означает, что будем реагировать на изменение ширины контейнера (существует также тип size для обоих измерений). Теперь внутри этого контейнера можно писать условные правила:
@container (min-width: 500px) {
.card {
flex-direction: row;
}
}Если ширина контейнера .card-container больше 500px, то стилизовать .card (внутри него) определенным образом – например, расположить содержимое в ряд (flex-direction: row) вместо колонки. Таким образом правило будет зависеть от ширины самого контейнера, в котором находится карточка, а не от ширины экрана.
Контейнерные запросы – относительно свежая возможность (широко поддерживается начиная с 2023 года) и в 2025-м уже применяется для разработки “понастоящему адаптивных” компонентов. Чтобы использовать их, нужно понимать и cascade layers (@layer) для предотврашения конфликтов, но базовый пример выше показывает суть:
@containerправила похожи на@media, но привязаны к элементу-контейнеру. Отслеживать какие браузеры поддерживают эту функциональность можно на при помощи ресурса Can I Use.



