Приветствую! Представляю вашему вниманию перевод статьи «Understanding CSS Grid: Grid Template Areas» автора Rachel Andrew
При использовании CSS Grid, вы можете располагать элементы на сетке, указывая начальную и конечную grid-линии. Однако, существует и другой, более наглядный способ описания разметки. В этой статье мы узнаем, как использовать свойство grid-template-areas
для размещения элементов на сетке и выясним, как оно в действительности работает.
Статьи из данной серии:
- Часть 1: Grid-контейнер
- Часть 2: Grid-линии
- Часть 3: Grid-области
Примечание от переводчика
В интернете очень много как статей, так и руководств о технологии CSS Grid. Но порой в материалах Rachel Andrew доступно освещаются те моменты, которым в других руководствах уделяется недостаточно внимания.
Следовательно, данную статью стоит воспринимать лишь как ещё одну точку зрения на уже хорошо известную технологию
Описание разметки с помощью свойства 'grid-template-areas'
Свойство grid-template-areas
принимает в виде значения одну или несколько строк. Каждая строка (заключённая в кавычки) представляет строку сетки. Свойство grid-template-areas
можно либо использовать в сетке, которая уже определена с помощью grid-template-rows
и grid-template-columns
, либо описать весь макет только с помощью него, но в этом случае высота всех строк будет определяться автоматически.
В следующем примере описывается сетка с четырьмя областями – каждая область занимает два колоночных и два строковых трека. Структура области задаётся путём указания её названия в каждой ячейке, которую должна занимать:
grid-template-areas: "one one two two"
"one one two two"
"three three four four"
"three three four four";
Размещение элементов на получившейся сетке осуществляется путём присвоения свойству grid-area
соответствующего названия области, которую данный элемент должен занять. Следовательно, если я хочу поместить элемент с классом test
в область сетки one
, я использую следующий CSS:
.test {
grid-area: one;
}
Увидеть это в действии можно на примере CodePen, размещённого ниже. У меня есть четыре элемента (с классами от одного до четырёх), которые присваиваются соответствующим grid-областям с помощью свойства `grid-area' и поэтому отображаются на сетке в нужном блоке.
Если воспользоваться Grid-инспектором браузера Firefox, можно увидеть названия областей и линии сетки, демонстрирующие, что каждый элемент действительно занимает две строки и две колонки – и всё это без необходимости использовать позиционирование элементов по линиям сетки.
Правила использования 'grid-template-areas'
У данного способа описания раскладки существует несколько важных правил. Их несоблюдение может привести к ошибкам в значении, что не позволит правильно отрисовать сетку.
Правило №1: Описывайте всю сетку
Первое правило заключается в том, что в значении свойства нужно описывать всю сетку, то есть должна быть заполнена каждая её ячейка.
Если вы хотите оставить ячейку пустой, просто укажите вместо названия одну или несколько точек, не разделяя их пробелом ('.'
или '...'
).
Следовательно, если я изменю значение свойства grid-template-areas
на следующее:
grid-template-areas: "one one two two"
"one one two two"
". . four four"
"three three four four";
то теперь у нас есть две незаполненные ячейки. Элемент "three" отображается только в последней строке сетки.
Правило №2: Одно имя – одна область
Область с определённым названием допускается определять только один раз. Это значит, что вы не можете поместить какое-то содержимое сразу в несколько мест на сетке, задав для разных областей одинаковое имя. Таким образом, следующее значение будет некорректным и приведёт к тому, что свойство полностью будет проигнорировано, так как мы продублировали область с именем three
:
grid-template-areas: "one one three three"
"one one two two"
"three three four four"
"three three four four";
Правило №3: Только прямоугольные области
Нельзя создавать непрямоугольные области, следовательно, данное свойство нельзя использовать для создания 'L' или 'T'-образных областей – это также делает всё свойство некорректным и приводит к его игнорированию:
grid-template-areas: "one one two two"
"one one one one"
"three three four four"
"three three four four";
Форматирование строк
Мне нравится оформлять значение свойства grid-template-areas
так, как изображено на примере выше, где каждая строка представляет строковый трек сетки. Это даёт визуальное представление о том, как будет выглядеть итоговый макет.
Также может быть полезным вставлять дополнительные отступы между ячейками, а пустые ячейки обозначать несколькими точками.
В приведённом ниже примере я вставила дополнительные пробелы у ячеек с коротким названием и несколько точек для пустых ячеек, чтобы визуально образовались не только строки, но и столбцы:
grid-template-areas: "one one two two"
"one one two two"
".... .... four four"
"three three four four";
Тем не менее, вполне допустимой является и запись всех строк в одну линию, как в следующем примере:
grid-template-areas: "one one two two" "one one two two" "three three four four" "three three four four";
Объяснение свойств 'grid-template-areas'
и 'grid-area'
Причина, по которой каждая область должна быть прямоугольной, заключается в том, что она должна быть той же формы, которую можно задать с помощью размещения элементов по grid-линиям. То есть, приведённый выше пример мы вполне могли бы воспроизвести с использованием grid-линий, как показано в CodePen ниже. В нём я создала сетку тем же способом, что и раньше. Но в этот раз для размещения элементов я использовала grid-линии, добавляя свойства grid-column-start
, grid-column-end
, grid-row-start
и grid-row-end
.
Примечание: если вы прочтёте предыдущую статью из данной серии «Понимание CSS Grid (2 часть): Grid-Линии», то узнаете, что с помощью сокращённого свойства grid-area
можно задать все четыре линии в одном свойстве.
Это значит, что мы можем создать этот же макет, используя сокращённое свойство с номерами линий, заданными в следующем порядке:
grid-row-start
grid-column-start
grid-row-end
grid-column-end
.one {
grid-area: 1 / 1 / 3 / 3;
}
.two {
grid-area: 1 / 3 / 3 / 5;
}
.three {
grid-area: 3 / 1 / 5 / 3;
}
.four {
grid-area: 3 / 3 / 5 / 5;
}
Свойство grid-area
интересно тем, что может принимать как номера линий, так и их имена.
Использование 'grid-area'
с номерами линий
Если в свойстве grid-area
указываются номера линий, то линии нужно указывать в порядке, описанном выше.
Если же в данном свойстве вы пропускаете какие-то номера, они принимают значение auto
, что значит, что область будет занимать один трек (что является поведением по умолчанию). Таким образом, следующий CSS задаст элементу свойство grid-row-start: 3
, а значения остальных свойств позиционирования установит на auto
. Следовательно, элемент будет автоматически размещён на 3 строковой линии, в первом доступном колоночном треке, и будет занимать один строковый трек и один колоночный трек.
grid-area: 3;
Использование 'grid-area'
с именами линий
Если вы используете идентификатор (именно так в Grid-разметке называется именованная область), то свойство grid-area
также допускает возможность указать четыре линии. Если у вашей сетки есть именованные линии, как описано в первой статье из данной серии, вы можете применять имена линий так же, как и их номера.
Но в данном случае, когда мы используем имена линий, поведение при их пропуске для свойства grid-area
отличается от поведения при использовании номеров.
Ниже я создала сетку с именованными линиями и использовала grid-area
для размещения элемента (опустив последнее значение):
.grid {
display: grid;
grid-template-columns:
[one-start three-start] 1fr 1fr
[one-end three-end two-start four-start] 1fr 1fr [two-end four-end];
grid-template-rows:
[one-start two-start] 100px 100px
[one-end two-end three-start four-start] 100px 100px [three-end four-end];;
}
.two {
grid-area: two-start / two-start / two-end;
}
Это значит, что мы не указали имя линии для свойства grid-column-end
. В спецификации говорится, что в этой ситуации свойство grid-column-end
должно использовать то же значение, что и у свойства grid-column-start
. Если значения этих двух свойств одинаковые, то конечная строка отбрасывается и, по сути, значение устанавливается на auto
, поэтому элемент занимает один трек, как и в случае с использованием номеров линий.
То же самое происходит, если опустить третье значение свойства grid-row-end
. Оно принимает то же значение, что и grid-row-start
и следовательно, становится auto
.
Посмотрите на следующий CodePen-пример, демонстрирующий, как разное количество значений для свойства grid-area
влияет на размещение элемента:
Это объясняет, почему свойство grid-area
работает с единственным значением, представляющим название области.
Когда мы с помощью свойства grid-template-areas
создаём именованную область, линии по краям получают то же имя, что и у области. В нашем случае мы могли бы поместить элемент в определённую ранее область, указав её название для свойств позиционирования по линиям:
.one {
grid-row-start: one;
grid-row-end: one;
grid-column-start: one;
grid-row-end: one;
}
Если имя области назначается свойству стартовой линии (-start)
, то это означает начальную точку колонки или строки. Если же имя области назначается свойству конечной строки (-end)
, – это соответственно означает конец колонки или строки.
Это значит, что когда мы задаём grid-area: one
, мы пропускаем последние три значение данного свойства сокращённой записи. Все они в итоге будут скопированы из первого значения – в нашем случае примут значение one
, а элемент разместится как в случае с использованием отдельных свойств.
Принцип, по которому в Grid-разметке работает именование, достаточно умный и позволяет применять интересные решения, которые я описала в моих статьях «Именование в CSS Grid» и «Editorial Design Patterns With CSS Grid And Named Columns».
Наложение элементов при использовании 'grid-template-areas'
При использовании свойства grid-template-areas
, только одно имя может принадлежать каждой ячейке. Однако, после построения макета с помощью этого свойства, у вас остаётся возможность добавлять на сетку дополнительные элементы, используя номера строк.
В приведённом ниже CodePen-примере я добавила дополнительный элемент и расположила его над другими элементами сетки, указывая grid-линии.
Вы также можете использовать имена линий, определенные при создании колонок и строк. Более того, вам также будут доступны названия линий, созданные при формировании областей. Мы уже видели, как определение названия для одной области даёт имена четырём линиям по краям этой области. Вы также получаете линию в начале и конце каждой области с суффиксами -start
и -end
, добавляемыми соответственно к начальной и конечной линии.
Следовательно, grid-область, именуемая one
, имеет начальную линию, именуемую one-start
и конечную линию, именуемую one-end
.
Также, вы можете использовать эти неявные имена линий для размещения элемента на сетке. Это может быть полезным, если вы перестраиваете сетку на разных контрольных точках, но хотите, чтобы размещённый на сетке элемент всегда начинался с определённой линии.
Использование 'grid-template-areas'
в адаптивном дизайне
Я часто работаю с созданием компонентов и вижу, что использование grid-template-areas
может полезно с точки зрения возможности прямо из CSS точно увидеть, как будет выглядеть данный компонент. Это также облегчает перестроение компонента в разных контрольных точках путём простого переопределения значения свойства grid-template-areas
, иногда в дополнение к изменению количества доступных колонок.
В примере ниже я определила макет компонента в виде одноколоночного макета. Далее, минимум на 600px я переопределяю количество колонок, а также значение свойства grid-template-areas
, чтобы создать макет с двумя колонками. Приятной особенностью такого подхода является то, что любой, кто посмотрит на этот код, сможет понять, как работает макет.
.wrapper {
background-color: #fff;
padding: 1em;
display: grid;
gap: 20px;
grid-template-areas:
"hd"
"bd"
"sd"
"ft";
}
@media (min-width: 600px) {
.wrapper {
grid-template-columns: 3fr 1fr;
grid-template-areas:
"hd hd"
"bd sd"
"ft ft";
}
}
header { grid-area: hd; }
article {grid-area: bd; }
aside { grid-area: sd; }
footer { grid-area: ft; }
Доступность
Используя этот метод, следует помнить о том, что с помощью него очень легко менять позицию элементов и в конечном счете можно столкнуться с ситуацией, в которой порядок отображения элементов на экране будет отличаться от их последовательности в исходном коде. Любой, кто взаимодействует с сайтом с помощью кнопки Tab или кроме экрана использует и озвучивание содержимого, будет получать информацию в том порядке, в котором она задана в исходном коде. Если отображаемое на экране содержимое не соответствует этой последовательности, это может существенно запутать пользователя. Не используйте этот метод изменения позиционирования элементов, предварительно не убедившись, что их последовательность в исходном коде соответствует визуальному отображению на экране.
Резюмируя
Собственно, в этом суть использования свойств grid-template-areas
и grid-area
при создании разметки. Если вы еще не использовали этот метод, попробуйте. Я считаю, что это отличный способ экспериментировать с разметкой и часто использую его при создании прототипов макетов, даже если по какой-то причине в рабочей версии будет использоваться другой метод.
lynoxod
Большое спасибо за статью