Html grid


Перевод статьи Getting to know CSS Grid Layout с сайта cm.engineering для CSS-live.ru, автор — Крис Райт

ciu-grid

Фотографии из  Unsplash

CSS Grid — важнейшее событие для веб-раскладки, что случалось в браузерах со времен флексбоксов. Он позволяет избежать всяких магических чисел, хаков и обходных путей, к которым мы привыкли за последние 15 лет. С ним стало намного проще описывать раскладки, что здорово урежет нишу большинства ведущих CSS-фреймворков и позволит писать меньше стилей.

Если не знакомы с CSS Grid и дочитали аж досюда, то это инструмент для раскладки, применяемый к контейнеру, который затем управляет размещением, размерами и выравниванием дочерних элементов.

CSS Grid предоставляет новые мощные возможности — с ними раскладка учитывает горизонтальное и вертикальное пространство одновременно, можно смело изменять раскладку, не затрагивая разметку, и не нужно медиазапросов, чтобы адаптироваться к свободному пространству.

Необходимый минимум


Поначалу может показаться, что для понимания Grid нужно изучить весь его новый обширный синтаксис, но чтобы сделать первые шаги в гридах, достаточно знать лишь часть. В примерах из этой статьи содержатся различные идеи, которые важны для начального понимания CSS Grid.

Браузерная совместимость

CSS-гриды уже есть в Safari 10.1, Firefox 52, Opera 44 и Chrome 57.

Есть более старая реализация устаревшей спецификации со своими ограничениями, которая доступна в браузерах Microsoft, но мы лишь кратко её коснёмся, чтобы понять некоторые различия между новыми и старыми реализациями, и как обойти их.

Для большинства раскладок нам пригодится следующая проверка возможности, чтобы старые браузеры по-прежнему поддерживали ту раскладку, которую они понимают:

@supports (display: grid) {   .grid {   display: grid;   }  }  

Браузеры, не поддерживающие @supports или гриды, не получат эту фичу.

Чтобы запускать примеры из статьи, вам потребуются браузеры с поддержкой Grid.

Создание двухколоночного грида с интервалами

Чтобы увидеть, как CSS Grid определяет колонки, возьмём эту раскладку:

ciu-grid

Двухколоночная раскладка с интервалами с использованием grid-template-columns


и grid-gap

Этот грид можно создать с помощью grid-template-columns и grid-gap.

Grid-template-columns отвечает за то, как выкладываются колонки грида, оно принимает ряд значений через пробел, определяющих размер каждой колонки; сколько значений указано, столько и будет колонок.

Например, четырёхколоночный грид из колонок шириной по 250px можно описать так:

grid-template-columns: 250px 250px 250px 250px;  

Ту же самую раскладку можно выразить с помощью удобного ключевого слова repeat.

grid-template-columns: repeat(4, 250px);  

Определение интервалов

Grid-gap указывает размер интервалов в грид-раскладке, оно может принимать одно или два значения, при указании двух значений вы определяете размеры интервалов и для рядов, и для колонок.

В нашем примере раскладки, разбитой на две колонки можно объявить наш грид так:

.grid {   display: grid;   grid-template-columns: 50vw 50vw;   grid-gap: 1rem;  }  

К сожалению, интервал добавится к общей ширине контейнера, которая будет рассчитываться как 100vw + 1rem, и раскладка в итоге будет с горизонтальным скроллбаром.

ciu-grid

Горизонтальный скроллбар от использования грид-интервала с единицами измерения относительно вьюпорта

Для исправления этого переполнения места нужно немного другое решение. Вводим единицу доли (FR, от англ. fraction).

Единица fr

Единица fr занимает долю доступного места; если бы доступное место составляло 900px, и при этом первому элементу досталась бы одна доля, а второму — две, то первый получил бы 1/3, а второй – 2/3 от этих 900px.

Переделаем наш новый код, заменив единицы вьюпорта на доли:

.grid {   display: grid;   grid-template-columns: 1fr 1fr;   grid-gap: 1rem;  }  

Выравнивание контента

Для выравнивания контента в нашем примере мы объявляем грид в дочерних элементах и размещаем их на соответствующих полосах с помощью свойств для выравнивания; полоса – это просто собирательное название для грид-колонок и рядов. У гридов, как и у флексбоксов, есть ряд свойств выравнивания – четыре значения – start, center, end и stretch, которые указывают дочерним элементам, где им находиться на отведённой для них полосе. Stretch, в отличие от других, растянет элемент от начала и до конца его полосы.

ciu-grid

align-items


и justify-content

В нашем примере, чтобы пригнать контент к центру по вертикали и горизонтали, можно применить эти свойства к контейнеру:

.center-content {   display: grid;   align-items: center;   justify-content: center;  }  

демо двух колонок

Воссоздание двухколоночной раскладки с помощью старых гридов.

Чтобы воспроизвести эту раскладку с помощью старого грида, придётся учитывать много ограничений в реализации. Мало того, что в старом гриде нет grid-gap, так ещё и в каждом грид-элементе нужно объявить, где это будет начинаться, иначе по умолчанию он будет 1, что заставит все дочерние элементы складываться друг под дружку в первой колонке.

В версии для старых гридов придется добавить интервал как отдельную полосу, чтобы обойти проблему отсутствия отдельного свойства для интервалов, а также уметь назначать начальную позицию каждого элемента.

