[Перевод] Понимание CSS Grid (2 часть): Grid-линии

Приветствую! Представляю вашему вниманию перевод статьи «Understanding CSS Grid: Grid Lines» автора Rachel Andrew

Понимание CSS Grid (2 часть): Grid-линии

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

Мы охватим следующие моменты:


  1. Свойства размещения элементов grid-column-start, grid-column-end, grid-row-start, grid-row-end и их краткие формы записи grid-column and grid-row
  2. Как использовать grid-area для размещения элементов по номерам grid-линий
  3. Как располагать элементы с помощью именованных линий
  4. Отличие в размещении элементов в явной и неявной сетке
  5. Использование ключевого слова span с небольшим бонусом subgrid
  6. Чего следует остерегаться при одновременном использовании ручного и автоматического размещения элементов

Статьи из данной серии:


Примечание от переводчика
В интернете очень много как статей, так и руководств о технологии CSS Grid. Но порой в материалах Rachel Andrew доступно освещаются те моменты, которым в других руководствах уделяется недостаточно внимания.

Следовательно, данную статью стоит воспринимать лишь как ещё одну точку зрения на уже хорошо известную технологию


Концепции позиционирования элементов по линиям

Чтобы разместить элемент на сетке, нужно задать линию, на которой он должен начинаться, и линию, на которой заканчиваться. Следовательно, если я хочу, чтобы на сетке, имеющей по 5 строк и колонок, элемент занимал вторую и третью колонки, а также с первой по третью строки, мне нужно использовать следующий CSS. Помните, что мы указываем не номер трека (колонки или строки), а номер линии, которые их разделают.

.item {
  grid-column-start: 2;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 4;
}

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

.item {
  grid-column: 2 / 4;
  grid-row: 1 / 4;
}

В следующем CodePen вы можете увидеть пример и попробовать изменить линии, которые охватывает элемент.

Обратите внимание, что наш элемент растягивается на всю определённую линиями область, потому что изначальные значения свойств выравнивания для элемента align-self и justify-self равны stretch.

Если достаточно, чтобы элемент занимал только один трек (одну колонку или строку), номер линии завершения можно не указывать, поскольку по умолчанию браузер и так растянет элемент до следующей линии, заняв один трек. Мы видим такое поведение, когда автоматически располагаем элементы (как в первой статье из этой серии) — каждый элемент помещается в ячейку, которая по ширине равна одной колонке, а по высоте — одной строке. Таким образом, чтобы заставить элемент занять место между 2 и 3 линией, следует указать:

.item {
  grid-column: 2 / 3;
}

Но также вполне корректной будет запись, не содержащая линию, на которой элемент заканчивается:

.item {
  grid-column: 2;
}


Сокращённое свойство "grid-area"

Располагать элементы можно и с помощью свойства grid-area. Указав в свойстве номера четырёх линий, можно тем самым определить область, занимаемую данным элементом. Более подробно мы разбёрем это свойство в следующей статье.

.item {
  grid-area: 1 / 2 / 4 / 4;
}

Последовательность номеров линий в данном свойстве определяет значения для следующих свойств: grid-row-start, grid-column-start, grid-row-end, grid-column-end. Для языков с горизонтальным направлением текста, записываемых слева направо (таких, как английский), это будет верх, лево, низ, право. Возможно, вы обратили внимание, что стороны указываются в обратном порядке по сравнению с тем, как мы привыкли записывать в CSS сокращения для таких свойств, как, например, margin.

Причина этого заключается в том, что Grid работает одинаково, независимо от того, какой установлен режим письма, и мы ещё вернёмся к этому чуть ниже. Следовательно, установка сначала двух линий начала, а затем двух линий конца имеет больше смысла, чем сопоставление значений с физическими сторонам экрана. Я не склонна использовать это свойство при размещении элементов по линиям, так как считаю, что свойства с двумя значениями grid-column и grid-row более удобочитаемы при беглом просмотре файла стилей.


Линии явной сетки

В первой части упоминались явная и неявная grid-сетки. Явная — это сетка, которую вы создаёте с помощью свойств grid-template-columns и grid-template-rows. При объявлении колоночных и строковых треков вы также определяете и линии между этими треками.

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

При работе с языком, имеющим горизонтальный режим записи справа налево (например, арабским), линия 1 в блочном направлении всё еще будет вверху, но линия 1 в строчном направлении уже будет справа, а не слева.
Тот же элемент в режиме записи RTL

Если вы работаете с вертикальным режимом записи (на изображении ниже установлено свойство writing-mode: vertical-rl), линия 1 блочного направления будет справа. Линия 1 строчного направления — вверху.
Режим записи vertical-rl

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

