Модуль 06 — Flexbox

Раскладка в одну линию: меню, ряды карточек, колонки, центрирование

Прогресс курса Модуль 6 из 9

Что вы освоите в этом модуле

01

Контейнер и элементы

display: flex на родителе делает его flex-контейнером, а его прямых детей — flex-элементами. Элементы выстраиваются в линию вдоль главной оси (по умолчанию — слева направо), по поперечной оси (сверху вниз) растягиваются на высоту ряда.

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Flexbox</title>
    <style>
        body { font-family: Arial, sans-serif; }
        .row { display: flex; gap: 8px; padding: 8px; background: #eceff1; }
        .item { padding: 8px 12px; background: #1967d2; color: white; }
        .tall { padding-bottom: 40px; }
    </style>
</head>
<body>
    <div class="row">
        <div class="item">Первый</div>
        <div class="item tall">Второй, повыше</div>
        <div class="item">Третий</div>
    </div>
</body>
</html>
Результат в браузере
Серая полоса, в ней три синих блока в ряд с промежутками; все три одной высоты, хотя второй содержит больший отступ снизу

Блоки div, которые раньше встали бы друг под другом, встали в ряд, каждый шириной по содержимому. Первый и третий растянулись по высоте до второго — это поведение по умолчанию align-items: stretch. gap: 8px — промежуток между элементами: не нужно задавать margin каждому и обнулять его у последнего.

flex-direction: column поворачивает главную ось вертикально — элементы встают столбиком, и все свойства выравнивания «поворачиваются» вместе с осью.

02

Выравнивание по главной оси

justify-content распределяет свободное место вдоль главной оси:

Результат в браузере
Пять серых полос с тремя синими блоками А, Б, В: прижаты влево, по центру, прижаты вправо, по краям с промежутками между, с равными промежутками по краям и между
ЗначениеКуда идёт свободное место
flex-startВ конец: элементы прижаты к началу (по умолчанию)
centerПоровну по краям
flex-endВ начало
space-betweenМежду элементами; крайние — вплотную к краям
space-evenlyПоровну во все промежутки, включая края
03

Выравнивание по поперечной оси

align-items выравнивает элементы поперёк главной оси — в ряду это вертикаль:

Результат в браузере
Три серые полосы высотой 70 пикселей с зелёными блоками: растянуты на всю высоту, по центру по вертикали, прижаты к верху

Сочетание justify-content: center и align-items: center — самый короткий способ поставить что угодно точно в центр блока по обеим осям, задача, над которой верстальщики годами ломали голову до Flexbox. Для одного элемента выравнивание переопределяет align-self.

04

Шапка с меню

Логотип слева, меню справа, всё по центру высоты — типовая шапка в три свойства. Меню — список <ul> (это перечень ссылок), который тоже стал flex-контейнером:

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Шапка</title>
    <style>
        *, *::before, *::after { box-sizing: border-box; }
        body { margin: 0; font-family: Arial, sans-serif; }
        .header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 12px 16px;
            background: #1967d2;
        }
        .logo { color: white; font-weight: bold; font-size: 1.25rem; text-decoration: none; }
        .menu { display: flex; gap: 16px; margin: 0; padding: 0; list-style: none; }
        .menu a { color: white; text-decoration: none; }
    </style>
</head>
<body>
    <header class="header">
        <a class="logo" href="#">Кафе «Нева»</a>
        <nav>
            <ul class="menu">
                <li><a href="#">Меню</a></li>
                <li><a href="#">Новости</a></li>
                <li><a href="#">Контакты</a></li>
            </ul>
        </nav>
    </header>
</body>
</html>
Результат в браузере
Синяя полоса шапки: слева белый жирный «Кафе «Нева»», справа три белые ссылки меню

Вложенные flex-контейнеры — нормальная практика: шапка раскладывает два блока, меню — свои пункты. list-style: none, margin: 0 и padding: 0 убирают маркеры и отступы, которые у списка по умолчанию. На узком экране четыре пункта меню уже не поместятся в строку — как с этим быть, в модуле 08.

05

Размеры элементов: flex

Свойство flex у элемента — сокращение трёх: flex-grow (какую долю свободного места забрать), flex-shrink (можно ли сжимать, когда места мало), flex-basis (исходный размер).

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>flex-grow</title>
    <style>
        body { font-family: Arial, sans-serif; }
        .layout { display: flex; gap: 8px; }
        .layout > * { padding: 10px; color: white; }
        .side { flex: 0 0 120px; background: #6a1b9a; }
        .main { flex: 1; background: #1967d2; }
    </style>
</head>
<body>
    <div class="layout">
        <aside class="side">Боковая колонка: 120px</aside>
        <main class="main">Основная колонка забирает всё оставшееся место</main>
    </div>
</body>
</html>
Результат в браузере
Фиолетовая боковая колонка узкая слева, синяя основная колонка занимает всю остальную ширину
ЗаписьСмысл
flex: 1Расти и сжиматься, исходный размер 0 — забрать свою долю места. У трёх элементов с flex: 1 — по трети
flex: 2Забрать вдвое больше, чем соседи с flex: 1
flex: 0 0 120pxРовно 120px: не расти, не сжиматься
flex: 1 1 160pxНачать со 160px, растягиваться и сжиматься по месту
06

Перенос: ряд карточек

По умолчанию flex-элементы стремятся уместиться в одну строку и сжимаются. flex-wrap: wrap разрешает перенос: когда элементу не хватает его flex-basis, он уходит на новую строку.

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Карточки</title>
    <style>
        *, *::before, *::after { box-sizing: border-box; }
        body { margin: 0; padding: 12px; font-family: Arial, sans-serif; background: #f5f5f5; }
        h1 { margin: 0 0 8px; font-size: 1.25rem; }
        .cards { display: flex; flex-wrap: wrap; gap: 12px; }
        .card {
            flex: 1 1 160px;
            padding: 12px;
            background: white;
            border: 1px solid #ddd;
            border-radius: 8px;
        }
        .card h2 { margin: 0 0 4px; font-size: 1rem; }
        .card p { margin: 0; color: #555; }
    </style>
</head>
<body>
    <h1>Напитки</h1>
    <div class="cards">
        <article class="card"><h2>Капучино</h2><p>220 ₽</p></article>
        <article class="card"><h2>Раф</h2><p>290 ₽</p></article>
        <article class="card"><h2>Американо</h2><p>180 ₽</p></article>
        <article class="card"><h2>Какао</h2><p>210 ₽</p></article>
    </div>
</body>
</html>
Результат в браузере
В широком окне четыре карточки напитков стоят в один ряд одинаковой ширины
Результат в браузере
В узком окне карточки встали по две в ряд

Ни одного медиазапроса — а раскладка подстроилась под ширину: 720px вмещают четыре карточки по 160px и больше, 360px — только две. Элементы последней строки растягиваются на всю её ширину; если нужна строгая сетка с одинаковыми колонками во всех строках, удобнее Grid (модуль 07).

07

Подвал внизу страницы

На короткой странице подвал «всплывает» к середине экрана. Решение: body — колонка высотой не меньше окна (min-height: 100vh), основная часть забирает всё свободное место:

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Подвал внизу</title>
    <style>
        *, *::before, *::after { box-sizing: border-box; }
        body {
            margin: 0;
            min-height: 100vh;
            display: flex;
            flex-direction: column;
            font-family: Arial, sans-serif;
        }
        header, footer { padding: 10px 16px; background: #37474f; color: white; }
        main { flex: 1; padding: 10px 16px; }
    </style>
</head>
<body>
    <header>Шапка</header>
    <main>Короткая страница: содержимого мало.</main>
    <footer>Подвал прижат к низу окна</footer>
</body>
</html>
Результат в браузере
Окно высотой 260 пикселей: тёмная шапка сверху, короткий текст, тёмный подвал у самого низа окна

Когда содержимого станет больше высоты окна, страница просто вырастет, и подвал окажется после содержимого, как обычно.

Ключевые выводы модуля

Запомните главное

  • display: flex раскладывает прямых детей вдоль главной оси; flex-direction: column поворачивает её
  • justify-content — по главной оси, align-items — по поперечной; оба center — центр блока
  • Промежутки — gap, а не margin у каждого элемента
  • flex: 1 — забрать долю свободного места, flex: 0 0 120px — фиксированный размер
  • flex-wrap: wrap + flex: 1 1 базовый_размер — ряд карточек, который переносится сам
  • Подвал внизу — body колонкой с min-height: 100vh и main { flex: 1 }
Практические задания — на учебном портале. Задания, критерии оценивания, сдача работ и оценки преподавателя — в курсе на portal.nevabit.ru. Учётную запись выдаёт преподаватель.
Модуль 05: Блочная модель Все модули Модуль 07: Grid