.grid-legacy {   display: -ms-grid;   -ms-grid-columns: 1fr 1rem 1fr; // gap replacement  }  .grid-legacy:first-child {   -ms-grid-column: 1;  }  .grid-legacy:last-child {   -ms-grid-column: 3;  }  

Подход к выравниванию и растягиваиние старого грида на всю высоту

У старого грида есть та же проблема, что у флекбоксов в IE11: установка контейнеру min-height


не всегда будет учтена. В гридах обойти эту проблему гораздо легче.

Для этого можно использовать функцию minmax для ряда родительского контейнера, minmax указывает диапазон наибольших и наименьших значений, которые могут быть у ряда или колонки.

-ms-grid-rows: minmax(100vh, 1fr);  

В самих дочерних элементах можно создать грид из единственной колонки и единственного ряда по 1fr.

.ms-cell {   -ms-grid-columns: 1fr;   -ms-grid-rows: 1fr;  }    

Наконец, поскольку нет возможности выравнивать с помощью родителя как во Flexbox или современном Grid, для этого придётся использовать сами элементы.

.ms-align-center {   -ms-grid-column: 1;   -ms-grid-column-align: center; // как align-self в современном гриде   -ms-grid-row-align: center; // как justify-self в современном гриде  }    

Демо двух колонок на старых гридах

Если хотите посодействовать тому, чтобы Microsoft обновил Grid в MS Edge, посетите их страницу на сайте «статус платформы», посвященную обновлению CSS Grid и проголосуйте за неё, чтобы как можно больше повысить ее приоритет.

Итак, мы уже знаем, как создавать колонки, интервалы, как выравнивать содержимое и как можно добиться поддержки старой версии гридов. Давайте поэкспериментируем, как создать с помощью гридов негативное пространство.

Создание негативного пространства с помощью CSS Grid

Одна возможность, которую дают вам гриды – объявить то, где начинаются колонки в грид-элементе с помощью свойства grid-column-start


, что позволяет создать негативное пространство внутри грида.

ciu-grid

Негативное пространство с использованием grid-template-columns и grid-column-start

Один из способов создать негативное пространство — задать грид-элементу номер колонки больше его собственного порядкового номера, оставив изначально предназначенное ему место пустым и сдвинув элемент по горизонтали в новую колонку.

ciu-grid

Перемещение первого элемента с помощью grid-column-start

В примере выше с негативным пространством, разметка состоит из div-а, обёрнутого в другой div.

<div class="grid">   <div class="child"><!-- содержимое --></div>  </div>  

Грид представлен так:

.grid {   display: grid;   grid-template-columns: 1fr 1fr;  }  

Чтобы заставить дочерний элемент начинаться в правой колонке, мы говорим ему начинаться в колонке 2.

.child {   grid-column-start: 2;  }  

Примечание: несоответствие в Firefox 52 приводит к некоторым проблемам с вертикальным выравниванием, где единица FR для высоты рядов не растягивается на всю высоту окна браузера, и для решения этой проблемы мы делаем дочерние элементы грид-элементами, и добавляем единственный ряд нужной нам высоты.


.l-grid--full-height {   grid-template-rows: minmax(100vh, 1fr);  }  

Демо создания негативного пространства

Создание «мёртвых зон» для контента

Если грид-элементу, который естественным порядком попал бы в третью колонку (поскольку вторая колонка перед ним занята), явно объявить grid-column-start:2;, то алгоритм постарается найти следующую свободную ячейку во второй колонке на следующих рядах.

ciu-grid

Мертвая зона для контента создана при помощи grid-template-columns и grid-column-start

Грид-полоса будет пропускать колонки, пока не найдёт следующую пустую вторую колонку. Это даёт возможность создать «мёртвую зону» внутри грида, где не будет назначено никаких грид-полос с контентом.

Демо «мёртвой зоны» для контента

Создание рядов

Что, если вы захотите разбить макет на четыре части? Всё, что мы рассмотрели до сих пор про колонки, применимо и к рядам.

.grid {   display: grid;   grid-template-columns: 1fr 1fr;   grid-template-rows: 250px 250px;  }  

ciu-grid

Создание грид-раскладки при помощи grid-template-columns


и grid-template-rows

Проблема в этом примере — это идеальный сценарий. Контент каждого грид-элемента достаточно мал, чтобы никогда не превысить указанный размер ряда. Когда дело касается рядов, контент меняет всё. Вот вам пример того, что случается, когда ваш контент переполнит указанный размер ряда:

ciu-grid

Контент переполняет указанные размеры ряда

Мы создали два ряда по 250px, если контент внутри ряда переполнит его, он прорвется через границу своего ряда и начнёт перекрывать контент ряда под ним. Не совсем желаемый результат.

Установка минимальных размеров с сохранением гибкости

В этом сценарии нам нужна возможность установить минимальный размер, но чтобы он мог подстраиваться по контенту, этого можно добиться с помощью ключевого слова minmax, которое мы использовали в примере с устаревшим синтаксисом.

.grid {   grid-template-rows: minmax(250px, auto) minmax(250px, auto);  }  

Теперь, после знакомства с основами, нужно создать ряды с контентом, можно начать выстраивать более сложные гриды, горизонтальные и вертикальные.

Демо создания гибких рядов с помощью минимальных размеров

ciu-grid

Использование


grid-column-start и ключевого слова span для создания сложных гридов. Фото из Unsplash

Создание более сложных гридов

Мы можем перейти к созданию более сложных гридов, заставляя грид-элементы занимать несколько полос в гриде. В колонке этого можно добиться с помощью grid-column-start и grid-column-end, или выразить это в этой сокращённой записи:

grid-column: 1 / 3;  

Недостаток этого подхода в его слабой модульности, из-за чего может понадобиться очень много кода для позиционирования частей контента.

Ключевое слово span более модульное, поскольку его можно разместить в любом месте и позволить гриду его обрабатывать. Это позволит растянуть элемент на несколько полос, отсчитывая их от фактического положения его начала.

.span-column-3 {   grid-column-start: span 3;  }  

Где бы мы ни разместили этот класс в гриде, он заставит этот элемент растянуться на три полосы от его текущего положения.

Демо сложных гридов при помощи span

Планирование раскладки с помощью span


Можно планировать раскладки множественных полос, разбивая раскладку до наименьшей единицы в раскладке грида. В этом примере наименьшая единица выделена:

ciu-grid

Наименьший грид-элемент используется для грид-колонок, поэтому можно выстраивать более крупные элементы с помощью span

Выстраивая всё вокруг наименьшей единицы, можно гибко применять классы со span для создания интересных раскладок, а поскольку значения span суммируются, можно объединять ячейки и по рядам, и по колонкам, для создания в гриде иерархии.

Гибкие гриды без медиавыражений

Хотя некоторые из предыдущих примеров могли реагировать на изменения доступного пространства, ни один из них не предназначался специально для этих целей. У грида есть две крайне мощные фичи для управления свободным местом. Эти фичи называются ‘auto-fit’ и ‘auto-fill’, и используются внутри функции repeat, обычно с функцией minmax, как здесь:

grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));  

Они заменяют собой числа в repeat, и вычисляют максимально возможное число колонок в контейнере. Основное различие между ними – это то, как они справляются с лишним пространством в строке.

Auto-fill пытается поместить наибольшее количество повторяющихся элементов в колонку, сколько их может уместиться без переполнения. Когда места для добавления другого элемента не хватает, следующий элемент будет размещён на следующей строке, а это место, которое он не смог заполнить, останется пустым.

ciu-grid

Пример: После auto-fill могут оставаться пустые места, тогда как auto-fit будет схлопывать пустые места до 0px.

Auto-fit ведёт себя почти как auto-fill, за исключением того, что любая пустая область будет схлопываться и растягивать элементы в этой строке – напоминая поведение флексбоксов, когда по мере уменьшения доступного пространства колонки схлопываются.

ciu-grid

Пример с grid-auto-fit

Раскладка, основанная на медиавыражениях, привязана к области просмотра, это не подходит для изолированных модулей – компоненты должны адаптироваться к тому пространству, которое им доступно. Поэтому как это будет выглядеть на практике?

ciu-grid

Практический пример grid auto-fit

Демо с Grid Auto-fit

Это только цветочки

Мы пережили почти пятнадцать лет безраздельного господства флоатов в раскладках, успели изучить их до мелочей, a CSS Grid — еще совсем новичок, и еще так много предстоит экспериментировать и изучать.

Самый важный шаг на сегодня – просто использовать Grid по максимуму, знакомясь с ним и создавая более продвинутые раскладки. Grid – это практически терра инкогнита веба, и как только мы лучше познаем его возможности и начнём сочетать его с другими фичами, мы сможем создавать более интересные и гибкие раскладки без лишних стилей, и сможем забыть про отдельные фреймворки.

