CSS Grid на практике: добавляем гриды к существующему дизайну
Перевод статьи Practical CSS Grid: Adding Grid to an Existing Design с сайта alistapart.com для css-live.ru. Автор — Эрик Мейер.
Понять и использовать CSS-гриды проще, чем может показаться. В день, когда вышел Firefox 52 с поддержкой гридов, я на радостях решил переделать основу раскладки моего личного сайта на гридах. И это был очень несложный процесс — пять минут, чтоб написать сами стили для грида, еще 15-20 ушло на отладку.
Гриды позволяют нам буквально определять линии для рядов и колонок сетки, а потом привязывать элементы к этим линиям в каком угодно порядке. Это может напомнить таблицы, но гриды настолько мощнее, что таблицы о таком и мечтать не могли. Гриды — это более отзывчивые раскладки, намного более доступные документы и гораздо более чистая разметка, чем можно было добиться даже с float-ами и позиционированием.
С появления CSS уже прошли десятилетия, но никогда еще в нем не было хоть сколько-либо похожей системы. К тому же гриды уже поддерживаются и в Chrome, и в Firefox, вот-вот присоединится и Safari (предварительная версия для разработчиков их уже поддерживает). Заря новой эры в цифровом дизайне занимается прямо у нас на глазах.
Как это было
Прежде чем подойти к гридам, позвольте мне на минутку объяснить структуру разметки основных страниц сайта meyerweb, а также подход с позиционированием и margin-ами, которым я пользовался, гм, уже лет этак 12. Вот как строится разметка:
<body> <div id="sitemast">…</div> <div id="search">…</div> <div id="main">…</div> <div id="extra">…</div> <div id="navigate">…</div> <div id="footer">…</div> </body>
Некоторые из этих ID — специфический пережиток моих взглядов на раскладку и именование начала 2000-х. Например, #extra
— то, что сегодня большинство из нас назвало бы #sidebar
. #sitemast
заменяет собой #masthead
. А #footer
— из того времени, когда элемента <
footer>
не было и в помине.
Эти div
ы (которым в наши дни лучше бы быть section
ами, но сейчас это неважно) идут в таком порядке, что если CSS не загрузится, или на сайт зайдут голосовым браузером, первой будет «шапка» сайта, второй — возможность поиска, и третьим — основной контент. А затем — дополнительные материалы, навигация по сайту и «подвал» внизу.
Всё это сшито в одну раскладку абсолютным позиционированием div
ов с навигацией и поиском. «Шапке» задана высота 192px
, и div
ам с навигацией и поиском указано top: 192px;
, чтобы они отображались сразу под ней. Чтобы для них осталось место, главному и дополнительному div
ам заданы верхние внешние отступы (рис. 1).
Рис. 1: главная страница сайта meyerweb (лишнее вырезано)
Конструируем грид
Такой, более-менее, была раскладка этого всего с середины 2005-го. Однажды в порядке эксперимента я пробовал поиграть с флексбоксами, но результат не выкладывал, потому что делать двумерную раскладку одномерным раскладочным инструментом выглядело как-то неуклюже. Наверное, надо было переделать на флексбоксы панель навигации, но что-то меня отвлекло, и я больше не возвращался к той задаче.
И тут грянули гриды. Пока поддержка гридов добиралась до обычных пользователей, я сосредоточился на изучении гридов и обучении им других, создании тестов и построении иллюстраций для своих работ с их помощью. А затем, 7 марта 2017 г., вышел релиз Firefox 52 с их поддержкой. Я написал в твиттер и опубликовал статью и пример, сделанный накануне вечером, после чего позволил себе передышку, по-прежнему с трудом веря, что этот день настал. После 20 с лишним лет CSS, наконец, настоящая система для раскладки, набор свойств и значений, с самого начала именно для нее предназначенный.
И где-то в этот момент я и решил переделать мой личный сайт, задействовав гриды для раскладки его основных блоков. Мне понадобилось меньше пяти минут, чтобы получить следующее:
body { display: grid; grid-template-rows: 192px min-content min-content 1fr; grid-template-columns: 1fr 20em; } #sitemast { grid-row: 1; grid-column: 1 / span 2; } #search { grid-row: 2; grid-column: 2; } #main { grid-row: 3; grid-column: 1; } #extra { grid-row: 3; grid-column: 2; } #navigate { grid-row: 2; grid-column: 1; } #footer { grid-row: 4; grid-column: 1; }
Это не всё, что мне понадобилось, но самое главное. Позвольте разобрать это для вас по частям.
body { display: grid; grid-template-rows: 192px min-content min-content 1fr; grid-template-columns: 1fr 20em; }
Эта часть CSS указывает, что элемент body
будет грид-контейнером, а также задает грид-линии. Когда вы делаете элемент грид-контейнером, все его дочерние элементы становятся грид-элементами (если вы работали с флексбоксами, то этот принцип вам уже знаком). Так что этим display: grid
я превратил все дочерние div
ы в грид-элементы.
Далее идут ряды грида. Значения в grid-template-rows
на самом деле определяют расстояние между грид-линиями (это же справедливо и для grid-template-columns
, до которого мы вот-вот доберемся). Так что значение 192px min-content min-content 1fr;
означает: «Отступи на 192 пикселя вниз от верхнего края грид-контейнера и размести там грид-линию. Затем размести еще две так, чтобы между ними хватало места для содержимого рядов, которые они определяют. Наконец, оставь одну fr
(от англ. «fraction» — доля) расстояния между третьей грид-линией и нижним краем грид-контейнера» (рис. 2).
Рис. 2: определение рядов
Значение min-content
— классная штука. Его смысл соответствует названию: «Занять тот минимум доступного места, который нужен, чтобы вместить содержимое». Так что в случае второго ряда, в котором будут полоска навигации и поле поиска, оно будет соответствовать высоте большего из этих двух элементов, и ни пикселем больше.
То же самое для третьего ряда, в котором содержатся главный и дополнительный div
ы. На главной странице основной div
будет выше другого. На внутренних страницах может быть и наоборот. В любом случае ряд, содержащий эти два div
а, всегда будет достаточной высоты, чтобы вместить их оба.
С рядами разобрались, на очереди колонки. Я решил не усложнять и задать всего две. Если взглянуть на главную страницу meyerweb, кажется, что на ней три колонки, но это верно только для статей в блоге — существенной, но не главной части сайта — и «колонка» слева представляет собой скорее боковую панель внутри главной колонки.
В исходном дизайне у боковой колонки (#extra
) ширина 18em, с добавочным пространством, чтоб отделить ее от главной. Но эта колонка должна вмещать еще и поле поиска, которое чуть шире. После нескольких проб я остановился на ширине 20em
. Остальному достался гибкий размер в виде 1fr
(рис. 3).
Рис. 3: определение колонок
Раз я уже дважды воспользовался единицей fr
, придется дать краткое пояснение. fr
расшифровывается как «fraction» (доля, часть), и означает «одна часть доступного несвязанного пространства». В нашем гриде две колонки. Одной из них явно задана ширина 20em
, и тем самым она связана — для нее нет места для гибкости. Оставшееся колоночное пространство не связано — если изменить ширину грид-контейнера (скажем, сузив или расширив окно браузера), несвязанное пространство изменится, но останется равным ширине контейнера минус 20em
связанного пространства.
Представим на минуту, что я решил разделить грид на четыре колонки, крайняя правая шириной 20em
, а остальные одинаковой гибкой ширины. Это будет выглядеть примерно так:
grid-template-columns: 1fr 1fr 1fr 20em;
Как вариант, я мог бы записать это в виде:
grid-template-columns: repeat(3, 1fr) 20em;
В обоих случаях это привело бы к тому, что несвязанное пространство поделится поровну между тремя первыми колонками. Будь грид-контейнер шириной 65em
, последняя колонка была бы шириной 20em
, а остальные три — по 15em
каждая (3 x 15 = 45; 45 + 20 = 65). Уменьшите грид-контейнер до 50em
, и первые три колонки сожмутся до 10em
каждая.
В моем случае я хотел, чтобы первая колонка заняла всё место, не занятое фиксированной последней колонкой, поэтому ей досталось 1fr
. Итоговый результат показан на рис. 4.
Рис. 4: готовый грид
Размещаем элементы
Когда грид-линии заданы, дело за привязкой грид-элементов к этим грид-линиям. Это может происходить автоматически, с помощью алгоритма grid-flow («гридового потока»), но здесь тот случай, когда я хочу поместить каждый элемент в конкретное место. Поэтому получается следующее:
#sitemast { grid-row: 1; grid-column: 1 / span 2; } #search { grid-row: 2; grid-column: 2; } #main { grid-row: 3; grid-column: 1; } #extra { grid-row: 3; grid-column: 2; } #navigate { grid-row: 2; grid-column: 1; } #footer { grid-row: 4; grid-column: 1; }
Я словно говорю каждому из этих шести div
ов: «Прилепись своим верхним краем к этой линии ряда, а своим левым краем — к этой линии колонки». Я использовал номера линий, потому что у меня не было ничего другого — вообще-то грид-линиям можно присваивать имена, но я этого не делал (но не пропустите такой пример далее в этой статье!)
Так что, если взять один пример, для блока #main
я указал, чтоб он начинался с третьей линии рядов и первой линии колонок. Это значит, что по умолчанию он заполнит всё пространство от первой до второй линии колонок и от третьей до четвертой линии рядов.
Почти все div
ы размещены таким образом. Единственное исключение в данном случае — #sitemast
. Он начинается с первых линий колонок и рядов, но, поскольку по замыслу должен растянуться на всю ширину грида, я задал ему для колонок значение 1 / span 2
. Это значит «начнись с линии колонок №1 и охвати две колонки». Я мог бы получить тот же результат и со значением 1 / 3
, что значит «продолжайся от линии колонок №1 до линии колонок №3» (рис. 5).
Рис. 5: размещение грид-элементов
Но имейте в виду: это просто схема, а не реальная ситуация. Во всяком случае, пока еще не реальная.
И здесь я хотел бы еще уточнить, что, хотя вы можете явно распределить все свои грид-элементы по конкретным рядам и колонкам, вам не обязательно это делать. В гридах есть модель автоматического размещения, благодаря которой грид-элементы будут сами попадать в следующую свободную грид-ячейку, в зависимости от направления потока. В моем случае я мог бы обойтись буквально следующими правилами:
#sitemast { grid-column: 1 / span 2; } #navigate { grid-row: 2; grid-column: 1; }
Это гарантировало бы, что «шапка» займет обе колонки по ширине, а div
ы с поиском и навигацией попадут именно в те ячейки, что нужно. После этого второй ряд был бы заполнен навигацией и поиском, а оставшиеся грид-ячейки — свободны.
При таком раскладе элементы без явной привязки к месту оказывались бы в гриде в том порядке, в котором они идут в коде. Шапка (#sitemast
) попала бы в первый же ряд с двумя свободными колонками, который смогла найти, и вышло так, что это как раз первый ряд грида. Наш div
с поиском попадет в следующую свободную ячейку, то есть «ряд 2, колонка 2», потому что колонка 1 во втором ряду уже занята div
ом с навигацией. После этого главный div
попадает в первую свободную ячейку: ряд 3, колонка 1. Дополнительный блок пойдет в следующую ячейку: ряд 3, колонка 2. И наконец, подвал разместился бы в ряду 4, колонке 1.
Итоговый результат в точности такой же, как на рис. 5. Вот только если на какой-то особой странице у меня добавится еще один div
, и появится в неудачном месте HTML, он может разнести всю раскладку в клочья. Назначая блокам моей раскладки нужные места явно, я гарантирую, что никакой шальной элемент ничего мне не перевернет.
При тех стилях, что я написал, если на страницу будет добавлен еще один дочерний элемент для body
, он станет грид-элементом. Если я не укажу ему явного места в гриде, он в итоге окажется в первой свободной грид-ячейке. Поскольку правая нижняя ячейка (ряд 4, колонка 2) не занята, этот добавочный элемент будет помещен именно туда… при условии, что ему не предписано охватывать две колонки. В таком случае он окажется в самом низу грида, в автоматически созданном пятом ряду.
Находим место прошлому
Достаточно легко задать грид, но когда вы наполняете его грид-элементами, они приносят с собой все свои имеющиеся стили. Иногда это не доставляет особых хлопот, но в моем случае это означало, что все внешние и внутренние отступы, на которых у меня прежде держалось взаимное расположение блоков, теперь вносят путаницу в размещение грид-элементов. Можете увидеть это на рис. 6, созданном на базе локальной копии сайта.
Рис. 6: грид + старый код = караул!
Это не дело. Пора переопределить старые раскладочные стили, которые уже не нужны в гридах, но оставить их для браузеров, которые еще не понимают гридов.
Так что я взял и обернул всё в блок @supports
. Поскольку я собирался ограничить грид-раскладку лишь широкими экранами, я вставил блок @media
прямо внутрь @supports
и там обнулил или еще как-то поменял всякие внешние и внутренние отступы, не нужные мне в контексте гридов. Вот что у меня получилось:
@supports (display: grid) { @media (min-width: 60.001em) { body { display: grid; grid-template-rows: 192px min-content min-content 1fr; grid-template-columns: 1fr 20em; } #sitemast { grid-row: 1; grid-column: 1 / span 2; } #search { grid-row: 2; grid-column: 2; position: static; padding: 0.25em 0 1em; } #main { grid-row: 3; grid-column: 1; margin-right: 0; margin-top: 1.25em; padding-top: 0; } .hpg #main { margin-top: 0; padding-top: 0; } #extra { grid-row: 3; grid-column: 2; position: static; top: 0; margin-top: 0; padding-top: 0.5em; margin-left: auto; } #navigate { grid-row: 2; grid-column: 1; position: static; margin-top: 1px; padding-bottom: 0; } #footer { grid-row: 4; grid-column: 1; margin-right: 0; } } }
Наверное, я мог бы отрефакторить это и сделать еще эффективнее, но пока собираюсь оставить как есть. Здесь хорошо видно, что пришлось сделать с каждым грид-элементом — каким из них понадобилось переопределить position
, чтобы их абсолютное позиционирование не взаимодействовало с гридом странным образом, какие отступы пришлось изменить, и так далее. Посмотрим на конечный результат (рис. 7).
Рис. 7: грид + @supports = ух ты!
Вы вправе подумать, что это был большой шум по пустячному поводу. К чему были все эти сложности, если в итоге не видно разницы? Реальная мощь здесь, в этом очевидно простом случае, в том, что мне больше не надо беспокоиться о том, что один блок может наложиться на другой. Подвал всегда будет под главным и дополнительным div
ами, независимо от того, который из них выше. С позиционированием в этом никогда нельзя было быть уверенным.
Аналогично, навигация и поиск всегда будут поддерживать общую высоту, гарантируя, что ни один из них не наложится на контент под ними — и, благодаря min-content
, мне не нужно гадать, какой высоты они могут оказаться. Грид сам всё это улаживает для меня.
И помните, раскладка по-прежнему работает в старых браузерах, как и раньше, на позиционировании. Я не «сломал» сайт для браузеров, не понимающих гридов. А более мощная грид-раскладка уже наготове для браузеров типа Chrome и Firefox, которые ее поймут.
Если хотите сами пощупать это всё вживую, зайдите на meyerweb.com и проинспектируйте элементы в Firefox 52 или новее. Там вы увидите небольшую иконку в виде вафельки рядом с объявлением display: grid
для элемента body
. Кликните ее, и Firefox прочертит на странице грид-линии, чтобы вам нагляднее было ее исследовать (в ночных сборках Firefox можно включить еще более мощный раскладочный инструмент, см. подробности в моей статье «Инспектируем гриды»).
Традиции наименования
Я уже упоминал, что грид-линиям можно присваивать имена. В собственных стилях я этого не делал, потому что грид у меня был простенький, но в более сложных гридах именование линий бывает полезным.
На примере урезанной версии стилей, без всех переопределений старья, с именованными линиями код мог бы выглядеть как-то так:
body { display: grid; grid-template-rows: [masthead] 192px [navsearch] min-content [mainextra] min-content [footer] 1fr; grid-template-columns: [left] 1fr [middle] 20em [right]; }
Каждое из этих слов в квадратных скобках присваивается в качестве имени соответствующей грид-линии (рис. 8).
Рис. 8: именованные грид-линии
Как только имена определены, на них можно ссылаться в свойствах grid-row
и grid-column
. Например:
#sitemast { grid-row: masthead; grid-column: left / span right; } #search { grid-row: navsearch; grid-column: middle; } #main { grid-row: mainextra; grid-column: left; } #extra { grid-row: mainextra; grid-column: middle; } #navigate { grid-row: navsearch; grid-column: left; } #footer { grid-row: footer; grid-column: left; }
Во многом аналогично именам классов, грид-линиям можно задавать несколько имен через пробел. Попробуйте-ка вот это:
grid-template-columns: [start left] 1fr [middle sidebar] 20em [right end];
Потом в объявлении grid-column
вы можете обращаться к любому из этих имен. Предел для количества имен не определен, но не забывайте, что приходит вместе с великой силой.
Если хотите знать, имена и номера грид-линий можно комбинировать, так что вполне можно писать что-то типа grid-row: navsearch; grid-column: 2;}
. Можно использовать любое имя, которое браузер сможет распарсить, что значит, что можно указывать почти всё, что только позволят вам Юникод и кодировка вашего CSS-файла.
Гриды и флексбоксы
У вас может возникнуть вопрос: теперь, когда есть гриды, надо ли выбрасывать флексбоксы? Ни в коем случае! Они прекрасно могут работать — и работают — вместе.
Рассмотрим панель навигации в моем дизайне. Многие годы он строился на ненумерованном списке с float: left
для его пунктов. Если чуть упростить, CSS и разметка выглядели примерно так:
#navlinks { float: left; width: 100%; } #navlinks li { float: left; list-style: none; margin-left: 1px; }
<div id="navigate"> <ul id="navlinks"> <li><a href="…">Archives</a></li> <li><a href="…">CSS</a></li> <li><a href="…">Toolbox</a></li> <li><a href="…">Writing</a></li> <li>><a href="…">Speaking</a></li> <li>>><a href="…">Leftovers</a></li> </ul> </div>
Почему float: left
, а не display: inline-block
? Потому что, когда я писал CSS для навигационных ссылок, такого выбора буквально не было, а у меня так и не дошли руки его обновить (возможно, вы уже замечаете определенную закономерность).
Теперь у меня есть два намного лучших варианта для выстраивания этих ссылок: гриды и флексбоксы. Я мог бы задать там грид, что выглядело бы примерно как-то так:
#navlinks { display: grid; grid-template-columns: repeat(6,min-content); } #navlinks li { list-style: none; margin-left: 1px; }
Это даст фактически тот же самый результат, но в виде грида, что гораздо надежнее и флоатов, и инлайн-блоков.
С другой стороны, тогда я использовал бы гриды, то есть двумерную систему раскладки, для одномерного фрагмента. Конечно, это возможно, но кажется слегка перебором, и гриды всё-таки придуманы не для этого. А вот флексбоксы созданы как раз для такого рода ситуаций.
Так что вместо этого я мог бы написать следующее:
#navlinks { display: flex; justify-content: flex-start; flex-wrap: wrap; } #navlinks li { list-style: none; margin-left: 1px; }
Опять же, результат будет по сути тот же, но в более надежном варианте. Вдобавок к выравниванию ссылок в строку, значение wrap
позволит ссылкам перенестись на вторую строку, если нужно. А поскольку эти флексбоксы сидят внутри грид-элемента, который принадлежит грид-ряду, высота которого равна min-content
, любое увеличение высоты (из-за переноса или чего угодно) сделает выше весь ряд целиком. То есть следующие ряды сдвинутся вниз, высвобождая необходимое ему место.
И сейчас, снова взглянув на разметку, я понял, что могу упростить ее, не затрагивая каких-либо стилей гридов. Я могу не оборачивать список в div
, а выбросить этот div
и переприсвоить его ID самому списку. То есть разметка станет такой:
<ul id="navigate"> <li><a href="…">Archives</a></li> <li><a href="…">CSS</a></li> <li><a href="…">Toolbox</a></li> <li><a href="…">Writing</a></li> <li><a href="…">Speaking</a></li> <li><a href="…">Leftovers</a></li> </ul>
После исправления селекторов у меня в CSS c #navlinks
на #navigate
итоговая раскладка будет той же, что и прежде. Элемент ul
станет грид-элементом и при этом флекс-контейнером. Теперь можно делать и так.
Недостаток в моем случае — придется снова разбираться с тем, как это изменение взаимодействует с моей старой раскладкой, но это не такая уж большая проблема. Надо будет просто взять и сделать это.
Разочарования
Каковы же минусы? Их немного, но они есть.
Самый фундаментальный — нет способа определить сетку для всей страницы, к которой можно было бы привязать все элементы. Другими словами, если я напишу:
body { display: grid; grid-template-columns: repeat(16, 1fr); }
…то это задаст гибкую 16-колоночную сетку только для элемента body
, и грид-элементами смогут стать только его непосредственные потомки. Я не могу размещать в этом гриде для body
элементы с других уровней дерева документа. Вот в чем главная причина, почему я не попытался вставить в общий грид ту боковую панельку из моих статей в блоге: на сегодняшний день я попросту не могу этого сделать, не прибегая к ужасным CSS- или HTML-хакам.
Возможность делать подобное известна как подсетка, и пока не реализована ни в одном браузере. Есть вопросы, как именно это должно — и как не должно — работать, так что надеемся, что в конце концов их решат. Досадно, что этой возможности нет до сих пор и из-за этого гриды нельзя использовать в полную силу, но, хочется верить, это временно.
А пока, уверен, люди придумают способы обходить это ограничение. В нашем случае простейший обходной путь такой: я мог бы задать грид, который применяется к каждой отдельной статье блога, и расположить части каждой статьи по этому вложенному гриду. CSS получился бы примерно таким:
div.post { display: grid; grid-template-columns: [meta] 10em [main] 1fr; grid-template-rows: [title] min-content [main] 1fr; }
С ним я разместил бы метаданные, заголовок и тело статьи в соответствующие ячейки грида, либо с помощью номеров грид-линий, либо их имен, которые я задал. Наподобие:
div.post h3 { grid-column: 2; grid-row: title; } ul.meta { grid-column: meta; grid-row: main; } div.post div.text { grid-column: main; grid-row: main; }
Недостаток в том, что метаданным тогда нужно быть строго определенной ширины, я не могу задать одну колонку для всех метаданных сразу и задать ей размер по наибольшему фрагменту содержимого. Но это ничем не хуже того, что у меня сейчас, когда я задаю фиксированную ширину плавающему блоку с метаданными, так что я ничего не теряю. Лишь (временно) недополучаю возможность приобрести что-то большее.
Еще одно ограничение, про которое пока неясно, будут ли с ним как-то бороться — нельзя напрямую задавать стили самим грид-ячейкам. Допустим, я хочу обернуть боковую панель #extra
рамкой, полностью заполняющей эту ячейку. Для этого мне приходится задавать стили div
у. Я не могу сделать что-то типа такого:
@grid-cell(2, 3) { background: teal; border: 1px solid; }
То есть я не знаю, будет ли синтаксис сколько-либо похож на это (скорее всего нет), такую возможность только начали обсуждать в рабочей группе CSS. Если у вас нашлись применения для подобной возможности, непременно поделитесь ими с миром и ребятами в www-style. Чем больше примеров из реальной жизни, тем заметнее необходимость в их поддержке.
И, разумеется, будут баги, которые надо исправлять. Например, когда я дописывал эту статью, я обнаружил, что в некоторых ситуациях Chrome 57 при использовании гридов может страдать пропадающим контентом. Похоже, что это возникает при убирании абсолютно позиционированных элементов со страницы с гридами, и может вызываться расширениями типа Window Resizer и LastPass. Хорошие новости, что в Chrome 58 уже внесено исправление, так что самое позднее к концу апреля 2017-го эта проблема уйдет.
Сила гридов
Надеюсь, этот обзор внедрения гридов в существующий сайт дал вам представление о новых возможностях. Но хочу предупредить, что это лишь представление, притом далеко не полное. Я едва коснулся поверхности того, какие возможности дает синтаксис CSS-гридов, так что, если это уже дало пищу вашей фантазии, я настоятельно советую вам взяться за эксперименты, а затем углубиться в спецификацию CSS Grid Layout и узнать, что еще можно там делать (грид-интервалы! Плотная упаковка гридов! Инлайн-гриды! Автозаполнение рядов и колонок!).
Даже больше того, всё, что я рассмотрел здесь — лишь одна крошечная песчинка на берегу маленького островка в океане возможностей, которые дают гриды. Уверен, что с ним можно сделать наши существующие дизайны гибче, надежнее и проще в поддержке. Это просто здорово. Но с ним можно делать и такие раскладки, о которых мы и не мечтали, потому что с ранее доступными нам инструментами они были просто невозможны. Немало новых приемов и даже целых новых художественных направлений в дизайне еще предстоит открыть. Столь глубинных перемен не случалось с нами с той поры, когда мы впервые перешли с таблиц на CSS-верстку. Надеюсь, и ваши открытия войдут в будущие летописи этого неизведанного мира.
Ссылки
Как я уже сказал, это было в лучшем случае введение. Хотите узнать больше? Вот несколько замечательных ресурсов, которые непременно надо посетить:
- Анонс CSS-гридов и инструмента инспектирования гридов в Firefox
- Экспериментальная лаборатория раскладок Джен Симмонс — коллекция примеров и экспериментов, от практичных до высокохудожественных изысков
- Руководство по CSS-гридам на MDN — главная база для 11 статей Рэйчел Эндрю, написанных специально для MDN
- Гриды на примерах — коллекция Рэйчел Эндрю с примерами, туториалами и видео
- Грид + флексбокс: мощнейшее комбо в веб-раскладке — отличный взгляд на объединение этих двух техник раскладки Чэнь Хуэй Цзина.
P.S. Это тоже может быть интересно: