Ещё одна коллекция интересных фактов про CSS-гриды (CSS Grid Layout)
Перевод статьи Another Collection of Interesting Facts About CSS Grid с сайта css-tricks.com для CSS-live.ru, автор — Мануэль Матузович
В прошлом году я собрал коллекцию интересных фактов о CSS Grid Layout после моего мастер-класса. В этом году я работал над другим мастер-классом и узнал ещё несколько увлекательных фактов о нашей любимой спецификации раскладки.
Я не жадный, поэтому ещё раз с радостью поделюсь своими знаниями и выводами с вами, с сообществом CSS-Tricks.
Как работает сокращённая запись grid
Читать и понимать спецификацию гридов — да, впрочем, и любую другую — порой бывает крайне сложно
К примеру, я только спустя какое-то время понял, как правильно использовать сокращённую запись grid
:
<‘grid-template’> | <‘grid-template-rows’> / [ auto-flow && dense? ] <‘grid-auto-columns’>? | [ auto-flow && dense? ] <‘grid-autwo-rows’>? / <‘grid-template-columns’>
Это можно понять, если специально уделить этому время или если постоянно читать спецификации. Я перебрал несколько комбинаций — и всё без толку. В итоге мне помогло примечание из спецификации.
Заметьте, что в одном объявлении
grid
можно указывать только свойства явного или неявного грида.
У Рэйчел Эндрю есть серия статей, которая помогает понять, как читать спецификацию на примере CSS-гридов.
Таким образом, в сокращённой записи 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
.
See the Pen grid shorthand — areas, explicit rows and columns by Manuel Matuzovic (@matuzo) on CodePen.
Хотите узнать больше о разнице между явным и неявным гридом? Прочитайте мою статью, здесь на CSS-Tricks.
Нам не обязательно указывать области, если они не нужны. Можно использовать сокращённую запись 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; */
Справа от слеша сокращённая запись задаёт 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; */
See the Pen grid shorthand — explicit rows and implicit columns by Manuel Matuzovic (@matuzo) on CodePen.
Директива @supports
в Edge
Проверка поддержки CSS Grid работает отлично с помощью директивы @supports
, поскольку все браузеры с поддержкой Grid также понимают и @supports
. А значит можно проверить, какую из спецификаций поддерживает браузер: новую, старую, или обе сразу. Обе? Edge 16 и выше поддерживает не только новую спецификацию, но также и старую.
Поэтому, если хотите отличить версии 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 } }
Вот небольшая демонстрация, которая показывает, какая директива @supports
срабатывает в браузере, в котором вы её открыли.
See the Pen display: grid support test by Manuel Matuzovic (@matuzo) on CodePen.
К слову: не стоит слишком увлекаться определением браузера через @supports
, потому что писать код под конкретный браузер само по себе плохо.
Указание точного количества элементов на колонку
Грид отлично подходит для раскладки страницы, но и на уровне компонентов от него также может быть польза. Один из моих любимых примеров — указание точного количества элементов на колонку в многоколоночном компоненте.
Скажем, есть список из 11 элементов, в который нужно добавить новую колонку после каждого четвёртого элемента. Первое, что нужно сделать после установки display: grid
на родительском элементе — изменить работу алгоритма auto-placement. По умолчанию, он заполняет каждый ряд по очереди, добавляя новые ряды, если нужно. С grid-auto-flow: column
он будет заполнять по очереди уже не ряды, а колонки. И напоследок нужно указать количество элементов на колонку. Это можно сделать, определив максимально необходимое количество рядов с помощью свойства 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, мы просто добавим ещё одну полосу в список или воспользуемся нотацией repeat, изменив первый параметр на нужное значение (grid-template-rows: repeat(5, auto)
).
See the Pen Limited number of items per column by Manuel Matuzovic (@matuzo) on CodePen.
Прижатый подвал с помощью CSS Grid
В CSS есть куча способов прижать подвал. Некоторые из них — это хаки со сложностями, но с помощью грида это делается в два счёта.
Возьмём «классическую» структуру страницы: шапка, основной контент и подвал.
<body> <header>HEADER</header> <main>MAIN</main> <footer>FOOTER</footer> </body>
Первым делом установим высоту для html
и body
как минимум 100% от окна браузера, чтобы убедиться, что страница всегда занимает всю вертикальную область. Затем поделим body на три ряда с помощью grid-template-rows
. Первый (шапка) и последний (подвал) ряды могут быть какого нам угодно размера. Ряд в середине (основной контент) должен всегда заполнять остальную область. Нам не придётся высчитывать высоту, поскольку это берёт на себя единица fr
.
html { height: 100%; } body { min-height: 100%; display: grid; grid-template-rows: auto 1fr auto; }
В результате основная область страницы растягивается, а подвал подстраивается под неё, оставаясь внизу окна браузера.
See the Pen CSS Grid Layout Sticky Footer by Manuel Matuzovic (@matuzo) on CodePen.
Автоматический минимальный размер грид-элементов
Недавно в твиттере Флориан поделился своим удивлением, почему обрезка однострочного текста в грид-элементе оказалась такой сложной задачей. Его пример отлично иллюстрирует интересный факт о грид-элементах.
Исходная ситуация — трёхколоночный грид с абзацем в каждом грид-элементе.
<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
, заставив текст быть однострочным, скрыл переполнение и поставил text-overflow: ellipsis
.
p { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
Это отлично работало бы в блочном элементе, но в этом примере с гридом колонки растягиваются до ширины однострочного абзаца:
See the Pen Automatic minimum size of grid items by Manuel Matuzovic (@matuzo) on CodePen.
В общем, это происходит потому, что грид-элемент не может быть меньше его дочерних элементов. По умолчанию у min-width
грид-элемента (или флекс-элемента) стоит auto
, что согласно спецификации:
… применяет автоматический минимальный размер по указанной оси грид-элемента, у которого
overflow
имеет значениеvisible
и который охватывает хотя бы одну полосу, функция минимального размера которой —auto
.
Это придаёт грид- и флекс-элементам дополнительную гибкость, но не всегда желательно, чтобы контент растягивал ширину родительских элементов. Во избежание этого, можно также изменить свойство overflow
грид-элемента на что-то отличное от visible
или установить min-width
в 0
.
Чтобы лучше разобраться в механизме автоматического минимального размера грид-элементов, смотрите спецификацию по гридам:
Заключение
Надеюсь, эти свежие находки придадут вам уверенность при написании и использовании грида, как это было в моём случае. В этой новой спецификации много тонкостей, но по мере использования она становится интереснее и понятнее.
P.S. Это тоже может быть интересно:
Матузович, всё же. Он сам так представляется.
Спасибо, исправил!
Стоит обратить внимание что grid-template-areas не работает в IE Edge (совсем). Понимаю что многим не важно, но в enterprise проектах прийдется дописать еще
-ms-grid-row: 2;
-ms-grid-column: 3;
для каждой area