Если стало интересно и появилось желание продолжить знакомство с CSS Grid, поиграйтесь с GridByExample Рэйчел Эндрю, где исследуется каждый аспект CSS Grid в демо-примерах с объяснениями.

css-live.ru

// синтаксис: align-items: normal | stretch | [ <overflow>? <position> ] | <baseline> justify-items: normal | stretch | <overflow>? [ <position> | left | right ] | <baseline> | legacy [ left | right | center ]  // <baseline> = [ first | last ]? baseline // <overflow> = unsafe | safe // <position> = center | start | end | self-start | self-end | flex-start | flex-end  // то что в [] или до ? — можно не указывать
  • left — для justify-items, не работает для align-items. Все элементы прижимаются к левому краю ячеек.
  • right — для justify-items, не работает для align-items. Все элементы прижимаются к правому краю ячеек.

  • flex-start — тоже что start для грид-сетки. Т.е. если элементы не являются детьми flex контейнера ведет себя как start.

  • flex-end — тоже что end для грид-сетки. Т.е. если элементы не являются детьми flex контейнера ведет себя как end.

  • baseline, first baseline, last baseline — выравнивает по линии текста (первой или последней). Обратная совместимость: для first baseline это start, для last baseline это end.

  • legacy — позволяет управлять тем, как будет наследоваться значение детьми.
    Если legacy указано без left, right, center, то значение просто наследуется у родителя или равно normal.
    Когда justify-self:auto ссылается на значение justify-items:, берется значение без слова legacy, например у legacy left будет взято left. Это нужно для правильного выравнивания тега <center> или элемента с атрибутом align.

Все варианты значений:

align-items:

// базовые значения align-items: normal; align-items: stretch;  // выравнивание позиции // align-items не может быть left или right align-items: center; align-items: start; align-items: end; align-items: flex-start; align-items: flex-end; align-items: self-start; align-items: self-end;  // выравнивание по линии текста align-items: baseline; align-items: first baseline; align-items: last baseline;  // когда элемент перекрывает контейнер align-items: safe center; align-items: unsafe center;  // глобально align-items: inherit; align-items: initial; align-items: unset;

justify-items:

// базовые значения justify-items: auto; justify-items: normal; justify-items: stretch;  // выравнивание позиции justify-items: center; justify-items: start; justify-items: end; justify-items: flex-start; justify-items: flex-end; justify-items: self-start; justify-items: self-end; justify-items: left; justify-items: right;  // выравнивание по линии текста justify-items: baseline; justify-items: first baseline; justify-items: last baseline;  // когда элемент перекрывает контейнер justify-items: safe center; justify-items: unsafe center;  // выравнивание с приоритетом заимствования значения у родителя justify-items: legacy right; justify-items: legacy left; justify-items: legacy center;  // глобально justify-items: inherit; justify-items: initial; justify-items: unset;

place-items:

// базовые значения place-items: auto center; place-items: normal start;  // выравнивание позиции place-items: center normal; place-items: start auto; place-items: end normal; place-items: self-start auto; place-items: self-end normal; place-items: flex-start auto; place-items: flex-end normal; place-items: left auto; place-items: right normal;  // выравнивание по линии текста place-items: baseline normal; place-items: first baseline auto; place-items: last baseline normal; place-items: stretch auto;  // глобально place-items: inherit; place-items: initial; place-items: unset;

wp-kama.ru

grid-template-columns
grid-template-rows

Defines the columns and rows of the grid with a space-separated list of values. The values represent the track size, and the space between them represents the grid line.

Values:

  • <track-size> — can be a length, a percentage, or a fraction of the free space in the grid (using the fr unit)
  • <line-name> — an arbitrary name of your choosing
.container {   grid-template-columns: <track-size> ... | <line-name> <track-size> ...;   grid-template-rows: <track-size> ... | <line-name> <track-size> ...;  }

Examples:

When you leave an empty space between the track values, the grid lines are automatically assigned positive and negative numbers:

  .container {   grid-template-columns: 40px 50px auto 50px 40px;   grid-template-rows: 25% 100px auto;  }

Html grid

But you can choose to explicitly name the lines. Note the bracket syntax for the line names:

.container {   grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end];   grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line];  }

Grid with user named lines

Note that a line can have more than one name. For example, here the second line will have two names: row1-end and row2-start:

  .container {   grid-template-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end];  }

If your definition contains repeating parts, you can use the repeat() notation to streamline things:

.container {   grid-template-columns: repeat(3, 20px [col-start]);  }

Which is equivalent to this:

.container {   grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start];  }

If multiple lines share the same name, they can be referenced by their line name and count.

.item {   grid-column-start: col-start 2;  }

The fr unit allows you to set the size of a track as a fraction of the free space of the grid container. For example, this will set each item to one third the width of the grid container:

.container {   grid-template-columns: 1fr 1fr 1fr;  }

The free space is calculated after any non-flexible items. In this example the total amount of free space available to the fr units doesn’t include the 50px:

.container {   grid-template-columns: 1fr 50px 1fr 1fr;  }

css-tricks.com

In the following example, there are three columns, each auto-sized to their contents. No rows are explicitly defined. The grid-auto-flow property is row which instructs the grid to search across its three columns starting with the first row, then the next, adding rows as needed until sufficient space is located to accommodate the position of any auto-placed grid item.

<style type="text/css"> form {  display: grid;  /* Define three columns, all content-sized,  and name the corresponding lines. */  grid-template-columns: [labels] auto [controls] auto [oversized] auto;  grid-auto-flow: row dense; } form > label {  /* Place all labels in the "labels" column and  automatically find the next available row. */  grid-column: labels;  grid-row: auto; } form > input, form > select {  /* Place all controls in the "controls" column and  automatically find the next available row. */  grid-column: controls;  grid-row: auto; }  #department-block {  /* Auto place this item in the "oversized" column  in the first row where an area that spans three rows  won’t overlap other explicitly placed items or areas  or any items automatically placed prior to this area. */  grid-column: oversized;  grid-row: span 3; }  /* Place all the buttons of the form  in the explicitly defined grid area. */ #buttons {  grid-row: auto;   /* Ensure the button area spans the entire grid element  in the row axis. */  grid-column: 1 / -1;  text-align: end; } </style> <form>  <label for="firstname">First name:</label>  <input type="text" id="firstname" name="firstname" />  <label for="lastname">Last name:</label>  <input type="text" id="lastname" name="lastname" />  <label for="address">Address:</label>  <input type="text" id="address" name="address" />  <label for="address2">Address 2:</label>  <input type="text" id="address2" name="address2" />  <label for="city">City:</label>  <input type="text" id="city" name="city" />  <label for="state">State:</label>  <select type="text" id="state" name="state">  <option value="WA">Washington</option>  </select>  <label for="zip">Zip:</label>  <input type="text" id="zip" name="zip" />   <div id="department-block">  <label for="department">Department:</label>  <select id="department" name="department" multiple>  <option value="finance">Finance</option>  <option value="humanresources">Human Resources</option>  <option value="marketing">Marketing</option>  </select>  </div>   <div id="buttons">  <button id="cancel">Cancel</button>  <button id="back">Back</button>  <button id="next">Next</button>  </div> </form> 