Последняя линия явной сетки всегда имеет номер -1, а нумерация линий идёт в обратном порядке, задавая следующей с конца линии номер -2 и так далее. Это значит, что если вы хотите, чтобы элемент охватил все колонки явной сетки, достаточно задать:

.item {
  grid-column: 1 / -1;
}


Линии неявной сетки

Если вы создали треки неявной сетки, они также отсчитываются от 1. В примере ниже я создала явную сетку для колонок, однако, строковые треки были созданы в неявной сетке, которой я задаю высоту 5em с помощью свойства grid-auto-rows.

Элементу с классом placed задано свойство grid-row: 1 / -1, при котором он должен занять всё доступное место по вертикали, начиная с первой строковой линии 1 до последней строковой линии -1. Если бы для двух образовавшихся строк была задана явная сетка, то элемент и занимал обе строки. Но так как данные строковые треки были созданы в рамках неявной сетки, последней линией (которую мы обозначаем номером -1) стала линия 2, а не линия 3.

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


Размещение элементов по именованным линиям

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

.grid {
  display: grid;
  grid-template-columns: [full-start] 1fr [main-start] 2fr 2fr [main-end full-end];
}

Имена линий можно использовать вместо номеров при размещении элементов на сетке.

.item {
  grid-column: main-start / main-end;
}

Если линии присвоено несколько имён, при размещении элементов на сетке можно выбирать любое из них, все имена будут означать одну и ту же строку.

Примечание: Именование линий сопровождается некоторыми примечательными моментами. Более подробно это описано в статье «Именование в CSS Grid»


Одинаковые имена у разных линий

Вы получите весьма интересное поведение, если дадите нескольким линиям одинаковые имена. Данная ситуация может произойти, если линии именуются с помощью функции repeat(). В приведённом ниже примере дана сетка с 8 колонками, созданными путём 4-кратного повторения шаблна 1fr 2fr. Начальную линию маленького трека я назвала sm, а для большого трека — lg. Это значит, что у меня есть по 4 линии с каждым именем.

В этой ситуации мы можем использовать имя линии в качестве её порядкового номера. Таким образом, чтобы разместить элемент, начиная со второй линии с именем sm и растянуть до третьей линии с именем lg, я задаю свойство grid-column: sm 2 / lg 3. Если указать имя без порядкового номера, это всегда будет восприниматься как первая линия с таким именем.


Использование ключевого слова "span"

Бывает, нужно, чтобы элемент занимал определённое количество треков (столбцов или строк), но при этом точно неизвестно или не важно, где именно он будет располагаться на сетке. Например, в ситуации, когда элементы располагаются на сетке автоматически, но вы хотите, чтобы они занимали несколько треков вместо одного, как предусмотрено по умолчанию. В этом случае вы можете использовать ключевое слово span. В приведённом ниже примере элемент начинается с линии auto (это линия, на которую элемент будет помещён в результате автоматического размещения) и занимает 3 колонки.

.item {
  grid-column: auto / span 3;
}

Эта техника станет очень полезной, когда мы получим широкую поддержку технологии subgrid в виде соответствующего значения для свойств grid-template-columns и grid-template-rows. Например, в макете, состоящем из набора карточек, у каждой из которых есть область заголовка и область основного содержимого, может возникнуть потребность сделать эти области у всех карточек одинаковыми. Каждая отдельная карточка будет использовать subgrid для своих строк (то есть, получать по две строки каждая). Результат можно увидеть в CodePen-примере ниже, если используете браузер Firefox или на изображении под ним.

gjgcms564vocxpt4z7u5-fycloi.jpeg


Наслаивание элементов при размещении по линиям

При автоматическом позиционировании, CSS Grid помещает элементы сетки в пустые ячейки, а не в одну и ту же. Однако, вы всё же можете сделать это с помощью их размещения с указанием конкретных линий. В следующем примере изображение занимает два строковых трека, а подпись расположена во втором строковом треке и имеет полупрозрачный фон.

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


Смешивание автоматического и «линейного» позиционирования

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

Поведение по умолчанию всегда предусматривает продвижение вперёд, оставляя ячейку свободной, если элемент не помещается на сетке. Вы можете менять это поведение с помощью свойства grid-auto-flow со значением dense. В этом случае, если присутствует элемент, который равен оставшемуся в сетке свободному месту, он будет помещён туда вне очереди, чтобы заполнить свободное пространство. В приведённом ниже примере используется «плотное» размещение, элемент 3 теперь размещается перед элементом 2.

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

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

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

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


В заключение

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

© Habrahabr.ru