CSS Grid с автозаполнением и максимальным количеством столбцов минимального размера
Требования:
Пользователь определяет максимальное число колонок. Это будет «естественное» состояние нашей автозаполняемой сетки
Если ячейка сетки становится уже заданной пользователем ширины, сетка перестраивается и уменьшает количество колонок
Ячейки сетки всегда должны растягиваться на всю ширину grid-контейнера независимо от количества колонок
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Все должно работать при любой ширине экрана и без JavaScript.
Ниже показано, как должна вести себя CSS Grid с автозаполнением, если слева от нее изменяется ширина div элемента.
Если не хотите читать, можете просто скопировать код ниже.
CSS .grid-container { /** * User input values. */ –grid-layout-gap: 10px; –grid-column-count: 4; –grid-item–min-width: 100px; /** * Calculated values. */ –gap-count: calc(var(–grid-column-count) – 1); –total-gap-width: calc(var(–gap-count) * var(–grid-layout-gap)); –grid-item–max-width: calc((100% – var(–total-gap-width)) / var(–grid-column-count)); display: grid; grid-template-columns: repeat(auto-fill, minmax(max(var(–grid-item–min-width), var(–grid-item–max-width)), 1fr)); grid-gap: var(–grid-layout-gap); }
12345678910111213141516171819 | .grid-container { /** * User input values. */ –grid-layout-gap: 10px; –grid-column-count: 4; –grid-item–min-width: 100px; /** * Calculated values. */ –gap-count: calc(var(–grid-column-count) – 1); –total-gap-width: calc(var(–gap-count) * var(–grid-layout-gap)); –grid-item–max-width: calc((100% – var(–total-gap-width)) / var(–grid-column-count)); display: grid; grid-template-columns: repeat(auto-fill, minmax(max(var(–grid-item–min-width), var(–grid-item–max-width)), 1fr)); grid-gap: var(–grid-layout-gap);} |
Демонстрация
Теория и инструменты CSS Grid с автозаполнением
Содержание статьи:
Код выше использует несколько современных CSS инструментов, среди которых CSS Grid функции repeat(), auto-fill(), minmax(), CSS max() и calc(). Ниже рассказываю, как это все работает.
CSS Grid функция auto-fill()
auto-fill() – ключ ко всему. Необходимо чтобы каждая строка заполнялась максимальным числом колонок. Детально прочитать про auto-fill можете в замечательной статье Sara Soueidan «the difference between auto-fill and auto-fit». В этой статье есть видео, показывающее принцип работы.
Но как убедиться, что не создается слишком много колонок?
CSS функция max()
Далее нам понадобится CSS функция max()! Нам необходимо чтобы каждая ячейка сетки могла достигать в ширину некий максимальный процент. Скажем, 25% для сетки из 4 колонок. Однако ширина не может быть меньше заданной пользователем.
То есть имея сетку из четырех колонок с минимальной шириной 100px, функция max() будет выглядеть следующим образом: max(25%, 100px).
Значение 25% не совсем корректно, ведь мы не учитываем отступы внутри сетки. На самом деле функция будет примерно такой:
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
CSS max(calc(25% – <grid-gap-for-one-cell>), 100px)
1 | max(calc(25% – <grid-gap-for-one-cell>), 100px) |
С помощью calc() в CSS можно вычислить значение! (Кто сказал, что CSS не язык программирования?)
CSS –gap-count: calc(var(–grid-column-count) – 1); –total-gap-width: calc(var(–gap-count) * var(–grid-layout-gap)); –grid-item–max-width: calc((100% – var(–total-gap-width)) / var(–grid-column-count));
123 | –gap-count: calc(var(–grid-column-count) – 1);–total-gap-width: calc(var(–gap-count) * var(–grid-layout-gap));–grid-item–max-width: calc((100% – var(–total-gap-width)) / var(–grid-column-count)); |
Мы рассмотрели еще один кирпичик для нашего механизма! Эти стили укажут ячейкам сетки, чтобы те занимали максимальную ширину с учетом заданного пользователем числа колонок, но при этом не были по ширине менее 100px.
CSS max(100px, var(–grid-item–max-width))
1 | max(100px, var(–grid-item–max-width)) |
CSS Grid функция minmax()
Мы почти закончили, остался последний ингредиент: сетка не всегда растягивается на всю ширину родительского контейнера.
Именно это решает функция minmax(). CSS код ниже задает минимальную ширину для <grid-item-width>, и если есть свободное место, функция растягивает все ячейки равным образом для заполнения всей ширины родителя!
CSS minmax(<grid-item-width>, 1fr)
1 | minmax(<grid-item-width>, 1fr) |
Соберем все вместе!
Собрав все кусочки выше воедино, мы получаем код ниже, который делает ровно то, что мы хотели!
CSS –gap-count: calc(var(–grid-column-count) – 1); –total-gap-width: calc(var(–gap-count) * var(–grid-layout-gap)); –grid-item–max-width: calc((100% – var(–total-gap-width)) / var(–grid-column-count)); grid-template-columns: repeat(auto-fill, minmax(max(var(–grid-item–min-width), var(–grid-item–max-width)), 1fr));
12345 | –gap-count: calc(var(–grid-column-count) – 1);–total-gap-width: calc(var(–gap-count) * var(–grid-layout-gap));–grid-item–max-width: calc((100% – var(–total-gap-width)) / var(–grid-column-count)); grid-template-columns: repeat(auto-fill, minmax(max(var(–grid-item–min-width), var(–grid-item–max-width)), 1fr)); |
CSS это весело!
CSS прошел очень долгий путь. Я вдоволь повеселился, работая над этим способом, и рад, что подобные кейсы теперь возможны без применения JavaScript.
Особая благодарность Andy Blum. Он предложил использовать auto-fill() вместо auto-fit(). Также огромная благодарность всем разработчикам и аналитикам, которые писали спецификации за создание и стандартизацию таких продвинутых функций.
Автор: Mike Herchel
Источник: webformyself.com