Отзывчивые CSS макеты без медиа-запросов

Источник: «Responsive CSS Layout Grids without Media Queries»
Узнайте, как Flexbox и Grid позволяют создавать плавно реагирующие макетные сетки без медиа-запросов.

Основой для многих сайтов по-прежнему остаётся макетная сетка, независимо от того, состоит ли она из Grid или Flexbox. В этом отрывке из книги Unleashing the Power of CSS: Advanced Techniques for Responsive User Interfaces мы увидим, как оба этих инструмента позволяют создавать плавно реагирующие макетные сетки без медиа-запросов.

Отзывчивый макет с Grid

Первое, пожалуй, моё любимое из всех решений из-за его универсальности и простоты использования. Используя Grid, мы можем создать отзывчивый набор столбцов, которые создают сами себя по мере необходимости. Мы предоставим единственное ограничение — минимальную ширину, которой могут быть столбцы, — выполняющую двойную функцию в качестве своего рода точки останова перед тем, как элементы столбца разбиваются на новые строки.

Вот всё, что нужно для создания адаптивной макетной сетки, где минимальный размер столба установлен на 30ch с помощью вспомогательного CSS переменной. Это правило предписывает браузеру создавать как можно больше столбцов шириной не менее 30ch:

.grid {
--min: 30ch;

display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--min)), 1fr));
}

Поскольку 1fr является максимальным значением функции minmax(), столбцам также разрешено растягиваться, чтобы равномерно заполнить всё оставшееся пространство в строке. Таким образом, если доступное пространство составляет 80ch и есть два дочерних элемента Grid, каждый из них займёт по 40ch. Если дочерних элемента три, третий будет во втором ряду, так как 80ch не делиться поровну на минимально разрешённый размер 30ch

Следующая демонстрация на CodePen представляет собой живой пример отзывчивого макета Grid.

See the Pen

Отзывчивый макет с Flexbox

Мы можем добиться аналогичного поведения от Flexbox. Разница между решениями Flexbox и Grid заключается в том, что элементы сетки, переходящие в новую строку, не могут распространяться на несколько столбцов сетки. С помощью Flexbox мы можем направить flex-элементы на увеличение, чтобы заполнить всё оставшееся дополнительное пространство, предотвращая сироту, которая появляется с решением Grid.

В этом коде, как в Grid коде, браузер создаст столько столбцов, сколько уместиться во внутреннем пространстве, по крайней мере с --min размером 30ch. Если у нас есть три элемента, а третий нужно переместить на новую строку, он займёт оставшееся место из-за сокращения flex, которое важно устанавливать flex-grow в 1. Поэтому в большинстве случаев он ведёт себя аналогично 1fr:

.flexbox-grid {
--min: 30ch;

display: flex;
flex-wrap: wrap;
}

.flexbox-grid > * {
flex: 1 1 var(--min);
}

На изображении внизу показан последний элемент списка с нечётным номером, занимающий два столбца благодаря свойству flex-grow.

Макет сетки Flexbox

Примечание: в решениях Grid и Flexbox, если мы добавим gap это пространство будет вычтено из расчёта того, столько столбцов может быть создано до добавления новых строк.

Внимательные читатели могли заметить ещё одно ключевое различие между этими решениями: при использовании Grid родитель определяет поведение дочернего элемента. Для Flexbox мы устанавливаем дочернее поведение макета для дочерних элементов. Сокращение flex задаёт по порядку flex-grow, flex-shrink и flex-basis.

В качестве эксперимента мы можем изменить значение flex-grow на 0 и посмотреть, как элементы будут расширяться только до значения flex-basis. (Поэкспериментируйте с демонстрацией CodePen ниже.) Важно сохранить flex-shrink равным 1, чтобы в конечном итоге — когда доступное внутреннее пространство уже, чем flex-basis — элементы по-прежнему могли сжиматься, поскольку оно помогает предотвратить переполнение.

Следующая демонстрация CodePen показывает макет FlexBox в действии.

See the Pen

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

<li style="--min: 40ch">...</li>

Другие дочерние элементы списка в этом примере по-прежнему будут окружать его и использовать 30ch из базового правила, но более широкий столбец эффективно меняет поведение.

Вот CodePen демонстрация этого кода в действии.

See the Pen

Вот ещё две техники Flexbox, которые интересным образом используют flex-grow и flex-basis:

Дополнительные материалы

Предыдущая Статья

Основы TLS (Transport Layer Security)

Следующая Статья

CSS: Введение в контейнерные запросы