От автора: в прошлом году после семинара я собрал подборку интересных фактов про Grid CSS макеты. В этом году я работал над другим семинаром и узнал еще несколько интересных фактов о спецификации макета, который мы все так любим. Конечно, я не буду держать свои знания при себе. Я рад поделиться с вами.
Понимание того, как работает «сетка»
Иногда понять части сетки — или в принципе любой другой спецификации — может быть очень сложно. Например, мне потребовалось некоторое время, чтобы понять, как правильно использовать сокращенное свойство grid. В спецификации указано, что действительными значениями являются:
<'grid-template'> | <'grid-template-rows'> / [ auto-flow && dense? ] <'grid-auto-columns'>? | [ auto-flow && dense? ] <'grid-autwo-rows'>? / <'grid-template-columns'>
Вы можете понять это, если потратите определенное время, или если у вас есть опыт чтения спецификаций. Я попробовал несколько комбинаций, и все они были неудачными. В итоге мне помогло примечанием в спецификации:
Обратите внимание, что вы можете указать только явные или неявные свойства сетки в одном объявлении сетки.
Таким образом, мы можем указать множество вещей, используя сокращенное свойство grid, но только не все сразу. Вот несколько примеров.
Использование grid вместо grid-template
Свойство grid-template является сокращением для определения grid-template-columns, grid-template-rows и grid-template-areas в одном объявлении. Мы можем сделать то же самое с помощью сокращения grid, которое немного короче.
grid: "one one" 200px "two four" "three four" / 1fr 2fr; /* сокращение для: */ /* grid-template-areas: "one one" "two four" "three four"; grid-template-rows: 200px; grid-template-columns: 1fr 2fr; */
Это сокращенное свойство создает три строки и две колонки с четырьмя областями сетки. Первая строка имеет явную высоту 200px, а вторая и третья — неявные высоты auto. Первый столбец имеет ширину 1fr, а второй — 2fr.
Нам не нужно указывать области, если они нам не нужны. Мы можем использовать сокращение grid только для определения явных строк и столбцов. Следующие два фрагмента кода по сути делают одно и то же:
grid-template-rows: 100px 300px; grid-template-columns: 3fr 1fr; grid: 100px 300px / 3fr 1fr;
Обработка неявных строк и столбцов
Можно также использовать сокращение grid, чтобы указать grid-auto-flow, но оно не работает точно так, как мы могли бы ожидать. Мы не только добавляем ключевое слово row или column в объявлении. Мы должны использовать ключевое слово с нужной стороны от косой черты.
Если auto-flow находится слева от косой черты, сокращение задает grid-auto-flow для row и создает явные столбцы.
grid: auto-flow / 200px 1fr; /* сокращение для: */ /* grid-auto-flow: row; grid-template-columns: 200px 1fr; */
Если auto-flow находится справа от косой черты, сокращение задает grid-auto-flow для column и создает явные строки.
grid: 100px 300px / auto-flow; /* сокращение для: */ /* grid-template-rows: 100px 300px; grid-auto-flow: column; */
Мы также можем установить неявный размер и для строк, и для столбцов, использовав ключевое слово auto-flow, которое соответственно задает для grid-auto-rows или grid-auto-columns указанное значение.
grid: 100px 300px / auto-flow 200px; /* сокращение для: */ /* grid-template-rows: 100px 300px; grid-auto-flow: column; grid-auto-columns: 200px; */
Отдельные запросы в Edge
Проверка поддержки CSS Grid отлично работает с помощью Feature Queries, потому что все браузеры, которые поддерживают Grid, также распознают и Feature Queries. Это означает, что мы можем проверить, поддерживает ли браузер старую или новую спецификацию, или и то, и другое. И то, и другое, спросите вы? Начиная с версии 16, Edge поддерживает не только новую спецификацию, но и старую.
Итак, если вы хотите различать версии Edge, которые поддерживают новую спецификацию, и те, которые не поддерживают, вы должны писать запросы следующим образом:
/* Edge 16 и выше */ @supports (display: -ms-grid) and (display: grid) { div { width: auto; } } /* Edge 15 и ниже */ @supports (display: -ms-grid) and (not (display: grid)) { div { margin: 0
Вот демо-версия, в которой показано, какие триггеры запросов функций в браузере вы открыли.
В качестве примечания. Вам не следует злоупотреблять использованием запросов функций браузеров, поскольку определение браузера это не слишком хорошая практика.
Указание точного количества элементов на столбец
Grid отлично подходит для макетов страниц, но она может быть очень полезной и на уровне компонентов. Одним из моих любимых примеров применения является возможность указать точное количество элементов на столбец в многостолбцовом компоненте.
Допустим, у нас есть список из 11 элементов, и мы хотим добавлять новый столбец после каждого четвертого элемента. Первое, что нам нужно сделать после установки display: grid для родительского элемента — это изменить способ работы алгоритма автоматического размещения сетки. По умолчанию он заполняет каждую строку, добавляя новые строки по мере необходимости. Если мы установим column для grid-auto-flow, сетка будет заполнять каждый столбец поочередно, а это то, чего мы добиваемся. Последнее, что нам нужно сделать, это указать количество элементов на столбец. Это можно сделать, определив столько явных строк, сколько нам нужно, с использованием свойства grid-template-rows. Мы можем установить высоту каждой строки явно или просто сделать их такими же по размерам, как и их содержимое, используя ключевое слово auto.
ul { display: grid; grid-template-rows: auto auto auto auto; /* или короче и более читаемо: */ /* grid-template-rows: repeat(4, auto); */ grid-auto-flow: column;
Если нам нужно изменить количество элементов до 5, мы просто добавим еще один трек в список треков или вместо этого используем повторную нотацию и просто изменим первый параметр на нужное значение (grid-template-rows: repeat(5, auto)).
Липкие футеры с использованием CSS Grid
Существует много способов создания в CSS липких футеров. Некоторые из них довольно сложны, но с помощью сетки это сделать довольно просто. Предположим, у нас есть * классические * шапка сайта, основной контент и футер.
<body> <header>HEADER</header> <main>MAIN</main> <footer>FOOTER</footer> </body>
Во-первых, мы устанавливаем высоту html и body как минимум на 100% окна просмотра, чтобы убедиться, что страница всегда занимает полное вертикальное пространство. Затем мы применяем grid-template-rows, чтобы разделить body на три строки. Первая (шапка) и последняя (футер) строки могут иметь любой размер. Если мы хотим, чтобы они всегда имели ту же высоту, что и их содержимое, мы просто устанавливаем для высоты auto. Строка в середине (контент) всегда должна заполнять остальную часть пространства. Нам не нужно вычислять высоту, потому что мы можем использовать дробную единицу измерения.
html { height: 100%; } body { min-height: 100%; display: grid; grid-template-rows: auto 1fr auto;
В результате основной контент растягивается, а футер соответственно корректируется и остается в нижней части окна просмотра.
Автоматический минимальный размер элементов сетки
Недавно Флориан написал в твиттере, что ему интересно, почему усечение текста из одной строки внутри элемента сетки выполняется настолько сложно. Его пример отлично иллюстрирует интересный факт об элементах сетки. Исходной ситуацией является трехстолбцовая сетка с абзацем в каждом элементе сетки.
<div class="grid"> <div class="item"> <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo ipsum exercitationem voluptate, autem veritatis enim soluta beatae odio accusamus molestiae, perspiciatis sunt maiores quam. Deserunt, aliquid inventore. Ullam, fugit dicta. </p> </div> </div>
.grid { display: grid; grid-template-columns: repeat(3, 1fr); grid-gap: 20px;
Каждый абзац должен состоять только из одной строки, если она длиннее ширины родительского элемента, в конце должно добавляться троеточие. Флориан решил эту проблему, установив для white-space — nowrap (принудительно задает одну строку без переносов), скрыв overflow и установив ellipsis для text-overflow.
p { white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
Это могло бы отлично работать для блочного элемента, но в этом примере столбцы расширяются до ширины одной строки абзаца:
Это происходит, потому что элемент сетки не может быть меньше, чем его дочерний элемент. По умолчанию для min-width элемента сетки (или flex-элемента) задано auto. В спецификации говорится:
… применяет автоматический минимальный размер по указанной оси к элементам сетки, для которых выходящий за пределы родителя контент видим и которые охватывают по меньшей мере один трек, для которого функция определения минимального размера трека имеет значение auto.
Это делает элементы сетки гибкими, но иногда мы не хотим, чтобы содержимое растягивало ширину родительских элементов. Чтобы избежать этого, мы можем либо изменить значение свойства overflow для элемента сетки на что-то отличное от visible, либо установить минимальную ширину 0.
Заключение
Надеюсь, эти советы помогут вам чувствовать себя более свободно в работе с Grid, как они помогают мне. В этой новой спецификации много тонкостей, но чем больше мы с ней работаем, тем более интересной и понятной она становится.
Автор: Manuel Matuzovic
Источник: https://css-tricks.com/
Редакция: Команда webformyself.