Перейти к содержанию

Flexbox для навигации и метаданных

Применим Flexbox к шапке и метаданным карточек, чтобы управлять выравниванием и переносом одной группы элементов.

Каталог уже имеет общую оболочку и интервалы. Теперь бренд и навигацию удобно расположить в строке, а число уроков и пояснение собрать в компактную группу. Для таких отношений подходит Flexbox: он распределяет непосредственных детей вдоль выбранной главной оси и управляет выравниванием в поперечном направлении. Сам список из шести карточек пока оставим вертикальным.

Мы не выбираем Flexbox для всей страницы только потому, что он современный. Внутри описания курса обычный поток остаётся полезным. Для сетки карточек позже потребуется другое отношение между строками и колонками. Здесь у каждой группы есть одна основная линия, которая может переноситься при недостатке ширины.

Контейнер и непосредственные дети

В HTML шапки уже есть div.lab-header-row, содержащий бренд и nav. Включим Flexbox для этой обёртки и для навигации. Добавьте в конец CSS:

.layout-lab .lab-header-row,
.layout-lab .lab-nav,
.layout-lab .lab-footer-row {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: center;
}
.layout-lab .lab-header-row,
.layout-lab .lab-footer-row {
  justify-content: space-between;
}
.layout-lab .lab-brand {
  font-weight: 700;
}
.layout-lab .course-meta {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem 1rem;
  align-items: baseline;
}

Ожидается бренд слева и навигация справа, пока их размеры помещаются в общую строку. Между ссылками появится промежуток. В футере текст и обратная ссылка получат сходное отношение. Если места недостаточно, группы смогут перейти на следующую строку. Это важная часть примера: мы не требуем от браузера любой ценой сжать длинный текст до выбранной ширины.

Flex-элементами становятся непосредственные дети контейнера. У lab-header-row это ссылка бренда и целый nav, а не все ссылки внутри навигации. Поэтому для самого nav создан второй flex-контекст. Если применить одно правило только к внешней обёртке, оно не начнёт автоматически распределять вложенные ссылки. Такая граница помогает объяснить, почему иногда «Flexbox включён», но нужная группа всё ещё выглядит иначе.

У course-meta прямые дети — два span. Они получают общую линию и могут переноситься. Название и описание карточки не становятся flex-элементами этой группы. Это локальное изменение: его можно убрать, не переписывая остальной компонент. Основные понятия осей и контейнера приведены в MDN.

Две оси и свободное место

При обычном flex-direction: row главная ось следует направлению строки. В нашем документе это горизонталь слева направо. justify-content работает вдоль этой оси, align-items — поперёк. Если направление станет column, отношения повернутся. Поэтому объяснение «justify всегда про горизонталь» ошибочно. Нужно сначала установить главную ось конкретного контейнера.

space-between распределяет свободное место между элементами, но не создаёт одинаковые поля у краёв. Края уже задаёт lab-shell. Значение gap добавляет минимальный промежуток между соседями; распределение свободного пространства может сделать расстояние больше. На широкой шапке между брендом и навигацией ожидается большое свободное место, а между двумя ссылками внутри nav — обычный заданный промежуток.

Если контейнеру нечего распределять, действие justify-content может быть почти незаметным. Например, узкий nav с естественной шириной не обязан растянуться на всю шапку. Его собственная ширина определяется внешним контекстом и содержимым. Это не означает, что объявление отсутствует: условие для заметного эффекта другое. Полезно смотреть размеры контейнера, а не только расстояние между буквами.

align-items: baseline у метаданных ориентирует текст по базовой линии. При разных размерах шрифта это может быть удобнее выравнивания центров коробок. В шапке выбрано center, потому что там выравнивается группа бренда и навигации. Мы не пытаемся назначить одно выравнивание всем блокам страницы. Свойство должно соответствовать отношению элементов в выбранном контейнере.

Перенос и порядок

flex-wrap: wrap разрешает несколько линий. Каждая линия распределяет место в рамках своего flex-контекста; это не общая таблица колонок между всеми строками. По этой причине Flexbox удобен для навигации, но не всегда подходит для выравнивания карточек в строгую двумерную сетку. В следующем уроке рассмотрим Grid, который явно описывает дорожки строк и колонок.

Для наблюдения сделайте название бренда длиннее и уменьшайте окно. Ожидается, что навигация сможет перенестись. Если одна длинная последовательность без пробелов всё ещё превышает ширину, одного разрешения переноса групп недостаточно: нужно проверить минимальные размеры самого элемента и возможность переноса его текста. Flexbox не изменяет любую строку автоматически в короткую подпись.

Не применяйте order ради перестановки навигации перед брендом без проверки исходного порядка. Свойство меняет визуальное расположение flex-элементов, но не переписывает HTML. Переход клавиатурой и чтение структуры продолжают опираться на документ. Для нашей шапки естественный порядок уже соответствует смыслу. Если нужно изменить содержание, лучше начать с HTML, а не скрыть новую последовательность стилем.

Почему не нужны индивидуальные поля ссылок

Промежутки навигации заданы на контейнере. Поэтому последняя ссылка не получает лишний правый отступ, который пришлось бы удалять отдельным селектором. Добавление третьей ссылки сохраняет правило. Тот же принцип применяется к метаданным: промежуток описывает отношение соседей, а не принадлежит случайно первому span.

Не смешивайте старые внешние поля и gap, если они решают одну задачу. В нашем HTML ссылки навигации не имели специальных полей, поэтому удвоения не возникает. Для списка карточек уже есть межэлементное поле из прошлого урока. Когда там появится Grid, мы отменим его явно. Переход между механизмами требует проверить состояние предыдущего шага, а не просто дописать новое правило.

У flex-элементов есть параметры роста и сжатия. Они нужны, когда свободное место должен получить конкретный ребёнок, а не просто расстояния между ним и соседями. Пока в шапке мы не задаём бренду обязательный рост: его естественный размер и распределение группы достаточны. В финальном уроке похожая идея пригодится основной области страницы, которая заполнит место перед футером.

Не смешивайте эти параметры с justify-content: рост изменяет размер участвующих коробок, а распределение свободного места работает с оставшимся пространством. Если после роста свободного места нет, ожидаемый большой промежуток может не появиться.

У сжимающегося элемента может оставаться минимальное требование от содержимого. Поэтому иногда одного flex-shrink недостаточно для устранения переполнения. Нужно проверить минимальный размер ребёнка и возможность переноса текста. Это особенно заметно у вложенной навигации с длинным адресом без пробелов. В нашем обычном наборе коротких ссылок проблемы может не быть, но правило полезно понимать заранее. Не ставьте overflow: hidden на всю шапку, чтобы скрыть выходящий текст: сначала выясните, какая коробка требует лишнее место.

Для самостоятельной работы временно переключите lab-header-row на flex-direction: column и сравните действие выравнивания. Затем верните строку. Каталог теперь имеет компактные служебные группы, а карточки продолжают естественно расти в одном столбце. В следующем уроке изменим именно список: зададим дорожки Grid, минимальную удобную ширину карточки и автоматическое число колонок.

Оглавление курса