Терминология — CSS: Вёрстка на Grid
В этом уроке отдельно хочется рассмотреть терминологию, связанную с Grid. Будучи основанной на сетках, она имеет множество различных понятий, знание которых будет необходимым в процессе изучения модуля.
Возможно вы уже сталкивались с понятием сетки. Зачастую это представляется неким магическим элементом, с помощью которого наша страница сразу становится удобной и красивой. Реальность, как и всегда, немного сложнее.
Понятие сетки пришло к нам с далёких времён, когда верстальщики занимались расположением контента в книге или газете. Возьмём для примера страницу Блога на сайте Хекслет. Она типична для газетной вёрстки и состоит из самостоятельных прямоугольных секций.
Эту страницу возможно разбить на некоторое количество рядов и колонок строго заданного размера. С помощью такой системы организации появляются ячейки, как в таблицах. Именно в них располагается весь контент: текст, картинки, блоки. Такой принцип называется модульными сетками. Сетки существуют во многих областях. Их применяют не только создатели газет и сайтов, но и архитекторы, дизайнеры разных направлений.
Сетки бывают совершенно разными: от простых квадратных сеток до очень сложных многослойных сеток, в структуре которых несколько сеток накладываются друг на друга. В области вёрстки часто применяются достаточно простые сетки на 12 или 24 колонки. Они достаточно универсальны для того, чтобы сверстать почти любой макет. Например, в одной из самых известных CSS библиотек Bootstrap используется система из 12 колонок. Вся организация контента построена именно на ней. В том числе сайт Hexlet, на котором вы сейчас находитесь.
Страница блога также построена по простой схеме 12 колоночной сетки. Она разделена на 12 одинаковых колонок с равными отступами между ними. Обратите внимание на то, как выстроен контент. Вы увидите, что каждый элемент подчиняется этой сетке, хоть вначале это могло казаться не так.
Обратите внимание на то, как левая и правая часть контента в блоге отделена с помощью отступа. Такой же размер отступа используется на протяжении всей сетки. Сами прямоугольные области с контентом могут занимать несколько колонок сразу. Это и позволяет создавать блоки различной ширины, при этом оставаясь в рамках сетки.
Зачастую таких сеток достаточно, чтобы выстроить контент на странице. Но иногда разработчики создают сетки внутри других элементов. Например блок со статьёй можно было бы тоже разметить и расположить контент по уже её внутренней сетке. Хоть и рабочий вариант, но старайтесь не перегружать свою страницу различными сетками. В первую очередь сетки позволяют нам создать шаблон сайта, а не работать с контентом где-то внутри шаблона.
Если вы когда-нибудь верстали таблицы с помощью HTML, то можете заметить, что принципы работы таблиц и сеток похожи. Так как по сути таблицы — это и есть сетка.
Обобщая всё сказанное в этом уроке, можно заключить, что сетки — это некая структура, направляющие, с помощью которых мы располагаем контент на странице как по горизонтали, так и по вертикали.
Чем же так полезны сетки? Ведь до этого мы прекрасно обходились и без них, да и некоторые из вас уже могли верстать целые сайты без их использования. У сеток есть ряд преимуществ:
Сетки предсказуемы. Мы заранее знаем с чем работаем, и как расположится наш контент. Сколько места он займёт относительно других блоков. В этом случае ширина измеряется количеством модулей сетки, а не значениями в пикселях.
Сетки отлично подходят для адаптивности. Это главное преимущество сеток. С ними очень просто создавать адаптивный дизайн для страниц.
Обратите внимание, что сейчас речь шла о сетках в общем, а не о Grid. Сетку возможно создать, совершенно не используя CSS Grid Layout. Например в Bootstrap когда-то использовался float. На текущий момент используется Flex. И там, и там получаются рабочие сетки. Но с приходом новой технологии процесс создания сеток значительно упростился, что положительно сказывается на скорости разработки.
В CSS Grid Layout есть несколько основных понятий, которые необходимо знать перед тем, как использовать модуль в реальной работе. Это поможет лучше понимать, как свойства влияют на нашу сетку. Пока все примеры будут показаны на абстрактном блоке. Разделим этот блок на 4 колонки и посмотрим, из чего он состоит:
Все колонки расположены внутри определённой области, которая ограничивает сетку со всех четырёх сторон. Весь этот прямоугольник, как вы могли догадаться, называется Grid-контейнером. Как и у Flex, сетка также создаётся внутри определённого блока.
Как вы видите, всю нашу структуру мы можем мысленно поделить на части, используя вертикальные и горизонтальные линии. Такие линии хоть и не видны на макете, но на самом деле Grid умеет с ними работать. Их можно нумеровать и даже давать имена. В дальнейших уроках мы разберём это подробнее. Эти линии называются Grid-линии или Линия Сетки.
После того, как мы разметили линии сетки, появились пересечения. Как у таблиц. В модуле они называются точно так же. Если какая-то область ограничена соседними вертикальными линиями, то это колонка, если горизонтальными, то это ряд. Также такие области ещё называют Полосой сетки или Трек сетки (Grid Tracks). Пересечение колонки и ряда станет ячейкой сетки.
Если взять несколько ячеек, то мы получим Grid область. При этом неважно, каким образом мы возьмём эти ячейки. Они могут быть из одного ряда или колонки, главное, что они должны быть ограничены едиными линиями сетки со всех четырёх сторон.
В процессе изучения курса мы вернёмся ко всем этим понятиям и тем, как с ними работать. Не пугайтесь, что сейчас этих понятий может быть достаточно много. В процессе изучения вы быстро научитесь определять область, с которой сейчас работаете.
Введение в CSS3 Grid Layout. Работаем с сетками
Update: Часть сведений в данной статье устарели. Рекомендую свежие материалы на css-live.ru.
Введение
Модуль CSS3 Grid Layout — это один из самых интересных, на мой взгляд, модулей в семействе CSS3. Официальная история модуля в виде черновика спецификации насчитывает сегодня чуть менее года. О предварительном анонсе еще с названием CSS Grid Alignment на TPAC 2010 Владимир Юнев писал еще в декабре 2010. Надо также отметить, что с чуть другим названием и несколько отличным синтаксисом, но с той же сутью, он был заявлен в качестве WD еще в 2007г. Сегодня работы по доводке модуля идут полным ходом, предварительная реализация уже есть в Internet Explorer 10 и есть надежда, что поддержка новых возможностей также появится в будущих версиях других популярных браузеров.
Зачем нужен Grid Layout?
Задача, которую решает модель CSS3 Grid Layout, очень проста и понятна любому веб-верстальщику (да и не только ему): предоставить удобный механизм расположения контента по виртуальной сетке.
В отличие от старых табличных подходов, основанных на использовании table, здесь не замусоривается семантика документа и представление четко отделено от содержания. В отличие от различных вариаций блочной верстки со становящимися при сколь-нибудь сложной структуре безумными и многоэтажными float’ами в сочетании с вручную просчитанными отступами, здесь описание стилей становится тривиально простым и прозрачным. В отличии от абсолютного позиционирования с привязкой к координатам, здесь сохраняется гибкость. В отличие от популярных сегодня css/js-библиотек для разметки по сетке путем указания соответствующих классов (взять хоть те же bootstrap или yui css grids), здесь не замусоривается привязка классов.
Сплошное удовольствие! Осталось только дождаться широкой поддержки 🙂 Впрочем, если вы планируете делать приложения в стиле Metro для Windows 8 на html/js, ключевые возможности, описываемые в модуле CSS3 Grid Layout, уже работают — и можно двигаться вперед, используя удобные и практичные механизмы.
Основы
Чтобы быстрее разобраться с тем, как работает Grid Layout, давайте сразу же начнем с примера. Представьте себе, что вам нужно решить классическую задачу верстки трехколоночного макета с примерно таким содержимым:
которое необходимо разнести на три колонки примерно вот так:
Это классическая задача, поэтому я не буду останавливаться на том, как она решается в случае использования уже традиционных подходов для многоколоночной блочной верстки. Давайте посмотрим, что можно сделать с помощью Grid Layout (я пропускаю браузерные префиксы в примерах, однако, на практике их нужно добавлять — для IE это -ms-).
Вот пример кода на CSS:
В самом простом варианте все, что нужно сделать, сводится к тому, чтобы указать в контейнере (section), что содержимое внутри него нужно располагать по сетке и задать виртуальную сетку, используя свойства grid-columns и grid-rows (чуть ниже я расскажу о том, какие значения они принимают). Далее для каждого элемента внутри достаточно сказать, где он должен располагаться.
И это все! Итого:
- Виртуальная сетка: grid-columns и grid-rows в контейнере
- Размещение элемента: grid-column и grid-row.
Теперь давайте разбираться в деталях и дополнительных возможностях.
Виртуальная сетка
Треки: строки и столбцы
Для создания виртуальной сетки, по которой в дальнейшем размешаются элементы, необходимо описать треки сетки (Grid Tracks) — строки и столбцы внутри сетки:
Линии сетки
Треки располагаются между линиями сетки (Grid Lines), которые, в свою очередь, находятся справа-слева и сверху-снизу от каждого трека:
Чтобы задать, как именно элемент будет размещен по сетке, необходимо указать, к какой линии по вертикали и горизонтали он будет привязан:
По умолчанию, элемент занимает пространство от указанной линии до следующей (поэтому такая нумерация совпадает с нумерацией ячеек и все выглядит так, как будто мы говорим, в какую ячейку разместить элемент).
Растяжение на несколько ячеек
Чтобы растянуть элемент на несколько ячеек сетки, можно использовать свойства grid-row-span и grid-column-span:
По умолчанию, оба свойства установлены в значение 1, что соответствует растяжению доступного пространства от указанной линии до следующей (+1).
Повторяющиеся треки
Часто бывает так, что предполагаемая для использования сетка содержит какой-то характерный шаблон:
Было бы удобным описывать такие сетки в более компактном и прозрачном виде — и такая возможность есть! Пример выше можно описать так:
Сам шаблон описывается в круглых скобках, после чего в квадратных указывается количество повторений.
Теперь, когда мы знаем базовые возможности для описания линий сетки, давайте снова вернемся к трекам и попробуем разобраться с используемыми единицами измерения.
Единицы измерения
Как вы уже могли заметить выше, местами я использовал необычное значение при указании размеров некоторых столбцов и строчек — 1fr. Об этом и других возможных значениях при указании длины мы сейчас и поговорим.
- линейные размеры — стандартные единицы указания длины, определенные в модуле CSS3 Values and Units, например, pt, px, em, vw и т. д.;
- проценты — размер трека в процентах от размеров контейнера с сеткой (хотя если высота или длина сетки зависит от контента, результат будет неопределенным);
- доли (fraction) — неотрицательное число с последующей единицей измерения fr, размер каждой доли берется пропорциональным указанному числу (см. подробнее ниже);
- max-content — ключевое слово для указания максимальной длины из максимальных длин элементов в треке;
- min-content — ключевое слово для указания максимальной длины из минимальных длин элементов в треке;
- minmax(min, max) — задает диапазон значений (принцип работы можно описать как minmax(p, q) = max(p, min(fill-available, q))
— максимум из нижнего порога и минимума доступного пространства и верхнего порога); - auto — ключевое слово, эквивалентное minmax(min-content, max-content).
Давайте попробуем разобраться, как работают доли (fraction value)? Сетка занимает некоторое пространство по ширине и высоте. Оно может зависеть от контента, быть жестко фиксированным или занимать все доступное пространство во внешнем контейнере. Далее, при описании треков части колонок и строк вы можете явно задать, какого размера они должны быть, для еще какой-то части вы можете указать, что их длина зависит от контента.
Теперь, если из доступной длины, отведенной под сетку по вертикали или горизонтали, вычесть сумму всех таких явных или «контентных» длин, оставшееся пространство распределяется между остальными треками пропорционально указанным в них долях (размер доли, деленный на сумму всех таких долей):
На примере выше это три столбца c ширинами в соотношении 2:1:1 и две строки с высотами в соотношении 5:2.
Пример
В черновике спецификации приводится такой комплексный пример, позволяющий увидеть всю эту схему с разными типами значений сразу:
- Стартовая первая линия.
- Линия в 100px от первой.
- Еще одна линия на расстоянии 1/2 оставшегося после всех рассчетов пространства — от второй линии.
- И еще одна линия, чье расстояние от третьей равно максимальному из размеров контента элементов в колонке.
- Наконец, последняя линия, расположенная от четвертой на расстоянии, равном либо минимальной длине элементов в колонке, либо 1/2 оставшегося пространства, смотря, что больше.
Тут есть еще небольшой нюанс относительно учета долей, которые оказались внутри функции minmax: они учитываются в общей сумме долей только если обозначены в максимальной позиции. Доли, обозначенные в минимальной позиции, считаются равными 0px. Подробнее тонкости рассчета смотрите в спецификации.
===
Следующим шагом мы попробуем разобраться, как элементы размещаются между линиями сетки (внутри ячеек).
Привязка элементов
Теперь, когда элементы «привязаны» к линиям сетки, возникает естественный вопрос: а как же они располагаются между линиями?
- start
- end
- center
- stretch
Привязка в колонках (по горизонтали) соответствует направлению текста (например, в арабском языке start будет справа, а end слева). Привязка в строках (по вертикали) совпадает с направлением потока блоков (это, кстати, означает, что в некоторых восточно-азиатских языках строки и столбцы могут поменяться местами).
Управление слоями
Следующий важный момент: расположение элементов внутри сетки с наложениями. Что происходит, если, к примеру, два элемента привязаны к одним и тем же линиям, либо накладываются при расширении на несколько ячеек?
Прежде всего, важно понять следующий нюанс: элементы, размещаемые внутри сетки, не влияют напрямую на расположение друг друга. Если вы десять элементов привяжете, скажем, ко второй линии по горизонтали и третьей по вертикали, то по умолчанию они все расположатся один на другим так, как будто каждый из них привязан к соответствующему углу. Элементы могут влиять только на размеры треков, если они завязаны, в свою очередь, на размеры контента.
Чтобы управлять порядком отображения таких слоев, текущая версия спецификации расширяет возможности z-index, позволяя управлять слоями элементов внутри сетки.
Замечание: в предыдущей версии спецификации, на которую опирается текущая версия IE10 (platform preview 5), для этих целей было определено отдельное свойство grid-layer, чтобы не конфликтовать с z-index, однако, далее в процессе обсуждений в рабочей группе это решение было пересмотрено.
css3 grid library
- display: grid
- grid-columns & grid-rows
- grid-column & grid row
- grid-column-span & grid-row-span
Немного о будущем, или какие еще возможности описаны в модуле
Наконец, давайте немного приоткроем двери в будущее и подглядим, какие еще возможности готовятся в модуле CSS3 Grid Layout.
Учтите, что на сегодня упоминаемые ниже возможности только описаны в черновике спецификации, но еще не имеют поддержки среди выпущенных браузеров (включая предварительные версии). Они также могут измениться в будущем в зависимости от реакции сообщества и рекомендаций рабочей группы CSS.
Указание конечной линии для привязки элемента
Опционально для привязки элемента к сетке можно указать не только начальную, но и конечную линию.
В отличие от механизма «span», который говорит, на сколько ячеек элемент должен растянуться по горизонтали или вертикали, данная возможность позволяет четко указать, на какой линии элемент должен закончиться. Это также удобно использовать в сочетании с возможностью именования отдельных линий сетки.
Именованные линии сетки
Для удобства линиям можно давать названия. Это делается вставкой в соответствующих местах строковых значений при описании треков (можно давать несколько имен, если это имеет практический смысл, например, с точки зрения семантики разметки):
Далее при описании привязки элементов можно ссылаться на эти имена:
Также спецификация вводит 4 заранее именованных линии — вертикальные и горизонтальные start и end, фактически, обрамляющие всю сетку. Это полволяет, к примеру, расположить элемент «от второго столбца и до последнего», не задумываясь об общем количестве столбцов.
Именованные ячейки и шаблоны
Еще один способ размещения элементов по сетке заключается в использовании шаблонов, позволяющих описать виртуальную структуру блоков:
При этом для размещения элемента с прявязкой к той или иной виртуальной ячейке достаточно сослаться на нее соответствующим правилом:
Такой подход оказывается особенно удобным, если в зависимости от различных условий, например, разрешения экрана, вам нужно менять расположение элементов и даже переделать саму сетку. В подобной ситуации Grid Layout хорошо сочетается с Media Queries:
Обратите внимание, что привязка самой статьи к именованной ячейке при этом не меняется. (Ручки уже чешутся начать использовать, однако, ждем, когда это все реализуют в браузерах.)
Заключение
Я постарался дать в статье обзор ключевых возможностей модуля CSS3 Grid Layout. Надеюсь, они вдохновляют вас не менее, чем меня. 🙂
Напомню, что модуль продолжает развиваться, редакторы собирают отзывы от внешнего сообщества и внутри рабочей группы CSS. На действующую реализацию основного функционала можно посмотреть в Internet Explorer 10. Несколько интересных примеров можно найти на ietestdrive.com: The Grid System и Hands On: CSS3 Grid Layout:
Также еще раз отмечу, что возможности Grid Layout, уже поддерживаемые движком IE10, также можно использовать при разработке приложений в стиле Metro на HTML/JS для Windows 8.
Разница между явными и неявными гридами
Grid Layout наконец-то дает нам возможность определять сетки в CSS и размещать элементы в ячейках сетки. Само по себе это здорово, но тот факт, что нам не нужно указывать каждую дорожку и нам не нужно размещать каждый элемент вручную, делает новый модуль еще лучше. Сетки достаточно гибкие, чтобы адаптироваться к своим элементам.
Все это обрабатывается так называемой явной и неявной сеткой.
Явные сетки
Мы можем определить фиксированное количество строк и дорожек, которые образуют сетку, используя свойства grid-template-rows , grid-template-columns и grid-template-areas . Эта определенная вручную сетка называется явной сеткой.
Повторение треков
Когда мы определяем grid-template-columns: 1fr 1fr 1fr 1fr; , мы получаем четыре вертикальных трека, каждая шириной 1fr . Мы можем автоматизировать это, используя такие обозначения grid-template-columns: repeat(4, 1fr); . Первый аргумент указывает количество повторов, второй — список треков, который повторяется это количество раз.
Трек — лист? Да, вы действительно можете повторять несколько треков.
Автоматический повтор треков
Обозначение повторения весьма полезно, но его можно автоматизировать еще больше. Вместо того чтобы устанавливать фиксированное число повторений мы можем использовать ключевые слова auto-fill и auto-fit .
Автозаполнение треков
Ключевое слово auto-fill создает так много треков , как вписываться в контейнер сетки, не вызывая его переполнение.
Обратите внимание, что repeat(auto-fill, 1fr); будет создана только одна дорожка, потому что одна дорожка с шириной 1fr , уже заполняющей весь контейнер сетки, является недопустимым объявлением (может быть, оно изменилось? Я не знаю).
Автоматическая подгонка треков
Ключевое слово auto-fit ведет себя так же, как auto-fill , за исключением того, что после размещения элемента сетки будет создавать только количество дорожек, которые необходимы.
В примере, используемом в этом разделе, сетка будет выглядеть одинаково с repeat(auto-fit, 100px); и repeat(4, 100px); . Разница видна, когда элементов сетки больше 4.
Если элементов больше, auto-fit создает больше столбцов.
С другой стороны, если в нотации повторения используется фиксированное количество вертикальных дорожек и количество элементов превышает это значение, добавляются дополнительные строки.
Я использовал grid-template-columns в приведенных выше примерах для удобства, но все правила применимы и к grid-template-rows .
Неявные сетки
Если элементов сетки больше, чем ячеек в сетке, или когда элемент сетки размещается за пределами явной сетки, контейнер сетки автоматически создает дорожки сетки, добавляя линии сетки в сетку. Явная сетка вместе с этими дополнительными неявными дорожками и линиями образует так называемую неявную сетку.
Ширина и высота неявных дорожек устанавливаются автоматически. Они достаточно велики, чтобы соответствовать размещенным элементам сетки, но это поведение по умолчанию можно изменить.
Определение размера неявных дорожек
Свойства grid-auto-rows и grid-auto-columns дают нам контроль над размером неявных дорожек.
Неявные дорожки теперь всегда будут иметь ширину 200px и высоту 60px , независимо от того, подходит ли элемент сетки или нет.
Вы можете сделать размер неявных дорожек более гибким, указав диапазон с помощью нотации minmax() .
Неявные дорожки теперь имеют ширину не менее 200 пикселей и высоту 60 пикселей, но будут расширяться, если этого требует контент.
Расширение сетки до начала
Неявные треки нельзя просто добавить в конец явной сетки. Также может случиться так, что явную сетку нужно расширить до начала.
Каждый элемент заканчивается на второй строке и занимает 2 ячейки (одну по вертикали, другую по горизонтали). Поскольку перед второй линией находится только одна ячейка, в сетку в начале каждой стороны добавляется еще одна неявная дорожка.
Автоматическое размещение
Как уже упоминалось, неявные треки также добавляются, если количество элементов превышает количество ячеек. По умолчанию алгоритм автоматического размещения размещает элементы, последовательно заполняя каждую строку, добавляя новые строки по мере необходимости. Мы можем указать, как автоматически размещенные элементы перетекают в сетку, используя свойство grid-auto-flow .
Вместо строк столбцы заполняются элементами и создаются дополнительные неявные столбцы.
Не определять явную сетку
В связи с тем, что можно автоматически определять размер ячеек с помощью, grid-auto-rows и grid-auto-columns не обязательно определять явную сетку.
Если полагаться исключительно на неявную сетку, то в сочетании с явным размещением может возникнуть путаница и трудность для понимания. В этом примере первый элемент размещается auto и занимает 2 строки, второй элемент размещается явно в первом столбце и занимает 2 столбца, образуя вторую вертикальную дорожку. Третий и четвертый элементы фактически будут автоматически помещены в четвертую строку, но пятый элемент будет явно помещен в ранее несуществующий третий столбец. Это создает третью вертикальную дорожку, и из-за автоматического размещения сетки третий элемент перемещается на строку вверх, заполняя пространство.
Заключение
Эта статья не охватывает всего, что нужно знать о явной и неявной сетке, но она должна дать вам больше, чем твердое понимание концепции. Знание того, почему и как создаются неявные линии и треки, жизненно важно для работы с Grid Layout.