Приветствую. Представляю вашему вниманию перевод статьи Equal Height Elements: Flexbox vs. Grid, опубликованной 9 апреля 2020 года автором Stephanie Eckles
Это вторая статья из серии, посвящённой ознакомлению с современными способами решения CSS-проблем, с которыми я сталкивалась на протяжении более 13 лет в роли фронтенд-разработчика.
Однажды (приблизительно 7 лет назад) я написала JQuery-плагин,
который работал с тремя колонками, расположенными на одной строке.
А именно, рассчитывал и задавал одинаковую высоту для элементов,
независимо от количества содержимого в каждом из них. Метод вёрстки
на float
, который был тогда основным, не мог
справиться с этой проблемой.
Решение с помощью Flexbox
С появлением Flexbox достижение такого поведения стало возможно благодаря добавлению всего одного свойства:
.flexbox { display: flex;}
Удивительно! В этом случае прямые потомки по умолчанию выстраиваются в строку и имеют одинаковую высоту.
Но если содержимое будет храниться в дополнительном элементе,
вложенном в .column
, высота колонок с разным
количеством контента снова будет отличаться.
Чтобы исправить это, вложенному элементу следует задать высоту 100%
.flexbox { display: flex;}/* Гарантия, что вложенные элементы с содержимым будут заполнять высоту колонок */.element { height: 100%;}
Колонки снова станут равной высоты и будут расти вместе с
содержимым вложенного элемента .element
.
Решение с помощью Grid
Используя Grid, мы сталкиваемся с похожим поведением:
.grid { display: grid; /* Смена оси автоматического размещения элементов */ grid-auto-flow: column;}
Подобно Flexbox, прямые потомки будут иметь одинаковую высоту, но их дети нуждаются в явном определении высоты, как и в способе с использованием Flexbox:
.flexbox { display: grid; grid-auto-flow: column;}/* Гарантия, что элементы с содержимым будут заполнять элементы колонок */.element { height: 100%;}
Ниже представлена Codepen-демонстрация обоих решений для разного количества колонок в строке:
Какой способ лучше?
Для решения проблемы с равной высотой элементов, преимущество Flexbox в том, что ось по умолчанию позволяет сразу выстроить колонки рядом друг с другом, тогда как в Grid её нужно менять явно. Кроме того, элементы также не будут иметь одинаковую ширину (что может быть преимуществом для определённых типов содержимого, например, навигационных ссылок).
Преимуществом Grid в том, что столбцам можно задать равную ширину, если в этом есть необходимость. Также, в случае необходимости, можно указать желаемое максимальное количество столбцов на "строку". В этом случае Grid-макет с легкостью справляется с расчётами для автоматического распределения пространства между столбцами, в то время как Flexbox требует ручного задания расчётов для ограничения количества колонок.
Обновим наше решение с использованием Grid для 3 элементов
.column
на строке:
&.col-3 { grid-gap: $col_gap; grid-template-columns: repeat(3, 1fr);}
В то время, как для Flexbox самый простой вариант был бы таким:
$col_gap: 1rem;.flexbox.col-3 { /* Требует явного разрешения переноса не помещающихся элементов на новую строку */ flex-wrap: wrap; .column { /* Альтернатива свойству "gap" */ margin: $col_gap/2; /* Расчёты ширины колонок max-width: calc((100% / 3) - #{$col_gap}); }}
Также, для каждого способа необходимо переопределять параметры с учётом адаптивности, но это выходит за рамки данной статьи