www.w3.org

What is a grid?

A grid is an intersecting set of horizontal and vertical lines – one set defining columns and the other rows. Elements can be placed onto the grid, respecting these column and row lines. CSS grid layout has the following features:

Fixed and flexible track sizes

You can create a grid with fixed track sizes – using pixels for example. This sets the grid to the specified pixel which fits to the layout you desire. You can also create a grid using flexible sizes with percentages or with the new fr unit designed for this purpose.

Item placement

You can place items into a precise location on the grid using line numbers, names or by targeting an area of the grid. Grid also contains an algorithm to control the placement of items not given an explicit position on the grid.

Creation of additional tracks to hold content

You can define an explicit grid with grid layout but the specification also deals with the content added outside of a declared grid, which adds additional rows and columns when needed. Features such as adding “as many columns that will fit into a container” are included.

Alignment control

Grid contains alignment features so that we can control how the items align once placed into a grid area, and how the entire grid is aligned. 

Control of overlapping content

More than one item can be placed into a grid cell or area, they can partially overlap each other. This layering may then be controlled with z-index property.

Grid is a powerful specification and when combined with other parts of CSS such as flexbox, can help you to create layouts that were previously impossible to build in CSS. It all starts by creating a grid in your grid container.

The Grid container

We create a grid container by declaring display: grid or display: inline-grid on an element. As soon as we do this all direct children of that element will become grid items.

In this example, I have a containing div with a class of wrapper, inside are five child elements.

<div class="wrapper">  <div>One</div>  <div>Two</div>  <div>Three</div>  <div>Four</div>  <div>Five</div> </div> 

I make the .wrapper a grid container.

.wrapper {  display: grid; } 

All the direct children are now grid items. In a web browser, you won’t see any difference to how these items are displayed before turning them into a grid, as grid has created a single column grid for the items. At this point, you may find it useful to work with the Grid Inspector, available as part of Firefox’s Developer Tools. If you view this example in Firefox and inspect the grid, you will see a small icon next to the value grid. Click this and then the grid on this element will be overlaid in the browser window.

Using the Grid Highlighter in DevTools to view a grid

As you learn and then work with the CSS Grid Layout this tool will give you a better idea of what is happening with your grids visually.

If we want to start making this more grid-like we need to add column tracks.

Grid Tracks

We define rows and columns on our grid with the grid-template-columns and grid-template-rows properties. These define grid tracks. A grid track is the space between any two lines on the grid. In the below image you can see a track highlighted – this is the first row track in our grid.

Html grid

I can add to our earlier example by adding the grid-template-columns property, then defining the size of the column tracks.

I have now created a grid with three 200-pixel-wide column tracks. The child items will be laid out on this grid one in each grid cell.

The fr Unit

Tracks can be defined using any length unit. Grid also introduces an additional length unit to help us create flexible grid tracks. The new fr unit represents a fraction of the available space in the grid container. The next grid definition would create three equal width tracks that grow and shrink according to the available space.

In this next example, we create a definition with a 2fr track then two 1fr tracks. The available space is split into four. Two parts are given to the first track and one part each to the next two tracks.

.wrapper {  display: grid;  grid-template-columns: 2fr 1fr 1fr; } 

In this final example, we mix absolute sized tracks with fraction units. The first track is 500 pixels, so the fixed width is taken away from the available space. The remaining space is divided into three and assigned in proportion to the two flexible tracks.

.wrapper {  display: grid;  grid-template-columns: 500px 1fr 2fr; } 

Track listings with repeat() notation

Large grids with many tracks can use the repeat() notation, to repeat all or a section of the track listing. For example the grid definition:

.wrapper {  display: grid;  grid-template-columns: 1fr 1fr 1fr; } 

Can also be written as:

.wrapper {  display: grid;  grid-template-columns: repeat(3, 1fr); } 

Repeat notation can be used for a part of the track listing. In this next example I have created a grid with an initial 20-pixel track, then a repeating section of 6 1fr tracks then a final 20-pixel track.

.wrapper {  display: grid;  grid-template-columns: 20px repeat(6, 1fr) 20px; } 

Repeat notation takes the track listing, and uses it to create a repeating pattern of tracks. In this next example, my grid will consist of 10 tracks, a 1fr track, and then followed by a 2fr track. This pattern will be repeated five times.

.wrapper {  display: grid;  grid-template-columns: repeat(5, 1fr 2fr); } 

The implicit and explicit grid

When creating our example grid we specifically defined our column tracks with the grid-template-columns property, but the grid also created rows on its own. These rows are part of the implicit grid. Whereas the explicit grid consists of any rows and columns defined with grid-template-columns or grid-template-rows.

If you place something outside of the defined grid—or due to the amount of content, more grid tracks are needed—then the grid creates rows and columns in the implicit grid. These tracks will be auto-sized by default, resulting in their size being based on the content that is inside them.

You can also define a set size for tracks created in the implicit grid with the grid-auto-rows and grid-auto-columns properties.

In the below example we use grid-auto-rows to ensure that tracks created in the implicit grid are 200 pixels tall.

<div class="wrapper">  <div>One</div>  <div>Two</div>  <div>Three</div>  <div>Four</div>  <div>Five</div> </div> 
.wrapper {  display: grid;  grid-template-columns: repeat(3, 1fr);  grid-auto-rows: 200px; } 

Track sizing and minmax()

When setting up an explicit grid or defining the sizing for automatically created rows or columns we may want to give tracks a minimum size, but also ensure they expand to fit any content that is added. For example, I may want my rows to never collapse smaller than 100 pixels, but if my content stretches to 300 pixels in height, then I would like the row to stretch to that height.

Grid has a solution for this with the minmax() function. In this next example I am using minmax() in the value of grid-auto-rows. This means automatically created rows will be a minimum of 100 pixels tall, and a maximum of auto. Using auto means that the size will look at the content size and will stretch to give space for the tallest item in a cell, in this row.

.wrapper {  display: grid;  grid-template-columns: repeat(3, 1fr);  grid-auto-rows: minmax(100px, auto); } 
<div class="wrapper">  <div>One</div>  <div>Two  <p>I have some more content in.</p>  <p>This makes me taller than 100 pixels.</p>  </div>  <div>Three</div>  <div>Four</div>  <div>Five</div> </div> 

Grid lines

It should be noted that when we define a grid we define the grid tracks, not the lines. Grid then gives us numbered lines to use when positioning items. In our three column, two row grid we have four column lines.

Diagram showing numbered grid lines.

Lines are numbered according to the writing mode of the document. In a left-to-right language, line 1 is on the left-hand side of the grid. In a right-to-left language, it is on the right-hand side of the grid. Lines can also be named, and we will look at how to do this in a later guide in this series.

Positioning items against lines

We will be exploring line based placement in full detail in a later article. The following example demonstrates doing this in a simple way. When placing an item, we target the line – rather than the track.

In the following example I am placing the first two items on our three column track grid, using the grid-column-start, grid-column-end, grid-row-start and grid-row-end properties. Working from left to right, the first item is placed against column line 1, and spans to column line 4, which in our case is the far-right line on the grid. It begins at row line 1 and ends at row line 3, therefore spanning two row tracks.

