Flexbox и grid — Примеры
Пример 1 — Вложенные flex-контейнеры вместо двух измерений
Каркасу страницы нужны фиксированная боковая панель и плавная основная колонка, но собран он из flex-контейнеров, и потребовался третий уровень, чтобы разместить панель инструментов рядом с таблицей; скажите, почему вложенность растёт и как заменить внешнюю структуру.
<div class="layout">
<aside class="side">Фильтры</aside>
<main class="content">
<div class="toolbar">Панель инструментов</div>
<div class="table">Строки</div>
</main>
</div>
.layout { display: flex; }
.side { width: 16rem; }
.content { display: flex; flex-direction: column; }
Решение
.layout { display: grid; grid-template-columns: 16rem 1fr; gap: 1.5rem; }
.content { display: flex; flex-direction: column; gap: 1rem; }
Flexbox распределяет элементы вдоль одной оси, поэтому двумерной структуре, собранной из него, нужен контейнер на каждую ось, и вложенность растёт с каждой новой областью. Grid сначала задаёт дорожки и размещает элементы по ним: одно объявление на весь каркас. Вычисленный результат на окне 1200px таков: боковая панель ровно 256px, gap 24px, а колонка содержимого забирает оставшиеся 920px; вложенные flex-контейнеры внутри ячейки grid нормальны и ожидаемы. Запах — в глубине внешней структуры, где справился бы один grid.
Пример 2 — Flex-элемент, который не желает сжиматься
Метка и кнопка копирования стоят в одной строке; когда метка держит длинный неразрывный токен, строка переполняется и кнопку выталкивает из вида. Объясните умолчание, которое это вызывает, затем разрешите элементу сжиматься.
<div class="row">
<span class="label">averylongunbrokentokenthatcannotwrap</span>
<button>Копировать</button>
</div>
.row { display: flex; gap: 0.5rem; }
.label { flex: 1; }
/* строка шире своего контейнера, и кнопка исчезает */
Решение
.row { display: flex; gap: 0.5rem; }
.label { flex: 1; min-width: 0; overflow-wrap: anywhere; }
Автоматический минимальный размер flex-элемента равен ширине его содержимого в самом узком виде, поэтому flex: 1 не может сжать метку ниже ширины этого единственного неразрывного токена — элемент вырастает сверх своей доли и тянет за собой всю строку. min-width: 0 убирает этот пол, а overflow-wrap: anywhere даёт браузеру место для переноса. Вычисленный результат в строке 300px: кнопка остаётся примерно 72px, gap 8px, метка 220px, а токен переносится на две строки вместо переполнения. Поля и отрицательные смещения тут не помогут: ограничение задаёт правило размеров, а не выравнивания.