Как центрировать в CSS через Flexbox, Grid, Position и Margin
Оглавление статьи

Чтобы центрировать блок по горизонтали и вертикали, обычно достаточно Flexbox с justify-content: center и align-items: center либо Grid с place-items: center. Если нужно поставить обычный блок только посередине строки, используйте ограничение ширины и margin-inline: auto. Абсолютное позиционирование оставьте для элементов, которые должны находиться поверх другого содержимого.
Способ зависит не только от желаемого результата, но и от того, что вы выравниваете: текст, сам блок, группу кнопок или элементы сетки. Разберём четыре подхода на собственных примерах, а затем проверим длинный текст и ситуацию, когда элемент больше доступной области.
Условия примеров: обычное горизонтальное направление письма writing-mode: horizontal-tb. Материал проверен 24 сентября 2026 года. Примеры выполнены в Chromium 144.0.7559.96 на ширинах 320, 768 и 1280 пикселей; отдельно проверены длинный текст и увеличенный шрифт. Это не проверка Safari, Firefox или реальных мобильных устройств. Там, где направление осей зависит от режима раскладки, оно указано отдельно.
Какой способ центрирования выбрать
Задача | Решение | Где задавать |
|---|---|---|
Текст или строчное содержимое по горизонтали |
| На содержащем его блоке |
Блочный контейнер по горизонтали | Ограниченная ширина и | На самом контейнере |
Карточка по двум осям | Flexbox или | На родителе карточки |
Ряд кнопок как группа | Flexbox с | На родителе кнопок |
Каждый элемент внутри своей ячейки |
| На Grid-контейнере |
Сетка целиком внутри свободного места |
| На Grid-контейнере |
Значок или подпись поверх блока |
| На наложенном элементе; опорный контейнер задаётся отдельно |
Эта таблица — отправная рекомендация, а не запрет других сочетаний. Базовые приёмы Flexbox и Grid показаны в рецепте центрирования MDN. Главное ограничение любого выравнивания: для заметного перемещения должно оставаться свободное пространство.
Подготовим блок для экспериментов
Используем одну карточку с подтверждением заявки. Разметка для первых примеров:
<div class="stage">
<div class="card">Заявка отправлена</div>
</div>Общие стили:
*, *::before, *::after {
box-sizing: border-box;
}
body {
margin: 0;
font-family: sans-serif;
}
.card {
width: min(100%, 22rem);
padding: 1rem;
border: 1px solid;
overflow-wrap: anywhere;
}border-box включает внутренние отступы и границы в заданную ширину. overflow-wrap: anywhere позволяет переносить длинный непрерывный текст. Это настройки размеров и переноса, а не собственно центрирование. Их поведение описано в справке box-sizing и overflow-wrap.
Для каждого следующего способа оставляйте общие стили, но заменяйте предыдущий вариант раскладки новым. Если одновременно сохранить position: absolute, автоматические отступы и старый transform, вы будете проверять их комбинацию, а не отдельный приём.
Центрирование через Flexbox
Добавьте к общим стилям:
.stage {
display: flex;
justify-content: center;
align-items: center;
min-height: 18rem;
padding: 1rem;
}Карточка окажется в центре внутренней области контейнера. Минимальная высота 18rem нужна здесь, чтобы увидеть вертикальное выравнивание. В реальном макете пространство может появиться иначе: например, из размеров родительской сетки. Фиксированная высота не является обязательным условием Flexbox.
justify-content распределяет свободное место вдоль главной оси, а align-items выравнивает элементы по поперечной. Если карточка заняла всю ширину, горизонтальное центрирование не даст заметного сдвига: свободного места по бокам уже нет.
Почему оси меняются при flex-direction: column
Нельзя навсегда запомнить justify-content как «горизонталь». Главная ось определяется flex-direction, а физическое направление связано и с режимом письма.
При horizontal-tb | Главная ось | Поперечная ось |
|---|---|---|
| Горизонтальная: | Вертикальная: |
| Вертикальная: | Горизонтальная: |
Например, несколько карточек можно собрать в центрированную колонку:
.stage {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-height: 18rem;
padding: 1rem;
gap: 1rem;
}Если в разметке несколько соседних карточек, justify-content: center центрирует их группу по главной оси, а не помещает каждую в одну точку. Для горизонтальной группы оставьте row. Свойство align-self позволяет отдельно переопределить поперечное выравнивание одного flex-элемента.
align-content не заменяет align-items в обычном однострочном Flexbox с flex-wrap: nowrap. Оно распределяет линии многострочного flex-контейнера по поперечной оси. Эта граница разобрана в руководстве web.dev по Flexbox.
Центрирование через CSS Grid
Для одной карточки решение короче:
.stage {
display: grid;
place-items: center;
min-height: 18rem;
padding: 1rem;
}place-items объединяет align-items и justify-items. В Grid они выравнивают элементы внутри выделенных им областей. Для одного автоматически размещённого элемента в простой сетке результат выглядит как центр родителя.
Но при нескольких элементах у каждого своя ячейка. Поэтому place-items: center не означает «собрать все элементы в общую центральную группу». Для отдельной карточки настройку можно задать через place-self: center, не меняя выравнивание остальных.
Чем place-items отличается от place-content
Items выравнивает элементы внутри ячеек, content — строки и колонки сетки внутри контейнера. Различие видно, когда сетка занимает меньше места, чем родитель, а её элементы меньше ячеек. Это разные операции в спецификации Grid.
<div class="tiles">
<div class="tile">Один</div>
<div class="tile">Два</div>
</div>.tiles {
display: grid;
grid-template-columns: repeat(2, minmax(0, 8rem));
place-content: center;
place-items: center;
gap: 1rem;
min-height: 18rem;
padding: 1rem;
}
.tile {
width: 6rem;
max-width: 100%;
padding: 0.5rem;
border: 1px solid;
}Здесь place-content: center располагает две колонки с промежутком по центру, а place-items: center выравнивает каждую плитку внутри своей ячейки. Уберите второе свойство — плитки с заданной шириной сместятся к началу ячеек. Уберите первое — расположение самих колонок изменится. Порядок выравнивания подробно разобран в руководстве MDN по Grid.
place-items: center не является универсальной заменой двух свойств Flexbox. Его часть justify-items не выравнивает flex-элементы по главной оси. Для Flexbox используйте justify-content вместе с align-items.
Margin: auto — когда достаточно отступов
Обычный блок по горизонтали
Чтобы центрировать контейнер с текстом, не обязательно менять родителя на Flexbox или Grid:
.stage {
padding: 1rem;
}
.card {
width: min(100%, 22rem);
margin-inline: auto;
}При обычном горизонтальном письме margin-inline: auto задаёт автоматические отступы слева и справа. Если блок уже родителя, положительное свободное пространство распределяется между ними поровну. Это правило описывает модель ширины и отступов CSS.
Не обязательно указывать ширину в пикселях: в примере она не превышает 22rem и доступную ширину. Можно ограничить блок через max-width. А вот полноширинный блок не станет визуально уже от одного margin: auto.
margin-inline — логическое свойство: при другом режиме письма оно не обязано означать именно левую и правую стороны. Сопоставление приведено в справке margin-inline.
Flex-элемент по двум осям
У автоматических отступов другой полезный сценарий: единственный элемент внутри Flexbox можно центрировать так:
.stage {
display: flex;
min-height: 18rem;
padding: 1rem;
}
.card {
margin: auto;
}Четыре автоматических отступа забирают положительное свободное пространство. Во Flexbox оно распределяется до выравнивания через justify-content и align-self; поэтому смешивание этих механизмов может скрыть ожидаемый эффект. Поведение закреплено в спецификации Flexbox.
В обычном блочном потоке margin-top: auto и margin-bottom: auto сами по себе так не центрируют. Фраза «margin auto работает по двум осям» верна только вместе с указанием подходящего контекста раскладки.
Position и transform: центрирование наложенного элемента
Абсолютное позиционирование подходит, например, для подписи поверх области предпросмотра. Для обычной карточки в документе предпочтительнее сохранить участие в потоке.
.stage {
position: relative;
min-height: 18rem;
}
.card {
position: absolute;
top: 50%;
left: 50%;
width: min(22rem, calc(100% - 2rem));
transform: translate(-50%, -50%);
}В этом примере position: relative делает .stage опорным контейнером. absolute убирает карточку из обычного потока: она больше не увеличивает высоту родителя. Другие свойства предков тоже могут создавать containing block, поэтому в сложном макете нельзя автоматически считать им непосредственного родителя. Условия описаны в справке position.
Зачем нужны top: 50% и translate(-50%, -50%) одновременно
top и left здесь отсчитывают проценты от размеров содержащего блока и ставят начало карточки на середину области. Затем translate() сдвигает её обратно на половину собственных размеров. Для обычного HTML-блока в показанном примере проценты трансформации берутся от его собственной коробки, а не от родителя.
У области 400 × 240 пикселей и карточки 100 × 60 центрированная позиция будет 150 пикселей слева и 90 сверху: 200 − 50 и 120 − 30. Одних top: 50%; left: 50% недостаточно — в середину попадёт угол, а не центр карточки. Отсчёт процентов определён в CSS Transforms.
translate() — функция двумерного переноса внутри transform, а не сокращение трёх свойств. Есть и самостоятельное CSS-свойство translate: вместо строки transform: translate(-50%, -50%) можно написать translate: -50% -50%. Не оставляйте оба варианта одновременно — смещения складываются.
Центрирование не гарантирует, что большой элемент поместится в небольшую область. Абсолютная карточка может перекрыть соседнее содержимое и выйти за границы. Используйте этот приём там, где наложение намеренное; для формы с непредсказуемой высотой начните с обычного потока.
Как центрировать текст, кнопку и изображение
text-align: center выравнивает строчное содержимое внутри блока: текст, строчные изображения, inline-block и inline-flex. Оно не переносит обычный дочерний блок заданной ширины в центр родителя.
Например, у кнопки есть две независимые задачи: расположить саму кнопку посередине области и совместить значок с подписью внутри неё.
<div class="button-slot">
<button class="action" type="button">
<span aria-hidden="true">✓</span>
<span>Отправить заявку</span>
</button>
</div>.button-slot {
text-align: center;
padding: 1rem;
}
.action {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
min-height: 2.75rem;
max-width: 100%;
padding: 0.625rem 1rem;
font: inherit;
}Родитель центрирует inline-flex-кнопку по горизонтали, а Flexbox кнопки выравнивает её содержимое. Для изображения можно выбрать такой же строчный сценарий либо сделать его блочным и применить ограничение ширины с margin-inline: auto. Не забывайте сохранить пропорции через height: auto, если меняете ширину.
vertical-align: middle не центрирует произвольный div по высоте родителя. Оно работает со строчными элементами, inline-block и ячейками таблицы в их собственных контекстах. Границы свойства приведены в документации vertical-align.
Блок по центру экрана, который не ломается от длинного текста
Для отдельной страницы подтверждения используем обычный поток и минимальную высоту экрана. Разметка заменяет предыдущий учебный контейнер:
<main class="screen">
<section class="card" aria-labelledby="result-title">
<h1 id="result-title">Заявка отправлена</h1>
<p>Проверьте почту: мы прислали подтверждение.</p>
</section>
</main>К общим стилям добавьте:
.screen {
display: flex;
min-height: 100vh;
min-height: 100dvh;
padding: 1rem;
}
.screen > .card {
width: min(100%, 28rem);
min-width: 0;
margin: auto;
}Пока карточка помещается, она центрируется. Если текста стало больше экрана, контейнер может вырасти, а содержимое остаётся доступным при обычной прокрутке. Это лучше, чем обязательно держать большой блок в геометрическом центре фиксированной высоты и потерять его начало за верхней границей.
Первая строка с 100vh служит запасным вариантом, следующая задаёт высоту динамической области просмотра. dvh учитывает изменение браузерных панелей на мобильных устройствах, но не решает автоматически все случаи с экранной клавиатурой. Ограничения разобраны в обзоре единиц viewport. Если над блоком есть шапка, этот рецепт центрирует страницу целиком, а не свободную область под шапкой: для неё нужен отдельный контейнер.
Проверьте устойчивость: замените короткую подпись несколькими абзацами, вставьте длинное слово без пробелов, уменьшите ширину до 320 пикселей и увеличьте шрифт. Начало текста должно оставаться доступным, а горизонтальная прокрутка не должна появляться из-за карточки. Правильный центр на одном скриншоте — только первая проверка.
Почему центрирование не работает: проверка по шагам
Симптом | Что проверить |
|---|---|
Нет вертикального сдвига | Есть ли свободная высота; не растёт ли родитель ровно по содержимому |
| Режим раскладки, непосредственного родителя, ось, |
При | Главную и поперечную оси, а не заученные «X» и «Y» |
Текст по центру, карточка слева | Не подменена ли задача перемещения блока свойством |
| Не занимает ли элемент всю ширину и в каком контексте работают отступы |
Абсолютный блок смещён | Containing block, собственные отступы, оба процентных смещения и другие трансформации |
Сетка центрирована странно | Выравниваете ли вы ячейки, элементы в них или сам Grid-контейнер |
В DevTools выделите родителя и ребёнка, посмотрите вычисленные размеры и включите подсветку Flexbox или Grid. Отключайте подозрительные правила по одному. height: 100% не равно «на весь экран»: процентная высота требует подходящего контекста расчёта и при неопределённой высоте предка может не дать ожидаемого результата.
Для небольших экспериментов пригодятся генераторы Flexbox и CSS transform из каталога инструментов ResizeWeb. Полученный CSS всё равно проверяйте на своей разметке: генератор не знает, сколько текста будет в вашем компоненте.
Частые вопросы
Существуют ли display: center и position: center?
Нет, это не допустимые значения этих свойств. Выберите механизм: display: flex или grid с выравниванием, либо position: absolute с координатами. Запись position: flex тоже неверна: Flexbox включают через display. Название center используется как значение у конкретных свойств выравнивания, а не как универсальный режим отображения.
Можно ли центрировать по вертикали без Flexbox и Grid?
Да. Современные браузеры поддерживают align-content и в обычном блочном контейнере. Поддержка в трёх основных движках зафиксирована в объявлении web.dev от апреля 2024 года. Для нашей карточки:
.stage {
display: block;
align-content: center;
min-height: 18rem;
padding: 1rem;
}
.card {
margin-inline: auto;
}Здесь вертикальное выравнивание делает align-content, а горизонтальное — автоматические отступы. Это не означает, что все свойства Flexbox стали работать в блочном потоке; для старых браузеров проверяйте совместимость отдельно.
Почему элемент математически в центре, но выглядит сдвинутым?
CSS выравнивает коробки элементов, а не визуальный центр нарисованной фигуры. Прозрачные поля картинки, несимметричная иконка и особенности шрифта могут менять впечатление. Сначала проверьте рамки и внутренние отступы; оптическую поправку вносите после геометрической, а не вместо неё.
Что запомнить
Для обычного блока по горизонтали начните с margin-inline: auto, для двух осей — с Flexbox или Grid. Во Flexbox сначала определите направление главной оси, в Grid — различайте элементы и сетку. position используйте осознанно, когда нужен слой вне обычного потока.
Сведите отладку к трём вопросам: что выравнивается, относительно какой области и где осталось свободное пространство. Затем проверьте длинное содержимое и узкий экран. Это часть повседневных задач верстальщика сайтов, а не отдельный трюк, который нужно заново подбирать для каждого div.
Комментарии 0
Обсудите материал, задайте вопрос или дополните его своим опытом.
Комментарии доступны зарегистрированным пользователям. Почту нужно подтвердить один раз.
Начните обсуждение: задайте вопрос автору или поделитесь практическим опытом.