The second item starts on grid column line 1, and spans one track. This is the default so I do not need to specify the end line. It also spans two row tracks from row line 3 to row line 5. The other items will place themselves into empty spaces on the grid.

<div class="wrapper">  <div class="box1">One</div>  <div class="box2">Two</div>  <div class="box3">Three</div>  <div class="box4">Four</div>  <div class="box5">Five</div> </div> 
.wrapper {   display: grid;   grid-template-columns: repeat(3, 1fr);   grid-auto-rows: 100px;  }   .box1 {   grid-column-start: 1;   grid-column-end: 4;   grid-row-start: 1;   grid-row-end: 3;  }  .box2 {   grid-column-start: 1;   grid-row-start: 3;   grid-row-end: 5;  } 

Don’t forget that you can use the Grid Inspector in Firefox Developer Tools to see how the items are positioned against the lines of the grid.

Grid cells

A grid cell is the smallest unit on a grid. Conceptually it is like a table cell. As we saw in our earlier examples, once a grid is defined as a parent the child items will lay themselves out in one cell each of the defined grid. In the below image, I have highlighted the first cell of the grid.

The first cell of the grid highlighted

Grid areas

Items can span one or more cells both by row or by column, and this creates a grid area. Grid areas must be rectangular – it isn’t possible to create an L-shaped area for example. The highlighted grid area spans two row and two column tracks.

A grid area

Gutters

Gutters or alleys between grid cells can be created using the column-gap and row-gap properties, or the shorthand gap. In the below example, I am creating a 10-pixel gap between columns and a 1em gap between rows.

.wrapper {  display: grid;  grid-template-columns: repeat(3, 1fr);  column-gap: 10px;  row-gap: 1em; } 
<div class="wrapper">  <div>One</div>  <div>Two</div>  <div>Three</div>  <div>Four</div>  <div>Five</div> </div> 

Any space used by gaps will be accounted for before space is assigned to the flexible length fr tracks, and gaps act for sizing purposes like a regular grid track, however you cannot place anything into a gap. In terms of line-based positioning, the gap acts like a fat line.

Nesting grids

A grid item can become a grid container. In the following example, I have the three-column grid that I created earlier, with our two positioned items. In this case the first item has some sub-items. As these items are not direct children of the grid they do not participate in grid layout and so display in a normal document flow.

In this case the nested grid has no relationship to the parent. As you can see in the example it has not inherited the grid-gap of the parent and the lines in the nested grid do not align to the lines in the parent grid.

Subgrid

In the working draft of the Level 2 Grid specification there is a feature called subgrid, which would let us create nested grids that use the track definition of the parent grid.

In the current specification, we would edit the above nested grid example to change the track definition of grid-template-columns: repeat(3, 1fr), to grid-template-columns: subgrid. The nested grid will then use the parent grid tracks to layout items.

.box1 {  grid-column-start: 1;  grid-column-end: 4;  grid-row-start: 1;  grid-row-end: 3;  display: grid;   grid-template-columns: subgrid; } 

Layering items with z-index

Grid items can occupy the same cell. If we return to our example with items positioned by line number, we can change this to make two items overlap.

The item box2 is now overlapping box1, it displays on top as it comes later in the source order.

Controlling the order

We can control the order in which items stack up by using the z-index property — just like positioned items. If we give box2 a lower z-index than box1 it will display below box1 in the stack.

.wrapper {  display: grid;  grid-template-columns: repeat(3, 1fr);  grid-auto-rows: 100px; }  .box1 {  grid-column-start: 1;  grid-column-end: 4;  grid-row-start: 1;  grid-row-end: 3;  z-index: 2; }  .box2 {  grid-column-start: 1;  grid-row-start: 2;  grid-row-end: 4;  z-index: 1; } 

Next Steps

In this article we have had a very quick look through the Grid Layout Specification. Have a play with the code examples, and then move onto the next part of this guide where we will really start to dig into the detail of CSS Grid Layout.

developer.mozilla.org

Новые значения свойства display

И grid, и flexbox являются новыми значениями для свойства display. Чтобы сделать элемент флекс-контейнером, мы используем display: flex, аналогично, чтобы сделать грид-контейнер, мы используем display: grid.

Как только мы это сделаем, непосредственные потомки нашего флекс- или грид-контейнера станут флекс- или грид-элементами, также они получат начальные значения флекс- или грид-элементов.

display: flex

В первом примере у нас есть три элемента в контейнере, которому задано display: flex. Это все, что на нужно, чтобы начать использовать флекбокс.

Пока мы не добавим другие значения свойств, начальные значения свойств флекс-контейнера следующие:

  • flex-direction: row
  • flex-wrap: no-wrap
  • align-items: stretch
  • justify-content: flex-start

Начальные значения для флекс-элементов:

  • flex-grow: 0
  • flex-shrink: 1
  • flex-basis: auto

Мы взглянем на работу этих свойств и значений позднее. Сейчас нам достаточно задать родительскому элементу display: flex и флексбокс будет работать.

See the Pen Flexbox Defaults by rachelandrew (@rachelandrew) on CodePen.

display: grid

Для раскладки элементов по сетке мы используем display: grid. Чтобы увидеть поведение грида, в примере будет использована раскладка с пятью картами.

Добавление display: grid не вносит драматических изменений, однако дочерние элементы теперь стали грид-элементами. Они расположились в одноколоночной полосе сетки, один под другим, сетка создала неявные строки для каждого элемента.

See the Pen Grid Defaults by rachelandrew (@rachelandrew) on CodePen.

Мы можем сделать шаг вперед и сделать раскладку более похожей на сетку за счет добавления колонок. Для этого мы используем свойство grid-template-rows.

В следующем примере, я создала три колонки равной высоты используя новую единицу измерения в CSS, созданную специально для грида — fr. Это сокращение от fraction (доля), в данном случае это доля доступного пространства, которую должна занять колонка. Вы можете видеть, как наши грид-элементы сразу же расположились по сетке в каждой из клеток наших явно определенных столбцов. В сетке по-прежнему создаются незадаваемые явно строки: по мере заполнения доступных ячеек в колонках, строки добавляются для размещения оставшихся элементов.

See the Pen Grid Columns by rachelandrew (@rachelandrew) on CodePen.

Опять-таки, у нас есть определенное поведение по умолчанию. Мы не позиционировали какие-либо из этих грид-элементов, они сами размещали себя по нашей сетке, каждый в отдельную ячейку. Начальные значения для грид-контейнера следующие:

  • grid-auto-flow: row
  • grid-auto-rows: auto
  • align-items: stretch
  • justify-items: stretch
  • grid-gap: 0

Эти начальные значения означают, что наши грид-элементы расположены каждый в отдельной ячейке сетки, работающей поперек рядов. Так как у нас трехколоночная сетка, после заполнения третьей колонки создается новый ряд для размещения оставшихся элементов. Элементы растягиваются по вертикали и горизонтали для заполнения площади сетки.

Выравнивание блоков

