В темные века верстальщики строили сайты на таблицах. Потом они освоили float и flexbox, и тьма отступила. В 2017-м наступила эпоха Просвещения с приходом CSS Grid Layout.
Grid учитывает горизонтальное и вертикальное пространство, с ним можно менять раскладку, не трогая разметку, и все это без медиазапросов. С Grid можно забыть про магические числа, хаки, обходные пути и CSS-фреймворки.
Несмотря на всю мощь, есть маленький нюанс, который портит картину — его все еще редко используют верстальщики. Спецификация Grid есть, браузеры поддерживают, а реальных проектов мало.
Об этом расшифровка доклада Сергея Попова на Frontend Conf: про спецификацию, про то, почему верстальщики боятся Grid и как решиться применять сетку в своих проектах, чтобы «Make your website great again!».
О спикере: Сергей Попов (popovsergey) — Генеральный директор аутсорса по фронтенд-разработке Лига А. от HTML Академии, фронтенд-разработчик, организатор сообщества moscowcss, соорганизатор WSD и pitercss_conf. Пока не стал руководителем в компании, много лет занимался версткой.
За последний год появилось много курсов и докладов про Grid, про то, как их использовать и писать. Если технические доклады вам надоели, то добавлю еще один в ваш список. Шутка — поговорим про комиксы. Или нет?
Примечание: вместо длинного «CSS Grid Layout» дальше будет просто «Grid».
Что сейчас с CSS Grid Layout?
Технически, Grid — это простая двухмерная сетка.
Нарисовать и использовать Grid достаточно просто, но разработчики все еще его сторонятся. Я вижу две причины для этого.
- Многие просто не понимают, что происходит с Grid. Большое количество мифов про этот инструмент мешают разобраться в нем.
- Мы, как верстальщики и фронтендеры, не понимаем, как и где применять Grid в повседневных задачах.
Начнем разбор с первого пункта.
Спецификация
Первая версия спецификации вышла в 2012 году, много менялась, переписывалась, и, спустя пять лет, начала активно внедряться. В 2017 случился тот самый бум, когда за полгода Grid из состояния первого опубликованного черновика пришел к тому, что сначала Chrome внедрил его без флага, а потом и все остальные браузеры. Из-за того, что внедрение происходило в спешке, спецификация не утряслась и некоторые спорные моменты пришлось оставить, чтобы браузерам не пришлось переписывать половину движка.
Спецификация стабильна, хотя до сих пор в статусе Candidate Recommendation. Если бы я мог, то давно бы уже зарелизил, но разработчики спецификации пока не спешат, а дополняют и меняют формулировки.
Давайте применять нерекомендованную спецификацию Grid Layout — в этом нет противоречия, потому что Grid сначала была реализован, а потом описан.
Второе неверное утверждение — это то, что Grid не имеет смысла без второго уровня.
Второй уровень спецификации
Когда писали спецификацию, она оказалась слишком большой, поэтому какую-то часть выделили во второй уровень. На 2018 год спецификация второго уровня в состоянии First Public Working Draft — первая публикация рабочего черновика.
Над спецификацией активно работают и в ближайшее время она перейдет в состояние Working Draft — рабочий черновик. Разработчики ждут, пока зарелизят Grid, но это долгий процесс, который может затянуться лет на 5.
По легенде спецификация второго уровня решает проблемы первого уровня. На самом деле она добавляет фичи, без которых можно обойтись, и ничего не мешает использовать первый уровень без второго.
display: subgrid;
Не успели мы понять, что такое grid, как появился subgrid. Давайте разбираться, что это такое.
Представим такую разметку.
Все довольно просто: у нас есть сетка, в нее вложено три несемантических и один семантический элемент. Grid работает как flexbox: когда вы применяете display: grid;
к обертке, он применяется только к элементам на первом уровне вложенности.
В примере 1, 2 и 3 <div>
займут место в сетке, а все, что находится внутри списка, — схлопнется. Вы потеряете все эти элементы, потому что так работает Grid.
Если хотите, чтобы эти элементы остались частью вашей сетки, то есть два варианта:
- Первый вариант — избавиться от обертки. Удалим
<ul>
, а<li>
заменим на<div>
. Мы убьем семантику, но оставим сетку.
- Второй вариант — использовать
display: subgrid;
.
Если применить display: subgrid;
к списку, то элементы <li>
станут частью этой сетки, <ul>
, как обертка, будет игнорироваться. Вы получите полноценную сетку и останется полноценная семантика — и HTML хорошо, и CSS хорошо.
Одна проблема — subgrid не поддерживается, он где-то там за флагами, а релиза можно ждать еще долго.
display: contents;
Вообще ждать не обязательно, потому что есть display: contents;
— замечательное свойство, которое работает так же, как display: subgrid;
. Если для элементов списка применить display: contents;
, то элементы <li>
станут частью сетки.
Есть нюанс — display: contents;
поддерживается не во всех браузерах.
CSS Subgrid Emulation
Пока у display: contents;
решают проблему поддержки, верстальщики придумали выход — сделали эмуляцию subgrid.
На слайде пример Паши Ловцевича.
В примере выше есть поведение subgrid, но его поведение эмулируется не посредством display: subgrid;
или display: contents;
, а за счёт кастомных выражений, которые пересчитываются в переменные.
Свойства с дефисом — это кастомные свойства в CSS.
Второй уровень не нужен
Если кто-нибудь скажет не использовать Grid, пока не выйдет второй уровень — не слушайте его. Второй уровень решает определенные проблемы, которые уже решены другими способами.
Не везде нужны subgrid. Grid в связке с Flexbox иногда получается куда круче, чем с subgrid.
Поэтому не надо ждать второй уровень, смело занимайтесь первым. Тем более, что он уже есть.
Поддержка Grid в браузерах
Эту картинку можно показывать, если кто-то скажет вам, что Grid не поддерживается.
Глобально поддерживается 87% браузеров, кроме Opera Mini — она ничего не поддерживает. Я писал в CanIuse, просил убрать ее из колонки, чтобы не портить картину, но пока безрезультатно ;)
Если добавить @supports
, то работает вообще все, даже Opera Mini. Я не знаю, поддерживает ли Opera Mini flexbox, но там можно сделать fallback.
Остается проблема с IE. Как всегда, он здесь, с нами, и никуда не делся.
IE и Grid
Если ваше приложение поддерживает IE, вы возможно скажете, что не можете использовать Grid. Это не так — Grid работает в IE, так как спецификация была рождена в Microsoft, и впервые появилась именно в IE. Просто ее никто не использовал, пока не пришли нормальные люди и не переписали спецификацию.
IE справляется с Grid, но ему нужно объяснить, как это делать. IE поддерживает Grid в старой версии спецификации, в которой не все свойства поддерживаются, а часть называется по-другому.
Версию спецификаций для IE учить не нужно, потому что большую часть работы за вас сделает Autoprefixer — плагин, который переводит новую версию спецификации в старую. Поэтому, чтобы обеспечить поддержку Grid в IE, достаточно использовать Autoprefixer.
Остальное надо просто знать и помнить. Достаточно открыть статью «Supporting CSS Grid in Internet Explorer», прочитать какие свойства поддерживаются в IE, а какие нет, и решить, что из них вы будете использовать.
Помните про «graceful degradation», когда в старых версиях браузера пропадают элементы из новых. Например, в браузерах, в которых не поддерживается border-radius, у форм будут квадратные уголки. Верстальщиков заставляли вырезать картинки форм, вместо CSS, и в некоторых ситуациях это считалось нормальным.
Почему бы в старых версиях браузеров не переводить Grid в обычные колонки? Если вы разрабатываете под старый браузер, либо не используйте современные технологии, либо смиритесь с тем, что контент в них будет выглядеть по-другому.
Internet Explorer вместе с Grid работает неплохо, просто надо немного практики. Если вы не используете Grid, потому что боитесь IE, то я вынужден вас удивить — это не прокатит.
Баги и Grid
Вы можете сказать, что в Grid много багов, но это не так. Rachel Andrew нашла все ошибки в CSS Grid — всего их 14, и это все что есть. Никто не занимается Grid Layout CSS больше, чем Рейчел, поэтому ей можно доверять.
Баги довольно специфические. Мы помним, когда пришли flexbox, в них тоже были баги, но нас это не остановило. Баги в Grid нас тоже не останавливают, тем более, такие.
«Некоторые HTML элементы не могут быть Grid-контейнером». Сразу идет уточнение, что кнопка не может быть Grid-контейнером, но мы и не хотели этого.
«Textarea, когда она является элементом Grid, схлопывается». Проблема легко решается, если поставить ширину и высоту в процентах.
Эти баги довольно специфические и проявляются не во всех браузерах. Если ты знаешь, что баг может проявиться, то просто берешь и исправляешь — это несложно.
Технических причин не использовать Grid не так уж много. Браузеры поддерживают, а в старых браузерах применяйте «graceful degradation». Теоретических причин тоже мало, потому что материалов больше, чем по flexbox.
Теория, или маленький ликбез
- Выжимка спецификации — «A complete guide to Grid» от СSS-Tricks настолько же хороша, как и по flexbox.
- Курс Learn CSS Grid или видеокурсы, например, от Wes Bos, записанные и спонсированные Mozilla.
- Полное погружение на сайте Gridbvexample.com: сам сайт написан на Grid, там есть информация по всем спецификациям, примеры, сниппеты кода.
- Игра с морковками — полная геймификация, даже дети разберутся.
- Интерактивный курс HTML Academy. Академия внедрила Grid в учебный процесс.
Grid уже здесь! Мы можем долго говорить почему не используем Grid, но пока вы читаете статью, Grid уже задеплоили в продакшен.
Сайты уже используют Grid. Например, я зашел на сайт Russian Internet Week, и это последнее место, где я ожидал увидеть Grid. Обычно сайты бизнес-конференций собираются на Тильде.
Причем они более-менее правильно используют сетку. RIW попробовали, и у них получилось, причем без fallbacks. Они явно ориентируются на пользователей современных браузеров.
Конференции, которые рассказывают про CSS, в любом случае, пытаются применять новые инструменты. Мы на сайте pitercss_conf сделали бейджики, а у ребят из Минска половина сайта на Grid.
Russian Internet Week — это довольно узкая аудитория посетителей. New York Times читает больше людей.
Я уверен, что среди читателей есть владельцы устройств даже с IE 9, 10, 11, но половина сайта на Grid.
Я был удивлен, когда увидел, что такие крупные проекты используют Grid.
Почему Grid не используют повсеместно?
Мы поняли, что спецификация есть, ее можно использовать и никакие отговорки не сработают. Так в чем же дело?
Есть определенные причины не применять сетки:
- Дизайнеры не ставят перед верстальщиками неразрешимых задач.
- Верстальщики не понимают, как приложить Grid к реальным проектам. Скорее всего ваш дизайнер не нарисовал сложную сетку, и вы не понимаете, как приложить Grid к макету.
С точки зрения дизайна
Сейчас я буду защищать дизайнеров.
Дизайн развивается медленно, по своим трендам, никак не связанным с развитием веб-технологий. Скорее наоборот — веб-технологам приходится подстраиваться под тренды дизайна. Маловероятно, чтобы верстальщики сказали: «Дизайнеры, а у нас есть Grid, можно с ним работать», а они бы ответили: «О, да!» и начали рисовать под них макеты.
Поэтому большинство сайтов выглядит так.
Абстрактный пример с простой сеткой и колонками, ничего необычного. Сайт легко собирается без flexbox, на float, даже можно обойтись табличной версткой.
Дизайнеры перестали ставить перед верстальщиками сложные задачи, потому что когда-то мы сами загнали их в угол тем, что перестали делать то, что они хотят.
Приходит к нам дизайнер и говорит:
— Я хочу сложную сетку!
— Я не могу. Она сложная.
— Нет, делай.
— Я не могу!
Потом мы идем к менеджеру, жалуемся, и дизайнер получает по голове.
Все, дизайнер больше не рисует сложные сетки. Раньше мы действительно не могли строить сложные интерфейсы, а сейчас можем — у нас полно инструментов. Теперь дизайнер не хочет, он перестал просить сложные макеты. Дизайнер рисует интерфейс, чтобы верстальщик смог его реализовать, и часто максимально примитивно.
Блог
Приведу распространенный пример из нашего аутсорса. Дизайнер получил задачу нарисовать блог и дает волю всем своим сеточным порывам. Рисует большой блок, широкий, 3 маленьких, средний, фантазирует. Выглядит круто и современно.
Верстальщик видит макет, пишет на flexbox одну обертку, вторую, третью и получает вот такую картинку.
Верстка идет в бэкенд.Бэкендер говорит верстальщику, что у него есть вывод из базы данных, а там карточки идут друг за другом, разложить их не получится.
На этом счастливая история заканчивается и мы возвращаемся к дизайнеру.
Когда дизайнер рисовал макет, то представлял и другие варианты. В вариантах был полет фантазии, а бэкендер сломал порывы в один момент. План сделать красивый блог, провалился.
Здесь есть разные варианты выхода:
- Дизайнера отправляют в дальний угол и говорят: «У нас будет все просто друг за другом, обойдемся без твоих выпендрежей, сделай — то, что можно реализовать на flexbox». Дизайнер будет страдать, но выложит на Behance портфолио с красивой сеткой. В макете будет ссылка на продакшен, а там просто квадратики.
- Верстальщик навешивает jQuery-плагин, который автоматом расставляет элементы по сетке с абсолютным позиционированием — все прекрасно! Кроме того, что плагин будет дополнительно нагружать страницу и безбожно лагать в IE. Однако, дизайнер и бэкендер будут довольны.
- Дизайнер и верстальщик договорятся и реализуют невероятную историю и приведут к компромиссу дизайн, бэкенд и верстку.
Реальный кейс
На главной странице журнала «The Village» сложная сетка. Она выполнена намеренно для разных типов материалов. Я знаю про это, так как работал в издании.
«The Village» написали огромный алгоритм, который на бэкенде генерирует сетку. Это смесь float, абсолютного позиционирования и других страшных вещей, но она работает!
Иногда ломается, но, когда это происходит, блоки просто переставляются местами и снова все работает.
Не представляю, сколько часов ушло на то, чтобы спроектировать эту систему, отладить и добиться, чтобы она работала практически без ошибок. Сколько времени бы ушло на реализацию этой же сетки, если использовать display: grid;
или grid-auto-flow: dense;
? Внутри Grid есть отдельная спецификация, которая автоматом расставляет элементы по странице, сама забивает свободные места и реализует подобную сетку. Не надо десяти тысяч строк кода бэкенда — все работает только одним свойством.
На момент создания алгоритма этой технологии еще не было, но когда речь пошла о редизайне, я предложил сразу использовать Grid.
В «The Village» заморочились, чтобы сделать как хотят, но большинство этого не делает. Поэтому мы видим заурядный веб, стандартизацию, все сводится к одному Layout. Раньше у нас был Bootstrap, который описывает большую часть кода. Сейчас уже у дизайнеров есть свои инструменты, наподобие Bootstrap, которыми они собирают сайты. Что за ерунда — где креатив?!
Наша задача состоит не в том, чтобы внутри сообщества договориться использовать Grid, а в том, чтобы мы рассказали об этом дизайнерам.
Я мечтаю выступить на конференции дизайна и сказать: «Привет! Мы стали лучше! Мы теперь снова умные», но верстальщика не пускают на дизайнерские конференции. Рассказать дизайнерам, что мы стали лучше — это не так уж сложно. Вам пришла простая сетка, вы спрашиваете: «Почему она простая, а не сложная? Я могу сделать любую!»
С точки зрения реализации
Кажется, что Grid сложно найти. Когда мне говорят: «У меня 3 колонки и я могу сделать это на flexbox. Зачем мне Grid?», то я отвечаю: «Действительно, не надо». Поэтому возникают сложности с тем, где вообще прикладывать Grid.
Grid — это не только сложная сетка
Это и простая раскладка, которую можно сделать на Grid, причем проще, чем на flexbox, потому что не нужна дополнительная обертка. Ниже есть один пример на Grid, его тоже можно сделать на flexbox, но надо много дополнительных оберток или flow, и получится настоящая мешанина.
Grid — не для мелких элементов: либо для очень сложных мелких, либо для крупных.
Grid для раскладки
Я не знаю ни одного сайта, у которого нельзя переписать раскладку на Grid и сэкономить на этом кучу бесполезных дополнительных оберток.
- Grid можно применить к глобальной раскладке.
- Grid можно применить к элементам интерфейса
Это бейджик pitercss_conf-2, он сделан на сетке.
Самое сложное в Grid Layout — это начертить сетку, которая вам подходит. В данном случае это не просто 6*6, а 5*8, но у каждого блока разная высота и ширина.
Мы видим задачу и компонуем контент, очень похоже на направляющие в Photoshop. Дизайнер отрисовал, а мы перевели макет на сетку. Здесь нет ни одной дополнительной обертки — только семантические элементы, которые выстраиваются в сетку с помощью Grid.
Посадочный талон можно сделать на flexbox.
А можно на Grid, и в мобильной версии талон выглядит по-другому.
Grid для структуры
Вторая важная вещь, которую нужно запомнить: с помощью Grid просто менять структуру.
Есть order во flexbox, который позволяет поменять порядок всех элементов. Это сложная технология, и как с Z-индексами можно выстрелить себе в ногу, если не знать, как ей пользоваться.
С Grid все просто. В этом примере, если бы не было сетки, нам бы пришлось правую часть с QR-кодом вынести в абсолютное позиционирование. А на Grid это 13 строк кода в мобильной версии.
Чтобы начать использовать Grid, надо начать использовать Grid. Попробуйте сверстать на сетке некоторые элементы вашего интерфейса. Можно начать с маленьких, можно — с глобальных, чтобы понять, насколько это упрощает жизнь.
Никто не скажет вам: «Вот здесь используй Grid, а здесь — нет!» Вы должны сами понять и научиться, но для этого нужно набивать шишки. Если реализация задачи на Grid заняла в два раза больше времени, чем на flexbox, значит, такие задачи не надо решать на Grid.
Вот для комиксов Grid идеален.
Рассмотрим нетривиальную задачу.
Если покопаться в коде, становится понятно, как все устроено. Ребята программируют на CSS и выстраивают Grid Areas. В зависимости того амплуа игрока, он автоматически встает в нужную Area. Вертикальное и горизонтальное выравнивание создает построение. Это целое программирование на CSS. Задача решается 50 строчками CSS-кода, что гораздо проще, чем через бэкенд или JS.
Я хочу, чтобы дизайны и раскладки были прикольными, такие как эта.
Это слишком сложная верстка на Grid, потому что задача была сложная. Верстальщик не мог отрисовать раскладку на простых flexbox, только Grid. Можно было сделать меньше ячеек, но учитывая, что ячейки строит repeat, на это много времени не ушло. Главное, что они сделали это.
Сверстано замудренно, но интерфейс очень круто перестраивается в дальнейшем.
Что дальше?
Давайте перестанем говорить себе: «Я не могу» в плане Grid. Вы можете — просто не хотите. Нет ни одной объективной причины не использовать сетку, кроме лени и нежелания попробовать.
Grid — это настолько универсальная система, что для нее даже невозможно сделать фреймворк. Если вы видите, что какой-то фреймворк использует Grid Layout — это бред, потому что Grid сам по себе фреймворк для построения сеток. Bootstrap вряд ли перейдет на Grid. Представьте, что там будет 20 миллионов классов — извращение!
Поэтому у вас никогда не будет готового решения. Возможно, будут шаблоны, но правил, где применять Grid, а где нет — не будет.
Учитесь, смотрите примеры, развивайтесь. Нет ничего плохого в том, чтобы смотреть на примеры других людей. Я, например, так и делаю.
Несите знания в команду. Говорите, что знаете Grid, предлагайте его использовать.
Подойдите к дизайнеру и скажите: «Давай ты будешь рисовать интереснее, а я буду твои задумки реализовывать!»
Скажите менеджеру: «Мы теперь можем больше с Grid!»
Делитесь знаниями внутри команды и двигайте веб вперед. В конечном счете у нас простая цель — делать веб лучше и круче!
Если в какой-то момент у нас все уходило в упрощение, то сейчас есть новые технологии. Не только Grid — это SVG-маски, анимации, трансформации. Проблема не в технологиях, а в том, что большинство до сих пор не использует на полную и половины из них. Мы не знаем всего или не хотим использовать, а дизайнеры не догадываются, что мы можем.
Контакты Сергея Попова: e-mail, Fb, twitter
Это доклад — один из лучших на Frontend Conf. Понравилось, и хотите больше — подпишитесь на рассылку, в которой мы собираем новые материалы и даем доступ к видео, и приходите на Frontend Conf РИТ++ в мае.
Знаете больше и готовы делиться опытом — отлично! Присылайте тезисы, прием докладов уже открыт и будет продолжаться до 27 февраля.
Автор: glebmachine