Модуль CSS Grid — это фантастический инструмент для создания макетов веб-сайтов. Он позволяет вам экспериментировать с макетами быстрее, чем любой другой инструмент, которые я пробовал.
В этой статье я научу вас, как это сделать.
Во-первых, я объясню HTML и CSS, которые нам нужны для этой задачи, которую я разбил на четыре части. Как только вы с этим разберетесь, мы перейдем к экспериментам с макетами.
Если вы совершенно не знакомы с CSS Grid, вам может понадобиться просмотреть мою предыдущую статью Учим CSS Grid за 5 минут.
Наш Grid
Мы собираемся начать с очень простой сетки, которая имитирует классический веб-сайт:
Я немного стилизовал наш пример, но это не имеет ничего общего с CSS Grid, поэтому я оставляю это.
1. Разметка
Первое, что нам нужно, это немного HTML. Контейнер (элемент который мы превратим в сетку) и элементы (хедер, меню, контент, футер).
<div class="container">
<div class="header">HEADER</div>
<div class="menu">MENU</div>
<div class="content">CONTENT</div>
<div class="footer">FOOTER</div>
</div>
2. Базовая настройка CSS
Затем нам нужно настроить нашу сетку и указать, сколько строк и столбцов нам нужно. Вот изначальный CSS для этого:
.container {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: 50px 350px 50px;
grid-gap: 5px;
}
Я собираюсь добавить еще, но сначала хочу, чтобы вы разобрались с этим.
Вот что говорит вышеприведенный код: создать сетку с двенадцатью столбцами, каждый шириной доли единицы (1/12 общей ширины). Создать три строки, где первая будет 50px высотой, вторая 350px и третья 50px. Наконец, добавить промежуток между элементами в сетке.
3. Добавление grid-template-areas
Функция, которая позволит нам легко экспериментировать с макетом, называется шаблоном.
Чтобы добавить его в Grid, мы просто дадим контейнеру свойство
grid-template-areas
. Синтаксис может быть немного странным, поскольку он отличается от любого другого синтаксиса CSS. Вот он:.container {
display: grid;
grid-gap: 5px;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: 50px 350px 50px;
grid-template-areas:
"h h h h h h h h h h h h"
"m m c c c c c c c c c c"
"f f f f f f f f f f f f";
}
Логикой свойства grid-template-areas является то, что вы создаете визуальное представление вашей сетки в коде. Как видите, он имеет три строки и двенадцать столбцов, точно так же, как мы определили в
grid-template-columns
и grid-template-rows
.Каждая строка кода представляет строку в макете, и каждый из символов (h, m, c, f) представляет ячейку сетки.Каждая из четырех букв теперь образует прямоугольную
grid-area
.Как вы могли догадаться, я выбрал символы
h, m, c, f,
потому что наш Grid состоит из header
, menu
, content
и footer
. Разумеется, я мог бы назвать их так, как захочу, но имеет смысл использовать первый символ элементов, которые они описывают.4. Предоставление областей для элементов
Теперь нам нужно связать эти символы с нашими элементами в сетке. Для этого мы будем использовать свойство
grid-area
:.header {
grid-area: h;
}
.menu {
grid-area: m;
}
.content {
grid-area: c;
}
.footer {
grid-area: f;
}
Вот что мы получим:
Эксперименты с макетом
Теперь мы наконец достигли красоты этой функции, так как мы можем легко экспериментировать с макетом. Это просто изменения положения символов в свойстве
grid-template-areas
. Давайте, например, переместим меню в правую сторону:grid-template-areas:
“h h h h h h h h h h h h”
"c c c c c c c c c c m m”
“f f f f f f f f f f f f”;
Вот такой результат получится в этом макете:
Мы можем использовать точки для создания пустых ячеек сетки.
grid-template-areas:
“. h h h h h h h h h h .”
"c c c c c c c c c c m m”
“. f f f f f f f f f f .”;
Вот как это будет выглядеть:
Теперь я рекомендую вам посмотреть этот скринкаст моего курса CSS Grid, где вы сможете экспериментировать с кодом самостоятельно.
Добавление адаптивности
Сочетание этого с адаптивностью также является функцией убийцей, так как это просто не могло быть возможно только с HTML и CSS. Предположим, вы хотите, чтобы меню поднималось к хедеру, когда страница просматривается на мобильном устройстве. В этом случае вы можете просто сделать так:
@media screen and (max-width: 640px) {
.container {
grid-template-areas:
"m m m m m m h h h h h h"
"c c c c c c c c c c c c"
"f f f f f f f f f f f f";
}
}
И это приведет к следующему:
Помните, что все эти изменения выполняются с помощью чистого CSS, не касаясь HTML. Мы можем перемещать элементы так, как мы хотим, независимо от того, как теги div находятся в разметке.
Это называется независимостью от источника, и это огромный шаг вперед для CSS.
Это позволяет HTML быть тем, для чего он был предназначен: разметка для контента. А не для стилизации, так как это работа CSS.
Доступ к бесплатному курсу CSS Grid от автора поста.
Превью курса.
Перевод выполнен при поддержке компании EDISON Software, которая профессионально занимается разработкой сайтов на Amiro.CMS и WordPress и для крупных заказчиков.
Комментарии (54)
AxisPod
04.12.2017 12:00Что толку экспереминтировать с grid, если нормально не поддерживается тем же IE? А если уж учесть, что якобы полностью поддерживается flex в IE и Safari, но при этом на деле это не так, а grid в IE поддерживается частично, потом так или иначе шаманить и фиксить непонятно откуда всплывшие баги?
Zenitchik
04.12.2017 12:47Ох, прямо как будто это первый случай, когда для IE нужны костыли.
Ну да, старые костыли мы выбросили, чуть было не обрадовались, что новые будут не нужны, а нас так обломали. Обидно, досадно, но в целом — всё как обычно.
SelenIT3
04.12.2017 16:33Прогрессивное улучшение — наше всё. Сначала сделать, чтобы везде было функционально, а потом добавить особую красоту туда, где она может улучшить пользовательский опыт, не требуя рискованных хаков и костылей. Как сейчас и советуют знатоки.
Akuma
04.12.2017 17:18+1Как связаны прогрессивное улучшение и css-сетка?
Вы можете прогрессивно улучшать, например, box-shadow. Когда он поддерживается — тень есть, когда не поддерживается — да и хрен с ней с тенью. Вот это вот стоит делать.
А верстать сначала на float:left; а затем то же самое (на 100% совпадающее, иначе никак это ж верстка) на гридах… зачем? Не делайте одно и то же два раза ради… да я даже не знаю ради чего. Просто не делайте так.
Либо grid, либо float. Не мешайте их.SelenIT3
04.12.2017 17:43на 100% совпадающее, иначе никак это ж верстка
Это заблуждение родом из 90-х. Современная вёрстка фактически по определению адаптивная. И в число параметров, к которым можно и нужно адаптироваться, входит не только ширина окна браузера, но и возможности клиентского окружения. Для этого придумали целую директиву supports.
Пользователи хороших браузеров не должны страдать из-за того, что старые браузеры просто существуют! Ну а что верстальщикам придется написать на 5-10 строк кода больше — ну так это их работа, им за это платят:)
одно и то же два раза ради… да я даже не знаю ради чего.
Так узнайте. И делайте так:). Ради удобства пользователей — в конце концов, вы ведь для них стараетесь.
Akuma
04.12.2017 17:46with simple fallbacks for non-supporting browsers
Перевестать все и вся на float — это не simple fallback. Вот в этом основная проблема.
Я не спорю, что могут быть ситуации, когда можно сделать простой фалбек или вовсе оставить «как получится» на флоатах и «красиво» на гридах. Но в реалиях будет примерно так:
1. style.css
2. style-grid.css
Подключаются одновременно и в каждом свои баги, которые нужно поддерживать и исправлять. Я призываю именно этого избегать.SelenIT3
04.12.2017 18:00Не надо переверстывать то, что легко и изящно делается на гридах, кривыми и капризными костылями на флоатах и clearfix-ах. Надо делать в каждом браузере максимально хорошо для пользователя, насколько этот браузер позволяет «малой кровью». И просвещать заказчиков, требующих «везде одинаково», что пользователи не будут сидеть и скрупулезно сравнивать сайт в разных браузерах, а откроют его в чем-то одном и будут искать заветную кнопку «сделать заказ». Или не будут — если сайт чем-то (неважно чем — тормознутостью, глюками, общей «старомодностью»...) им не понравится.
Но не делать хорошо там, где можно, только потому, что настолько хорошо можно сделать не везде — не дело. Это не техническое обоснование, это верстальщицкая лень. Которая дает лишь небольшой сиюминутный тактический выигрыш (больше заработать методом «тяп-ляп и в продакшн», дольше побухать:), но стратегически от нее одни минусы (у конкурентов сайты будут быстрее, красивее и надежнее, можно упустить момент и оказаться морально устаревшим, как верстальщики на таблицах в конце 2000-х:). Конечно, во всём нужен разумный баланс, но просто так поощрять лень не надо:)
Akuma
04.12.2017 18:03Воу, я вроде бы ничего не говорил про «тяп-ляп и в продакшн» :)
SelenIT3
04.12.2017 18:06А для чего еще может понадобиться экономить время на том, чтобы сделать хорошо, надежно и современно? :)
Akuma
04.12.2017 18:11Например, чтобы сделать просто «хорошо и надежно».
«Современно» в вебе это не всегда хорошо и надежно, к сожалению.
Впрочем, думаю я понял вашу позицию. Поначалу я подумал, что вы предлагаете весь макет целиком и полностью верстать два раза, но, похоже, вы просто предлагаете «менее красивые» фалбеки для небольших кусочков верстки. Тут мое мнение с вашим совпадает.SelenIT3
04.12.2017 18:17«Современно» в вебе это не всегда хорошо и надежно, к сожалению.
В общем случае, согласен. Но в частном случае раскладки блоков использовать инструмент, изначально для нее предназначенный — в отличие от флоатов, инлайн-блоков, колонок и прочего, чем нам приходилось поневоле выкручиваться до сих пор — почти всегда будет надежнее и быстрее, чем эмулировать то же поведение хаками и/или скриптами. Не говоря о новых возможностях, которых у старых технологий в принципе не было (напр. выравнивания чего угодно как угодно).
«менее красивые» фалбеки для небольших кусочков верстки
Именно так!
Akuma
04.12.2017 18:18Смотря для каких участков страницы :)
Сложная сетка — да, почему бы и не гриды.
Просто блоки 3х33%? Поставьте флоаты и не мучайте мой ИЕ 8 :)SelenIT3
04.12.2017 18:22Для IE8 по-любому будут флоаты или инлайн-блоки, он другому не обучен.
Но зачем мучить флоатами и инлайн-блоками (требующими reflow с repaint-ом чуть ли не всего body при появлении в любом из элементиков малейшего намека на динамику, т.к. они зависят друг от друга, как падающие костяшки домино) мой Хром, когда можно дописать 3-5 строчек CSS и обеспечить его железобетонной сеткой на гридах? :)
Akuma
04.12.2017 17:49Я это не из головы беру. Во времена, когда не поддерживался border-radius многие делали так же:
Отдельный код для «уголков картинками» и отдельный с border-radius. И когда вся страница в этих уголках, там получается такая ядреная смесь, что пипец просто.
Так критичны уголки? Оставьте все на картинках и не мучайтесь.
А для гридов ситуацию с фалбеком не каждый верстальщик даже придумать сможет, не то что реализовать. Ну правда же.
Да, кстати. caniuse.com/#search=supports
Отличный вариант для фаллбека на IE :)SelenIT3
04.12.2017 18:04Именно что отличный. Браузеры, не понимающие supports (в т.ч. IE) просто проигнорят всё, что внутри него.
А варианты можно найти практически всегда. Например, вместо вот такой аккуратно выровненной сетки можно сделать более примитивную, прижатую к левому краю, на инлайн-блоках или тех же флоатах. Пользователи старых браузеров не заметят разницы, а новых — порадуются красоте:)
iGetPass
04.12.2017 18:21Верстка только на дивах — зло. Спецификация html5 добавила много президент рамных тегов, которые помогают в чтении кода, сео и доступности для скрин ридеров
mSnus
05.12.2017 00:12Какой же ад будет поддерживать сайты с этой сеткой, float-ами и flexbox вперемешку… "… я поставил компонент 'Позвоните нам' и у меня что-то меню пропало.."
SelenIT3
05.12.2017 21:58+1В рамках одного контейнера «перемешки» быть не может — все три штуки взаимоисключающие. И
grid
, иflex
отменяют действиеfloat
для потомков (удобно для фолбэков!), а из них двоих применяется то, что объявлено позже. Только сposition:absolute
могут быть нюансы, но абсолют — он и вАфригридах абсолют.
А компоненты из разных контейнеров друг другу мешать не должны. И если всё-таки мешают — проблема ну явно не в гридах:)
maslyaev
Zenitchik
Вы никогда на LaTeX не писали?
maslyaev
Господь миловал.
izzholtik
Фронтэнд исторически поражает синтаксисом, рассчитанным на слабоумных, и вырастающими из него тоннами сложностей и исключений. Это нормально.
плачет
izzholtik
святые костыли, как же я ненавижу, когда обрамлённый какими-то символами тест превращается во что-то другое, теряя изначальный посыл, причём на каждом сайте это работает по-разному. Ещё один пример излишней заботы о слабоумных, не осиливших теги или хотя бы BBcode.
Athari
BBcode — это извращение над HTML, которое не имеет права на существование. Он был придуман для того, чтобы "обезопасить" пользовательский ввод. Если хочется тегов, то в современном мире использовать не HTML (возможно, с дополнительными тегами) — это маразм.
Кроме того, что HTML, что BBcode очень неприятно набирать в отличной от английской клавиатурной раскладке. Заставлять постоянно переключать раскладку — это издевательство над пользователем.
И таки для markdown есть какой-никакой стандарт. Много где остаётся царское наследие, но в будущем всё должно свестись к CommonMark.
И да, markdown включает подмножество HTML, поэтому, если так хочется хочется теги, всегда можно использовать их. На этом сайте даже галочка для отключения парсинга MD есть.
maslyaev
присоединяется
mrsweet
А почему вообще синтаксис должен быть сложным?
izzholtik
Потому что
мир несправедливпредметная область сложная, и синтаксис должен быть достаточен для её описания. А его намеренно упрощают до такой степени, чтобы для понимания именно синтаксиса не надо было прилагать вообще никаких усилий (вероятно, для создания видимости простоты и поддержания всего этого вот «войти в айти», но это не точно), в результате чего для решения реальных задач нужно использовать костыли и хаки.За примером далеко ходить не надо, из прошлой статьи цикла:
То есть ради того, чтобы синтаксис был прост и единообразен как консервная банка, сотням тысяч программистов придётся держать в уме виртуальные «четвёртые» колонки. Великолепно.
vbif
Зачем «держать в уме»? Достаточно понять принцип.
izzholtik
Это и есть заучивание странностей движка. Такой себе извращённый подвид перехода бага в фичу посредством документирования.
vbif
Где здесь странности? Как раз наоборот, если бы нумеровались колонки, а не границы, было бы сложнее понять принцип работы.
izzholtik
Зачем «понимать» очередной «принцип», если можно просто указывать начало и конец в том виде, в котором их понимает человек?
vbif
В этом смысле Grid Layout сделан идеально.
bazil
Спросите авторов, поинтересуйтесь зачем они так сделали. Хейтить всегда легко, использовать фразы "понимает человек". Зачем вы нам своё недовольство выливаете ?
izzholtik
Потому что могу и потому, что это даже не оффтоп?)
Мне вообще больше нравится способ разметки из Java/Android, когда в сетках (GridLayout / GridBagLayout) элементам неединичной ширины задаются не начало и конец, а собственно ширина. Здесь же мы имеем гибрид этих двух подходов: простые элементы располагаются на сетке автоматически, а «широкие» приходится прибивать гвоздями к координатам. Хотя насчёт гвоздей могу ошибаться, пока ещё не сильно лапал эту фичу.
SelenIT3
Не проблема — возьмите и укажите их в таком виде:). Грид-линиям можно давать произвольные имена. А если у вас есть именованные грид-области, то их начало и конец автоматически получают имена
имя_области-start
иимя_области-end
. Куда уж еще понятнее? :)izzholtik
CSS is awesome :D
SelenIT3
И сейчас, пожалуй, эту фразу впервые можно употреблять без иронии!
Zenitchik
Понимание принципа — это не заучивание.
SelenIT3
Не придется. Нумерация грид-линий — лишь один из over 9000 способов обратиться к ним. Выбирайте из всего многообразия то, что вам больше по душе (и по задаче:).
Вообще когда-то было хорошее правило хотя бы бегло ознакомиться с предметом критики (скажем, пробежавшись по оглавлению спеки), прежде чем бросаться обвинять авторов в чем-либо. Например, прежде чем ругать конструкторов бензопилы за тяжелую и неудобную ручку «этой дурацкой ножовки», было бы неплохо выяснить, что бензопилу можно заправить и включить. Жалко, что в вебе это правило больше не работает...
izzholtik
Придётся. Потому что иначе они не смогут читать код людей, ипользующих этот способ. Это как ситуация с ++i: мало кто использует, но помнить приходится всем.
Athari
Я не понял, а что именно с
++i
надо запоминать? Арифметические знаки, знаете, запоминать приходится. Ещё в школе заставляют.maslyaev
Тут мы наблюдаем не сложность синтаксиса, а его хаотичность и дырявость. На первый взгляд (взгляд ребёнка или кого-нибудь падкого на вау-эффект) кажется всё предельно просто — берёшь и буковками рисуешь чё в результате хочешь увидеть. Красота. Но мы-то с вами знаем, что код совсем не обязательно пишется руками. Я бы даже сказал, что он чаще пишется алгоритмами, чем руками. А теперь представьте себе, какой это ад написать генератор страницы, который будет выписывать эти все «a a a» и «b b b». В зависимости от каких-нибудь опций, настроек, прав пользователя и чёрта лысого. По постановке задаче, уточняющейся пару раз в день.
и пойдёт напишет заявление по собственному. Ибо сколько можно издеваться над организмом?Протрахавшись неделю, разраб константой вклячит что-нибудь вроде такого:
SelenIT3
Вот только это не понадобится. Для автоматической генерации в гридах предусмотрены специально обученные инструменты, в частности, именованные линии с волшебными окончаниями
-start
и-end
, которые достаточно один раз поставить в нужные места шаблона вgrid-template-columns
и-rows
соотв-но. А «верстка ASCII-артом» из примера предназначена именно для быстрого набрасывания простого макета человеком (в т.ч. ребенком — почему нет?:).maslyaev
Видел эти «start» и «end» в предыдущей статье цикла (которая «за 5 минут»). Это, конечно, менее вопиюще, но по своей сути столь же безумно. ИМХО, конечно.
Я понимаю, фронтендеры через себя ещё и не такое пропускают, но, господа, это всё же ненормально. Берегите себя.
SelenIT3
Там были другие «start» и «end»:). Там были начало и конец элемента в координатах грида. Но можно задать начало и конец и области в самом гриде, не заполняя ее буквами, как здесь. Сила (но и сложность) гридов именно в наличии множества альтернативных записей для одного и того же действия, которые можно выбирать по задаче. Ну и даже самый извращенный из этих вариантов всяко здоровее, чем центрирование через
margin:auto
, clearfix-хаки и прочие давно привычные для верстальщиков штуковины:)kuftachev
Не соглашусь. В этом примере выглядит все логично, достаточно красиво и компактно. Для того же Flex-Box будет больше кода. Вопрос в другом, как это все будет выглядеть в том случае, если будет не 4 элемента на страницу, а хотя бы 100? Как будут выглядеть вложености?
Кстати, если там не одна буква для обозначения, то можно писать более полно, а для прода минифицировать…
В общем, я хочу сказать, что есть много вопров, и что многие технологии красивы на уровне «Hello, world!», а потом превращаются в кашу.
SelenIT3
Для 100 элементов, скорее всего, лучше использовать как раз другие варианты разметки грида — не с именованными областями, а с
repeat()
и «массивами» именованных линий. Имхо, уж в чем-чем, а в недостатке гибкости синтаксиса CSS-гриды обвинить трудно:).Вот со вложенностями, увы, пока всё довольно грустно. В ранних черновиках были подсетки (subgrids), но с ними всплыло много сложностей в реализации, так что их отложили на 2-й уровень спеки. Частично проблему решает display:contents, но он пока работает без флагов только в Firefox и совсем недавно в WebKit (хотя в Хроме он тоже реализован и где-то в ближайшей паре-тройке релизов его должны вынести из-под флага, только Edge как обычно)...