В этих двух примерах мы уже встретились со значениями, определенными в модуле выравнивания блоков. “Box Alignment Module Level 3” по сути отвечает за все выравнивания и распределения пространства, определенные в спецификации флексбокса и делает их доступными для других модулей. Поэтому, если вы уже используете флексбокс, то вы используете и выравнивание блоков.

Посмотрим, как выравнивание блоков работает в флексбоксе и гриде, а также на те проблемы, которые мы решаем с его помощью.

Колонки одинаковой высоты

Это то, что очень просто делалось во времена табличной раскладки, но чертовски сложно делать при помощи позиционирования и обтекания. Ниже, в примере с обтеканием, наши карты содержат разное количество контента. У нас нет способа указать другим картам, что они должны визуально соответствовать по высоте первой карте — так как у карт нет никаких связей друг с другом.

See the Pen Floated Columns by rachelandrew (@rachelandrew) on CodePen.

Как только мы задаем свойство display родительского элемента в значение grid или flex, мы устанавливаем отношения между его потомками. Эти отношения активируют работу свойств выравнивания блоков, делая создание колонок равной высоты простым.

В примере с флексбоксом в наших элементах находится разное количество контента. Фон каждого из них выравнивается по линии, а не сидит за контентом, как это должно быть у плавающих элементов. Так как эти элементы выведены в ряд, их поведение контролируется свойством align-items. А для того, чтобы колонки были одинаковой высоты, значением этого свойства должно быть stretch — это начальное значение этого свойства.

See the Pen Flexbox Equal Height Columns by rachelandrew (@rachelandrew) on CodePen.

То же самое мы видим и с раскладкой на гриде. Ниже показана простейшая из раскладок — две колонки (основной контент и боковая). Я опять использую единицы измерения fr: боковая колонка получит значение 1, а основной контент — 3. Фоновый цвет в боковой колонке доходит до того же края, что и контент в основной колонке. Опять, дефолтным значением для align-items является stretch.

See the Pen Grid Equal Height Columns by rachelandrew (@rachelandrew) on CodePen.

Выравнивание в флексбоксе

Мы увидели, что значением по умолчанию для align-items в флексбоксе и гриде является stretch.

В флексбоксе при использовании align-items, мы выравниваем элементы внутри флекс-контейнера на пересекающихся осях. Основная ось определяется свойством flex-direction. В первом примере основной осью является ряд (горизонталь): мы растягиваем элементы на противоположной оси до высоты флекс-контейнера. В свою очередь высота флекс-контейнера это высота флекс-элемента с наибольшим количеством контента.

Высота контейнера определяется высотой самой длинной колонки

Увеличенная версия

Я могу задать высоту контейнеру и в этом случае его высота будет определяться заданным значением.

Высота контейнера явно задана

Увеличенная версия

Вместо дефолтного значения stretch мы можем использовать и другие варианты:

  • flex-start
  • flex-end
  • baseline
  • stretch

Для управления выравниванием по основной оси, используйте свойство justify-content. Его значение по умолчанию flex-start, поэтому все элементы выровнены по левому краю. У нас есть выбор из следующих значений:

  • flex-start
  • flex-end
  • center
  • space-around
  • space-between

Ключевые слова space-between и space-around особенно интересны. В случае со space-between, пространство оставшееся после укладки флекс-элементов равномерно распределяется между ними.

Распределение пространства между элементами со space-between

Увеличенная версия

Использование space-around аналогично, за исключением того, что распределяется пространство, оставшееся с обеих сторон от элементов, а половинные промежутки помещаются в начало и конец.

Распределение пространства между элементами со space-around

Увеличенная версия

Вы можете увидеть работу этих свойств и значений в демо:

See the Pen Flexbox Alignment flex-direction: row by rachelandrew (@rachelandrew) on CodePen.

Мы также можем вывести флекс-элементы как колонку, а не как ряд. Если мы изменим значение flex-direction на column, то основной осью станет колонка, а ряд станет поперечной осью — align-items по-прежнему в значении stretch, а элементы растягиваются на ширину ряда.

Все флекс-элементы выведены в одну колонку

Увеличенная версия

Если мы захотим выровнять их по началу флекс-контейнера, мы используем flex-start.

Флекс-элементы выровнены по началу контейнера

Увеличенная версия

See the Pen Flexbox Alignment flex-direction: column by rachelandrew (@rachelandrew) on CodePen.

Выравнивание в гриде

В грид-раскладке поведение похоже, за исключением того, что мы выравниваем элементы внутри заданной области сетки. В флексбоксе мы говорим об основной и поперечной осях; в случае с гридом мы используем термины “блочная” или “ колоночная ось” для описания осей, определяющих наши колонки, а термины “строчная” и “рядная ось” для описания осей, определяющих наши ряды, как это задано спецификацией.

Мы можем выровнять контент внутри области грида, используя свойства и значения, описанные в спецификации выравнивания блоков.

Область грида это одна или более ячеек. В примере ниже, у нас есть четырехколоночная и четырехрядная сетка. Ряды отделены отступами в 10 пикселей и у нас есть три области грида, созданные с использованием позиционирования на основе линий. Мы позднее подробно рассмотрим такое позиционирование, сейчас скажу, что значение перед / это линия, с которой начинается контент, а значение после это место, где контент завершается.

See the Pen Grid Alignment: align-items and justify-items by rachelandrew (@rachelandrew) on CodePen.

Точечная граница фонового изображения помогает нам увидеть заданные области. Так в первом примере, каждая область использует дефолтное значение stretch для align-items на оси колонки и justify-items на оси ряда. Это значит, что контент растягивается для полного заполнения области.

Образец выравнивания в гриде

Увеличенная версия

Во втором примере, я изменила значение align-items в грид-контейнере на center. Мы также можем изменить это значение в отдельном грид-элементе при помощи свойства align-self. В этом случае, я задала значение center всем элементам , кроме второго, которому задано stretch.

Выравнивание в гриде с center

Увеличенная версия

В третьем примере, я снова поменяла значения justify-items и justify-self , задав соответственно center и stretch.

Выравнивание в гриде с justify-items

Увеличенная версия

Во всех этих примерах контент выравнивался в областях грида, области определялись началом и окончанием линии грида.

Мы также можем выравнивать всю сетку внутри контейнера, если наши полосы занимают меньше пространства, чем контейнер, которому задано display: grid. В этом случае мы можем использовать свойства align-content и justify-content, как и в случае с флексбоксом.

See the Pen Grid Alignment: aligning the grid by rachelandrew (@rachelandrew) on CodePen.

В первом примере мы видим выравнивание по умолчанию, при котором колонки и ряды задаются в абсолютных величинах и занимают меньше пространства, чем позволяет их контейнер фиксированной ширины. Дефолтное значение для обоих start.

выравнивание с align-content start

Увеличенная версия

Чтобы сдвинуть полосы вправо вниз, мы изменим значение на end.

выравнивание с align-content end

Увеличенная версия

Также как и с флексбоксом, мы можем использовать space-around и space-between. Это может повлечь поведение, которое может быть нежелательным для нас, так как отступы в сетке станут шире. Однако, как вы можете видеть на изображении ниже и в третьем примере на Codepen, мы получаем те же отступы между полосами, которые у нас были с флексбоксом.

выравнивание со space-around

Увеличенная версия

Полосы фиксированного размера получают дополнительное пространство, если они охватывают больше одной полосы. Элементы #2 и #4 в нашем примере шире, а #3 выше, так как они получили дополнительное пространство, которое предназначалось промежутку между полосами.

Мы можем полностью центрировать грид, задав align-content и justify-content значение center, как показано в последнем примере.

выравнивание с align-conten

Увеличенная версия

У нас есть отличные возможности выравнивания в флексбоксе и гриде и в целом они работают согласованно. Мы можем выровнять отдельные элементы и группы элементов так, чтобы они были отзывчивыми и не накладывались друг на друга — этого и не хватало вебу до настоящего времени.

Отзывчивость по умолчанию

В последнем разделе мы рассмотрели выравнивание. Свойства выравнивания блоков, используемые в раскладках на основе флексбокса и грида это одна из областей, где мы видим, что эти спецификации возникли в мире, где отзывчивый дизайн является общим принципом. Значения типа space-between, space-around и stretch позволяют добиться отзывчивости и равного распределения содержимого между элементами.

Однако здесь есть нечто большее. Отзывчивый дизайн часто заключается в сохранении пропорций. Когда мы рассчитываем колонки для отзывчивого дизайна, используя подход target ÷ context, представленный в статье Этана Маркотта “Fluid Grids”, мы поддерживаем пропорции оригинального дизайна в абсолютных величинах. Флексбокс и грид дают нам более простые способы работы с пропорциями в нашем дизайне.

Флексбокс дает нам путь к гибкости на основе приоритета контента. Мы видели это при использовании ключевого слова space-between для задания равномерных отступов между элементами. Сначала рассчитывается количество пространства между элементами, а затем оставшееся пространство в контейнере делится и используется для равномерного размещения элементов. Мы можем добиться большего контроля над распределением контента за счет свойств, которые мы можем применять к самим флекс-элементам:

  • flex-grow
  • flex-shrink
  • flex-basis

Эти три свойства чаще указываются в короткой записью свойства flex. Если мы добавляем элементу flex: 1 1 300px, мы указываем, что свойство flex-grow равно 1, то есть этот элемент может расширяться; flex-shrink равно 1, это позволит элементам уменьшаться, а flex-basis равен 300 пикселям. Применение этих правил к нашей карточной раскладке даст следующий результат:

See the Pen Flexbox: flex properties by rachelandrew (@rachelandrew) on CodePen.

Наш flex-basis равен 300 пикселям и у нас три карты в ряду. Если флекс-контейнер шире 900 пикселей, тогда оставшееся пространство делится на три и распределяется поровну между элементами. Это потому что мы задали flex-grow равный 1 и наши элементы могут расти больше, чем задано flex-basis. Мы также задали flex-shrink равный 1, а это значит, что если у нас не хватит места для трех колонок по 300 пикселей, их размер будет уменьшаться в равных долях.

Если мы хотим, чтобы эти элементы росли в разных пропорциях, тогда нам нужно изменить значение flex-grow у одного или нескольких элементов. Если мы захотим, чтобы первый элемент занял втрое больше доступного пространства, то мы зададим flex-grow: 3.

See the Pen Flexbox: flex properties by rachelandrew (@rachelandrew) on CodePen.

Доступное пространство распределяется после того, как выделено место в соответствии с заданным flex-basis. Именно поэтому наш первый элемент не стал в три раза больше остальных, а просто занял три части оставшегося пространства. Вы увидите большее изменение, если зададите flex-basis:0, в таком случае у нас не будет стартового значения, которое мы вычитаем из ширины контейнера. Соответственно, вся ширина контейнера будет распределена между элементами пропорционально.

See the Pen Flexbox: flex properties by rachelandrew (@rachelandrew) on CodePen.

Очень полезным инструментом, помогающим вам понять эти значения является Flexbox Tester. Передавайте ему различные значения и он рассчитает для вас итоговые значения, а также объяснит, почему они получились.

Если вы используете auto в качестве значения flex-basis, то в роли последнего будет использоваться любой доступный размер флекс-элемента. Если размеры не указаны, тогда в качестве дефолтного будет использовано значение content, то есть ширина контента. Поэтому использование auto очень полезно для многократно используемых компонентов, которым может понадобиться задание размера элемента. Вы можете использовать auto и быть уверенными, что если элемент должен быть определенного размера, то флексбокс обеспечит этот размер.

В следующем примере, я задала всем картам flex-basis: auto, а затем первой из них ширину в 350 пикселей. Таким образом flex-basis этой первой карты теперь равен 350 пикселям, у двух других он определяется шириной контента.

See the Pen Flexbox: flex properties by rachelandrew (@rachelandrew) on CodePen.

Если мы вернемся к нашему оригинальному flex: 1 1 300px, добавим еще элементов и зададим flex-wrap: wrap контейнеру, элементы будут укладываться настолько близко, насколько это можно при заданном значении flex-basis. Если у нас 5 изображений и 3 из них укладываются в один ряд, тогда оставшиеся 2 будут выведены на следующем. Так как элементам позволено расширяться, оба перенесенных элемента вырастут в равной мере и мы получим 2 равных увеличенных элемента снизу и 3 равных элемента сверху.

See the Pen Flexbox: wrapping by rachelandrew (@rachelandrew) on CodePen.

Часто возникает следующий вопрос: а как сделать так, чтобы элементы в нижнем ряду были такими же, как и в верхнем, оставляя после себя пустое пространство? С флексбоксом никак. Для такого поведения нужна раскладка на гриде.

Сохранение пропорций с помощью грид-раскладки

Грид, как мы уже видели обладает концепцией создания полос колонок и рядов, в которых позиционируются элементы. Когда мы создаем гибкую грид-раскладку, мы задаем пропорции при задании полос в грид-контейнере — именно полос, а не элементов, как в флексбоксе. Мы уже сталкивались со специальной единицей fr, когда создавали раскладку на гриде. Эта единица работает примерно также как flex-grow при flex-basis:0. Она распределяет доли доступного пространства в грид-контейнере.

В следующем примере кода, первой полосе колонок было задан 2fr, двум другим 1fr. Таким образом, мы делим пространство на четыре части и даем две части первой полосе и по одной двум оставшимся.

See the Pen Simple grid show fraction units by rachelandrew (@rachelandrew) on CodePen.

Смешивание абсолютных единиц измерения и fr валидно. В следующем примере у нас будет полоса 2fr, полоса 1fr и полоса в 300 пикселей. Сначала вычитается абсолютная величина для третьей полосы, а затем оставшееся пространство делится на три, две части идут в первую полосу, а оставшаяся во вторую.

See the Pen Grid: Mixing absolute and fraction units by rachelandrew (@rachelandrew) on CodePen.

Также из этого примера вы можете заметить, что наши элементы заполняют указанные полосы — они не распределяются по всему ряду, как в флексбоксе. Это потому, что в гриде мы создаем двумерную раскладку, а затем помещаем туда элементы. В флексбоксе мы берем наш контент и укладываем его столько, сколько помещается в одном измерении, в колонке или в ряду, обрабатывая дополнительные ряды или колонки как совершенно новые флекс-контейнеры.

Хорошо то, что у нас по-прежнему есть способ создать столько колонок определенной величины, сколько влезет в контейнер. Мы можем сделать это с помощью синтаксиса grid и repeat.

В следующем примере я буду использовать синтаксис repeat для создания максимального количества двухсотпиксельных колонок, помещающегося в контейнере. Я использую синтаксис repeat для перечисления полос с ключевым словом auto-fill и задаваемым им размером.

На момент написания это не было имплементировано в Chrome, но работало в версии Firefox для разработчиков.

See the Pen Grid: As many 200 pixel tracks as will fit by rachelandrew (@rachelandrew) on CodePen.

Мы можем продвинуться еще на один шаг и скомбинировать долевые и абсолютные единицы, чтобы грид создавал максимум двухсотпиксельных полос, помещающихся в контейнер и поровну распределил между ними оставшееся место.

See the Pen Grid: As many 200 pixel tracks as will fit, distribute remain space evenly by rachelandrew (@rachelandrew) on CodePen.

Таким образом мы совместим преимущества двумерной раскладки с гибким количеством полос — и все это без медиазапросов. Дальше мы рассмотрим расширение спецификаций флексбокса и грида. Там, где флексбокс прекращает распределять элементы в одном измерении, грид только начинает это делать.

Разделение порядка в разметке и визуального порядка элементов

С флексбоксом мы можем делать многое в плане позиционирования флекс-элементов. Мы можем выбрать направления, в котором они обтекают, задав flex-direction в значение row, row-reverse или column, column-reverse и мы можем задать порядок, контролирующий порядок вывода элементов.

See the Pen Flexbox: order by rachelandrew (@rachelandrew) on CodePen.

С грид-раскладкой, нам надо правильно расположить дочерние элементы по сетке, которую мы определили. В большинстве примеров мы полагаемся на автоматическое размещение по сетке; правила, которые определяют размещение непозиционированных нами элементов. В следующем примере я использую позиционирование на основе линий, чтобы позиционировать элементы грида.

Свойства grid-column и grid-row являются краткой записью следующего набора свойств: grid-column-start, grid-row-start, grid-column-end и grid-row-end. Значение перед / это линия, с которой начинается контент, а значение после — линия, на которой контент заканчивается.

See the Pen Grid: line-based positioning by rachelandrew (@rachelandrew) on CodePen.

Вы также можете именовать свои линии. Это пригодиться, когда вы создаете свою сетку в грид-контейнере. Имена линий указываются в квадратных скобках, а позиционирование осуществляется также как и в предыдущем примере, только вместо индекса линии указывается ее имя.

See the Pen Grid: line-based positioning, named lines by rachelandrew (@rachelandrew) on CodePen.

У вас может быть несколько линий с одним именем и вы можете указывать их с помощью имени и индекса.

Вы можете использовать ключевое слово span, охватывая указанное число линий, например, до третьей линии с именем col. Этот тип позиционирования полезен для использования компонентов, размещающихся в разных местах раскладки. В примере ниже, я хочу чтобы некоторые элементы разместились на 6 полосах колонок, а оставшиеся заняли бы три полосы. Я использую авторазмещение для раскладки элементов, но когда грид встречает элемент с классом wide, стартовое значение будет auto, а конечное span 2; таким образом он начнется там, где и должен начать автоматически, но затем охватит две линии.

See the Pen Grid: multiple lines with the same name by rachelandrew (@rachelandrew) on CodePen.

Использование авторазмещения с несколькими подобными правилами может оставить пробелы в вашей стеке, также в сетке могут появится элементы требующие двух полос при наличии только одной. По умолчанию грид продвигает вперед, поэтому как только она оставит пробел, она не будет возвращаться, чтобы заполнить его — если мы только не зададим grid-auto-flow: dense, в этом случае грид будет возвращаться для заполнения пробелов, беря контент в DOM-порядке.

See the Pen Grid: grid-auto-flow: dense by rachelandrew (@rachelandrew) on CodePen.

Также есть отдельный метод позиционирования элементов в грид-раскладке — путем создания визуального представления раскладки напрямую в свойстве grid-template-areas. Для этого вам сначала надо присвоить имена всем прямым потомкам грид-контейнера, которые вы хотите позиционировать.

Затем мы располагаем элементы в манере ASCII-арта, указывая значение grid-template-areas. Если вы хотите полностью изменять раскладку с помощью медиазапросов, вам достаточно изменить только это свойство.

See the Pen Grid: template areas by rachelandrew (@rachelandrew) on CodePen.

Как вы можете видеть из примера, чтобы оставить ячейку пустой, мы используем точку или серию точек без пустого пространства между ними. Чтобы вызвать охват элементом нескольких полос, мы повторяем его имя.

Последствия переупорядочения для доступности.

В флексбоксе, а еще больш в гриде, нам нужно с огромной осторожностью использовать методы для переупорядочения контента. Вот что говорит спецификация флексбокса:

Авторы должны изменять только визуальный, а не логический порядок. Таблицы стилей не должны производить логическое переупорядочивание.

И предупреждение в спецификации грида:

Грид-раскладка дает авторам возможность перестановки по всему документу. Однако это не является заменой корректной разметке исходников документа. Свойства упорядочивания и размещения по сетке не затрагивают невизуальные медиа (такие как речь). Кроме того, визуальное изменение порядка грид-элементов не влияет порядок прохода по ним в режиме последовательной навигации (например, по ссылкам).

В обоих случаях, как определено на данный момент, переупорядочивание является исключительно визуальным. Оно не меняет логический порядок документа. Дополнительно нам надо особо позаботиться о слабовидящих пользователях с клавиатурой. Очень легко сделать так, что при проходе табом по документу мы будем перескакивать из навигации сверху вниз документа из-за того, что грид-элемент в источнике находится раньше, чем позиционируется визуально.

Новая система для раскладки

Я не рассматривала каждый аспект флексбокса и грида в этой статье — моя цель состояла в том, чтобы показать сходства и различия в спецификациях и заодно рассказать о выравнивании блоков. Для демонстрации того, что эти спецификации принесли нам новую систему раскладки, соответствующую нуждам сайтов и приложений, которые мы создаем сейчас.

В настоящий момент флексбокс работает во всех основных браузерах, в то время как грид под флагом работает в Chrome, Opera, Safari и Firefox. Флексбокс изначально работал с префиксной версией, которая использовалась разработчиками, но затем он изменился, оставив нас с ощущением, что мы не можем полагаться на него. Грид разрабатывался под флагом и если вы посмотрите примеры в статье с активированным флагом, вы заметите, что имплементации уже очень совместимы. На данный момент спецификация находится в статусе кандидата в рекомендации. Поэтому когда грид выйдет в работу (это ожидается в начале следующего года) у него будет солидная кроссбраузерная поддержка.

Можете поиграть с примерами из статьи, а также ознакомиться с остальными ресурсами, которые приведены в списке ниже.

prgssr.ru


You May Also Like

About the Author: admind

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.