Подробно о размещении элементов в грид-раскладке (CSS Grid Layout)
Перевод статьи Deep Dive into Grid Layout Placement с сайта blogs.igalia.com, опубликовано на css-live.ru с разрешения автора — Мануэля Рего Касановаса.
Полный обзор разных методов позиционирования элементов, предлагаемых спецификацией CSS Grid Layout.
В последние месяцы в рамках моей работы в Igalia я сосредоточенно доделывал те новые/пропущенные места в реализации CSS Grid Layout в движке Blink, что относились к размещению элементов. Вкратце, работа в основном велась по 2 направлениям:
- Поддержка неявного грида перед явным. Так, чтобы к гриду можно было добавлять полосы не только в направлении заполнения (обычно справа/снизу), но и с противоположной стороны.
- Правильная интерпретация неизвестных именованных грид-линий. Это случай, когда элемент привязывается к линии под названием «
foo
», но нигде в гриде нет линий с таким именем.
Эти задачи могут показаться простыми, но из них вытекало немало изменений в реализации самого механизма. Ради их завершения мне в итоге пришлось чуть ли не переписать весь код нахождения позиций в гриде. Я даже написал документ с пояснением всего плана и всех технических подробностей, где можно найти ссылки на все соответствующие патчи.
Теперь, когда я всё это доделал, самое время объяснить, как им пользоваться. Хотя мой коллега Серхио уже писал об этом в 2014-м, спецификация с тех пор поменялась, так что, думаю, лучше попытаться объяснить всё целиком с нуля. Эта статья — что-то вроде выжимки с примерами из раздела «Размещение грид-элементов» спецификации CSS Grid Layout.
Грид-линии
Это, пожалуй, одно из важнейших понятий спецификации грид-раскладки. Грид-линии — это линии, разделяющие грид по горизонтали и вертикали. И они нумеруются, начиная с 1
.
Рассмотрим, как это работает, на примере грида 3х2:
<div style="display: grid; grid-template-columns: 300px 200px 100px; grid-template-rows: 100px 50px;"> </div>
Пример нумерованных грид-линий
Свойства размещения в гриде
Чтобы указать позицию элементов в грид-контейнере, понадобятся свойства размещения в гриде. Вот эти свойства:
grid-column-start
: задает первую вертикальную линию для элемента.grid-column-end
: задает последнюю вертикальную линию для элемента.grid-row-start
: задает первую горизонтальную линию для элемента.grid-row-end
: задает последнюю горизонтальную линию для элемента.
Этими свойствами мы определяем область, в которую будет помещен грид-элемент. Для этого используются номера грид-линий.
Начальное значение этих свойств — auto
, благодаря чему элементы могут размещаться автоматически, отыскивая в гриде пустые ячейки. За подробностями этого обращайтесь к предыдущей статье по теме (либо к недавней статье на css-live по той же теме — прим. перев.).
В добавок к этому есть несколько удобных сокращений:
grid-column
: сокращенная запись для свойствgrid-column-start
иgrid-column-end
.grid-row
: сокращенная запись для свойствgrid-row-start
иgrid-row-end
.grid-area
: сокращенная запись для всех 4 свойств сразу..
Итак, представьте, что добавляете в тот же грид следующий элемент:
<div style="grid-column-start: 2; grid-column-end: 4; grid-row-start: 1; grid-row-end 2;"> </div>
Возможно, читать будет проще, если воспользоваться сокращениями:
<div style="grid-column: 2 / 4; grid-row: 1 / 2;"></div>
Это значит, что грид-элемент займет 2-ю и 3-ю колонки в первом ряду.
Пример размещения элемента с помощью номеров линий
Охват ячеек
Предыдущий грид-элемент охватывает 2 колонки (2-ю и 3-ю), ссылаясь на линии. То же самое можно сделать с помощью ключевого слова span
, в сочетании с количеством ячеек, которое нужно охватить.
Таким образом, поместить элемент в то же самое место можно так:
<div style="grid-column: 2 / span 2; grid-row: 1;"></div>
Пример размещения элемента с помощью span
Обратите внимание, что здесь мы не указываем последнюю линию для ряда. Это значит, что у grid-row-end
будет значение auto
. В этом случае auto
по умолчанию означает охват одной ячейки.
Отрицательные номера линий
До сих пор мы видели только положительные номера, но у линий есть и отрицательные индексы. Отрицательные номера позволяют указывать линии, считая с конца грида.
Отталкиваясь от того же примера, можно опять поместить элемент в то же самое место с помощью отрицательных индексов:
<div style="grid-column: -3 / -1; grid-row: -3 / -2;"></div>
Пример размещения элементов с помощью отрицательных номеров
В некоторых случаях это бывает очень кстати. Например, если элемент обязательно должен быть в последней колонке, независимо от общего количества полос, достаточно лишь задать grid-column-end: -1;
.
Именованные грид-линии
Помимо сказанного, грид-линии можно именовать, так что не нужно будет держать в уме конкретные числа, чтобы обращаться к ним.
Немного изменим наше определение грида, сохранив размеры полос, но добавив линиям имена:
<div style="display: grid; grid-template-columns: [start] 300px [main] 200px [aside] 100px [end]; grid-template-rows: [top] 100px [middle] 50px [bottom];"> </div>
И снова, чтобы разместить элемент в том же самом месте, нужно лишь обратиться к именам линий:
<div style="grid-column: main / end; grid-row: top / middle;"></div>
Пример размещения по именам линий
У одной линии может быть несколько имен, надо только задать их в определении: grid-template-rows: [top start] 100px [middle center] 50px [bottom end];
.
Имена линий также могут повторяться. Чтобы обратиться к ним, придется использовать номер, который тоже может быть положительным и отрицательным. Рассмотрим это на другом примере:
<div style="display: grid; grid-template-columns: [col] 200px [gap] 50px [col] 200px [gap] 50px [col] 200px [gap];"> </div>
И представьте, что вы размещаете несколько элементов вроде этого:
<div style="grid-column: col 2;"></div> <div style="grid-column: col 1 / gap 2;"></div> <div style="grid-column: col -1;"></div>
Пример размещения элементов с повторяющимися именами линий
И конечно, можно охватывать ячейки вплоть до именованной линии:
<div style="grid-column: col 2 / span 2 gap;"></div>
Пример размещения элемента с охватом ячеек до именованной линии
Грид-области
Что еще лучше, можно определять грид-области и размещать элементы непосредственно в них. Понадобится свойство grid-template-areas
, чтобы присвоить имена различным областям в гриде. И можно непосредственно размещать элементы, пользуясь сокращенным свойством grid-area
.
Давайте для примера возьмем грид побольше (5×4):
<div style="display: grid; grid-template-columns: 100px 100px 100px 100px 100px; grid-template-rows: 100px 100px 100px 100px; grid-template-areas: 'title title title title aside' 'nav main main main aside' 'nav main main main aside' 'footer footer footer footer footer';"> </div>
И разместим по элементу в каждой области:
<div style="grid-area: title;"><div> <div style="grid-area: nav;"></div> <div style="grid-area: main;"></div> <div style="grid-area: aside;"></div> <div style="grid-area: footer;"></div>
Пример размещения элементов в грид-областях
Грид-области и именованные грид-линии
У областей и размещения в них есть еще одна интересная особенность: грид-области неявно задают имена окружающим их линиям. Эти неявные имена отличаются суффиксами «-start
» и «-end
». И при размещении элементов можно обращаться к этим линиям, а не сразу к целой области.
Например, область «title
» из предыдущего примера создает 4 неявных имени для линий (по 2 для каждой оси):
- Линия слева: «
title-start
» - Линия справа: «
title-end
» - Линия сверху: «
title-start
» - Линия снизу: «
title-end
»
Разместить элемент с помощью неявных имен можно по образцу следующего примера:
<div style="grid-column: main-start / aside-end; grid-row: title-start / nav-end;"></div>
Размещение элемента с помощью неявных имен от грид-области
Точно так же происходит и обратное действие. Если вы даете линиям имена с этими суффиксами, вы фактически создаете неявные области. Так что тот же самый грид можно создать с помощью именованных грид-линий:
<div style="display: grid; grid-template-columns: [title-start nav-start footer-start] 100px [main-start nav-end] 100px 100px 100px [aside-start title-end main-end] 100px [aside-end footer-end]; grid-template-rows: [title-start aside-start] 100px [nav-start main-start title-end] 100px 100px [footer-start nav-end main-end aside-end] 100px [footer-end];"> </div>
Все примеры размещения элементов из этого раздела в этом новом гриде разместятся в абсолютно тех же самых местах.
Неявный грид
Свойствами для задания грида (grid-template-columns
, grid-template-rows
и grid-template-areas
) мы определяем явное количество грид-полос (колонок и рядов) в нашем гриде. Однако спецификация гридов разрешает размещать элементы и вне явного грида. Ради поддержки этой возможности автоматически создаются неявные полосы, размер которых управляется свойствами grid-auto-columns
и grid-auto-rows
. В следующих примерах я буду выделять неявные линии красным цветом.
В этот раз возьмем простой грид 2×1:
<div style="display: grid; grid-template-columns: 200px 200px; grid-auto-columns: 100px;"> </div>
И представим, что мы размещаем элемент в 5-ю колонку (grid-column: 5;
). Поскольку у грида лишь 2 колонки, для размещения элемента будут добавлены еще 3 неявные.
Пример неявного грида
Опять же, можно создавать неяные полосы с элементами, охватывающими несколько ячеек. Например, если элемент занимает 3 колонки, начиная со второй (grid-column: 2 / span 3
):
Пример неявного грида с охватом нескольких ячеек
Изначально неявные полосы могли добавляться только с конца. Но теперь можно добавлять их и перед явным гридом. Например, если мы разместим элемент с помощью grid-column: -5;
, это добавит 2 колонки слева и элемент будет помещен в минус вторую колонку.
Пример неявного грида перед явным
Неявный грид и именованные грид-линии
Но это не единственный способ создания неявных полос, их также можно создавать, используя неопределенные именованные грид-линии. Это скорее способ указать на ошибку в чьем-то CSS, чем самостоятельный инструмент, но для кого-то и он может оказаться полезной. Идея в том, что все линии в неявном гриде могут подхватить любое случайное имя, которое вдруг понадобится вам для размещения элемента.
Этот простой пример размещает элементы, обращаясь к несуществующей линии с названием «foo
». Для примера мы создадим 3 неявных колонки (1 перед и 2 после явного грида) вот такими элементами:
<div style="grid-column: foo;"></div> <div style="grid-column: 2 / span 2 foo;"></div> <div style="grid-column: -1 foo;"></div>
Пример неявного грида с использованием неизвестных именованных грид-линий
Обратите внимание, что простейший пример с grid-column: foo
оказался в 4-й колонке (добавив лишнюю пустую колонку сразу после явного грида). Это потому, что первой линией с именем «foo
» считается первая неявная линия (линия 4), так что последняя линия грида (линия 3) сюда не включается.
Кроме того, последний элемент с grid-column: -1 foo
попал в минус первую колонку (возможно, неожиданно для вас). Это потому, что мы начинаем искать линию с именем «foo
» начиная от края явного грида. Таким образом, мы пропускаем линии -1, -2 и -3 (поскольку они явно не «foo
») и считаем, что это имя принадлежит линии -4 (первая линия неявного грида).
Всё несколько хитрее, если такая линия на самом деле есть, поскольку ее тоже нужно учесть при размещении элемента. Особенно сложно это в случае, если вы используете span до именованной линии, но линий не хватает. В этом случае только неявные линии с той стороны, в направлении которой мы их ищем, могут считаться линиями с искомым именем.
Опять же, надеюсь, это проще будет представить наглядно. Давайте добавим имя средней линии в предыдущем примере:
<div style="display: grid; grid-template-columns: 200px [middle] 200px; grid-auto-columns: 100px;"> </div>
А теперь разместим несколько элементов, обращаясь к этой линии “middle”:
<div style="grid-column: 3 middle;"></div> <div style="grid-column: span 2 middle / 5;>"</div> <div style="grid-column: -4 / span middle;"></div>
Пример неявного грида, использующего больше именованных линий, чем их фактически доступно
Странным случаем здесь оказывается grid-column: span 2 middle / 5;
, как видно, он занимает место от минус первой по 4-ю колонки (включительно). Элемент заканчивается на линии 5, и ему приходится захватить 2 линии с именем «middle
», чтобы найти начало. Может показаться, что это должны быть линии 2 и 4, но, как уже объяснялось, линии должны отсчитываться от края явного грида. Так что сначала мы посчитаем линию 2, а потом нам придется искать начало элемента среди неявных линий слева (в нашем случае это линия -4).
Особые случаи
Со свойствами размещения в гридах бывают особые ситуации, для которых предусмотрен раздел спецификации о разрешении конфликтов.
Например, если вы размещаете элемент, у которого линия конца находится перед линией начала, то эти линии меняются местами. То есть что-то вроде grid-column: 5 / 2;
превратится в grid-column: 2 / 5;
.
Другой случай — когда span
указан и для начальной, и для конечной позиции. Тогда span
для конечной позиции отбрасывается. Так, grid-column: span 2 / span 3;
превратится в grid-column: span 2;
. Что задействует алгоритм автоматического размещения, чтобы найти свободное место (в данном случае шириной в 2 колонки) и расположиться в нем.
Последний случай — когда у нас указан только span
до именованной линии. В этом случае он заменяется на span 1
. Например, grid-column: span foo;
превратится в grid-column: span 1;
.
Пример особых случаев размещения
Итого
Если вы дочитали аж досюда, должно быть, вам и вправду интересен CSS Grid Layout. Главный вывод — эта спецификация действительно гибка в отношении того, как размещать элементы в гриде. Как видите, есть немало разных способов поместить элемент в одно и то же место. Возможно, каждый из нас привыкнет к нескольким из них, а про остальные просто забудет.
По моему скромному мнению, самые основы (нумерация линий, охват ячеек, имена линий и областей) вполне интуитивны. И неявный грид тоже не так уж сложен. А с отрицательными индексами даже веселее. Но вот линии с неизвестным именем и вправду ведут себя хитро (надеюсь, что вам о них беспокоиться всё равно не придется). Но да, здесь я предвзят, поскольку я уже долго вожусь со всем этим.
Наконец, я решил, что неплохо будет закончить статью большим примером, в котором использована большая часть того, что в ней описано. Если вы сумели в нем разобраться и ничуть не запутались — значит, вы овладели секретом размещения элементов в грид-раскладке. Поздравляю! :)
Вот определение грид-контейнера, использованного в этом примере:
<div style="display: grid; grid-template-columns: [left] 200px [main-start] 100px [center] 100px 100px [main-end] 50px 50px [right]; grid-template-rows: [top title-start] 50px [title-end main-start] 200px [main-end center] 150px 100px [bottom]; grid-auto-columns: 50px; grid-auto-rows: 50px;"> </div>
А на следующей картинке видно, как разместятся разные элементы.
Большой пример размещения
Вы можете пощупать его «вживую» в нашем репзитории для примеров: http://igalia.github.io/css-grid-layout/grid-placement.html
Состояние дел
Как отмечено во вступлении, реализация в Blink сейчас (Chrome 50+) должна поддерживать все эти возможности размещения. Над этой реализацией работает Igalia, сейчас мы портируем ее и в WebKit тоже.
С другой стороны, у Gecko тоже уже есть их поддержка, которую разработала сама Mozilla.
Igalia и Bloomberg вместе работают над тем, чтобы сделать веб лучше
Наконец, как всегда я хочу еще раз подчеркнуть, что вся эта работа проделана в рамках сотрудничества между Igalia и Bloomberg. Большое спасибо за поддержку!
P.S. Это тоже может быть интересно:
Очень интересная статья, спасибо. Неявные гриды с автоименованием та еще головоломка =)
У меня вопрос по вот этому примеру из раздела «Именованные грид-линии»
http://css-live.ru/Primer/grids/example-named-grid-lines-items.svg
Не могу понять как у автора получилось, что 3й элемент расположился в нижнем ряду, ведь насколько я понимаю расположение элементов идет слева-направо сверху-вниз (если забыть про grid-auto-flow: dense, конечно) и в Chrome 48 я ожидаемо получил 3й элемент справа от 2го
https://jsfiddle.net/zzk4dfzf/
Я что-то упустил?
Спасибо за внимательность и отличный вопрос! Действительно, я тоже не вижу оснований для нового ряда, и в Фоксах (44-м с флагом и ночном 47-м) он тоже во втором ряду. Уточним у автора оригинала:)
Оказалось, что это действительно была ошибка автора. Еще раз спасибо за наблюдательность!
Исправили и перевод, и оригинал:)
Суперская статья, спасибо, многое теперь стало понятнее.
Объясните, пожалуйста, правило:
#item-7 { grid-column: span bar / 9; }
.Что такое
bar
? Я думал, что это название грид-линии, но линий с таким именем не задавалось.И еще вопрос по:
А именно:
Почему здесь написано так, а не, например, вот так:
То есть, я правильно понимаю, в первом случае алгоритм такой: «Мы размещаем элемент во 2й колонке, захватываем при этом 2 колонки, НО, если последняя линия, которая ограничивает элемент НЕ gap, то продолжаем охватывать ячейки дальше, пока gap не будет являться завершающей грид-линией для элемента»?
А в моем случае(вариант ниже): «Мы размещаем элемент во 2й колонке, захватываем при этом ВСЕ колонки, которые встреться перед грид-линией gap»?
P.S. Тут можно видеть, что Grid Layout развязывает руки и фантазию перед безграничным разнообразием вариантов решения одной и той же задачи, однако, хотелось бы прояснить ситуацию в деталях.
P.S.S. Одно дело, когда
grid-column-start, grid-row-start, etc
заменяют простымgrid-area
, это вопрос вкусовщины и, если хотите, читабельности, но в примерах выше, что я навел, мне кажется за вариациями воплощения одинаковых вещей кроются разные алгоритмы.<div>style="grid-column: col 2 / span 2 gap;"></div>
<div>style="grid-column: col 2 / span gap;"></div>
Разобрался с экранированием=)
Спасибо за хороший вопрос!)
По первому вопросу — насколько я сам понимаю, пример с
#item-7 { grid-column: span bar / 9; }
по сути аналогичен примеру сgrid-column: span 2 middle / 5
из статьи. Конец элемента фиксирован, а начало приходится искать среди неявных грид-линий (поскольку, как верно замечено, явной грид-линии с именемbar
нет). Здесь на ее роль годится первая неявная грид-линия слева (линия -8).По второму вопросу — достаточно близко: в первом случае (…
/ span 2 gap;
) мы захватываем ячейки по вторую линию с именемgap
(если линий с таким именем не хватает, в ход идут неявные линии после грида), а во втором (…/ span gap;
) — только по первую такую линию.Спасибо за ответ. Некоторые хитрости не совсем очевидны. Например.
<div style="grid-column: 3 middle;"></div>
<div style="grid-column: middle 3;"></div>
Поскорее бы Grid Layout вошел в обиход, даже на первый взгляд здесь нюансов чрезмерно много.
Читаю статью и постоянно перелистываю пытаясь понять синтаксис. Когда объясняются разные возможности, то после написания какого-то кода, во многих случаях, желательно писать как его читать «переводить на русский». С опытом это делается на автомате, а по началу приходится делать много лишней работы, потому что думаешь, «а как это понимать? так или эдак?» А без этого, всё дальнейшее объяснение усваивается не слишком продуктивно, где-то, конечно, можно догадаться, но вообще на догадках «здание» не построишь…
«есть немало разных способов поместить элМемент в одно и то же место» — очепятка.
Вообще, на мой скромный взгляд, разработчики, плавая в своей технологии, упускают один важный момент. Вроде автор прошёлся по всем основным моментам и по не-основным тоже :) Всё рассказал и проиллюстрировал. Лично у меня сложности возникли, когда я разбирал пример «Неявный грид и именованные грид-линии». Кто-то справедливо заметит: «если б ты читал текст ДО ЭТОГО внимательно, ты бы всё понял». Но ДО ЭТОГО всё понимал! Только НЕ ВСЁ ЗАПОМИНАЛ. Почувствуйте разницу! Поэтому когда происходит переход от простых, в чём-то даже элементарных примеров, в сложные, как раз очень важно ПОКАЗАТЬ, как эти простые примеры работают В СЛОЖНЫХ СИТУАЦИЯХ. Вот когда это начинаешь видеть, по-настоящему начинаешь понимать, как эта штука работает. А до этого, просто знакомишься с возможностями, и не более того.
Кроме этого, я считаю, что очень важно было упомянуть в статье, что свойства grid-auto-columns и *rows, по-умолчанию, равны нулю. Вроде мелочь, но поскольку очень многое, из дальнейшего изложения, строится из этих свойств, то упомянуть, что их, вообще-говоря, нужно задать — важно. Разработчику, в этом плавающему, это может показаться самим собой разумеющимся, но новичку, у которого итак обилие информации, отследить подобные мелочи, порой, довольно сложно…
Ну а теперь после чтения нотаций… Хотел бы задать вопрос :-) Я, вроде, думал, что со всем разобрался, но когда начал, как раз, писать своё понимание сложных, с моей точки зрения, примеров, то сразу же обнаружил момент, который я не понимаю.
Вот пример из статьи:
div style=»grid-column: foo;» — пробую его проинтерпретировать, как можно более подробно:
Поскольку указана только стартовая линия, то горизонтальный размер, проставляется auto, а это, по-умолчанию, одна полоса, ищем линию foo начиная с начала (левого края) явно заданного грида, не находим, идём в неявную область, через промежуток grid-auto-columns находим или «автоопределяем» линию, назначаем ей название foo (у неё могут быть несколько названий), это начало грид элемента по-горизонтали. По-умолчанию, как я уже говорил, грид-элемент длится до следующей линии, если её нет(что, в принципе, не мудрено, поскольку мы уже вышли за пределы явной области), то через заданный промежуток grid-auto-columns мы «автоопределяем» ещё одну линию, на которой элемент заканчивается. Вот как бы такое простое объяснение.
Но тут есть одно «умолчание»: когда мы «уходим» в неявную область, и назначаем, через заданный свойством grid-auto-columns промежуток новую линию и даём ей заданное нам наименование, насколько это линия «первая попавшаяся»? В данном случае у нас не было других линий, а если б у нас УЖЕ БЫЛА линия foo, которая была назначена, другим гридом ушедшим в неявную область, чтобы было тогда?…
Элемент назначил бы первой линии название foo? Или потянулся бы за уже существующей (пусть и не явно) линией foo и начинался бы уже с неё? (понятно, что линий foo, в данном примере, в явных областях нет). То есть, насколько неявно-заданные линии, работают для других грид-элементов?
То, что начинают искать они линии, ВСЕГДА с явной области, даже если край элемента лежит в не явной, и между началом элемента и краем явной грид-области, лежит линия с искомым названием, то она игнорируется и поиск начинается с явной области, об этом сказано в статье. Но тут другая ситуация — обе возможные линии находятся в неявной зоне. Сольются они в одну или начнут плодить сущности? :-)
Спасибо за хороший вопрос! На мой взгляд, если уже есть одна неявная линия foo, по логике надо бы всегда использовать ее в качестве первой линии foo, когда это возможно. И только если использовать существующую уже никак нельзя, создавать новые. Пример https://jsfiddle.net/hgn76o2t/1/ вроде бы это подтверждает — новые линии foo заводятся для двух последних элементов на 3 строке и для самого нижнего элемента.
Благодарю за интересный пример! В нём, кстати, кроме рассматриваемой темы, много поучительных моментов, например использование атрибутов…
Илья, а у «виртуальных линий» вообще есть шанс? :-) Вот смотрите, в последнем грид-элементе меняю foo на bar — ничего не меняется. Вроде, понятно, почему, ну взял грид-элемент и назвал эти линии по-своему, имел право… Но может ли оказаться первая неявная линия bar не первой линией после явной, а, например, второй?
То есть, bar c номером один, находится на вертикальной линии… ну допустим четвёртой? (или пятой, или шестой — не суть) Главное что не третьей, которая, первая виртуальная(неявная) линия. Я вот что-то прикинул и не очень понимаю, как такое вообще может быть. Так всё-таки, может такое быть или нет? Потому что, если не может, то, вероятно, мой первый вопрос, лишён всякого смысла…
Я тоже долго ломал голову, но так и не смог придумать ситуации, где такое могло бы быть. Видимо, не может.
Линии ничто не мешает одновременно быть и foo, и bar — количество имен для линий, и в явном, и в неявном гриде, не ограничено. Так что если другой элемент дал этой линии другое неявное имя, это не значит, будто линия «уже занята». Запрещено, как я понимаю, только давать неявные имена явным линиям (не считая -start и -end для границ именованных грид-областей).
» Запрещено, как я понимаю, только давать неявные имена явным линиям» — не понял, это как?..
Имел в виду, что все эти «линии foo» ищутся только в неявном гриде, линии явного грида (если среди них не было foo) алгоритм игнорирует. Признаю, выразился неудачно)
Ну он сначала «смотрит» есть ли foo среди явных, а потом уходит в неявные. Ну да, явным линиям, грид-элемент, таким образом, ничего не назначит(не считая -start и -end для границ именованных грид-областей).
Полностью согласен (я не мог сам настолько точно сформулировать:).
И потом, если из Вашего примера удалить всё, оставить только пример где «foo меньше чем 4», то для этого грид-элемента, по-сути(то есть если не считать левых столбцов, которые этот элемент не затрагивают), ничего не изменится: foo так и будет идти раньше чем 4. То есть, не смотря на то, что, 4 — это старт, всё равно, по-видимому, алгоритм размещения, в данном случае, такой: ищем foo начиная с левого края явной области (вне зависимости где 4, главное, что она задана положительным образом, что говорит, по-видимому, о НАПРАВЛЕНИИ поиска), если не находим, идём дальше в том же направлении, первую попавшуюся линию называем foo и считаем что это искомая точка по-горизонтали(а если мы идём по вертикали, значит по-вертикали). А после этого уже, увидев что foo раньше чем 4, «меняем направление», то есть начало и конец меняются местами, как это сказано в статье(впрочем я раньше думал, что называть от большего к меньшему — это тоже способ, в грядках это преподносится именно так. Но разработчик говорит, что это, скорее, исправленный баг).
Характерно тут то, что в неявной области, у линии foo(или иной названной), похоже, не шансов разместится на второй линии, если нет foo на первой.
Я понимаю этот алгоритм точно так же!)
Спасибо за совместный мозговой штурм! :)
А пока приведу свои интерпритации остальных примеров, вдруг кому-то пригодятся или может кто-нибудь меня поправит, укажет на какие-то нюансы…
div style=»grid-column: 2 / span 2 foo — элемент начинается от линии два и длится до второй линии foo после начала элемента.
div style=»grid-column: -1 foo; — элемент начинается от первой линии foo идущей от правого края элемента, если такой линии не обнаружено, то она будет создана в неявной области и длится один промежуток, длина которого, определится свойством grid-auto-columns (в этом пример возможен тот же вопрос, что и был задан в сообщении выше)
div style=»grid-column: 3 middle;» — элемент длится от третьей линии middle, отсчёт middle ведётся из явной области, в которой есть одна линия с таким названием, значит элемент начинается со второй «виртуальной» middle и длится один промежуток, длина которого, определится свойством grid-auto-columns (в этом пример возможен тот же вопрос, что и был задан в сообщении выше, наверное, в данном пример, он будет звучать так: возможно ли, чтоб между двумя middle была третья линия не-middle?)
div style=»grid-column: span 2 middle / 5;» — элемент длится до линии 5 (при этом если, скажем, последняя линия в явной области — три, то, в случае цифрового наименования, сначала будет 4я линия, потом 5я), и до этой линии нужно найти две такие линии начиная с правого края явной зоны (потому что 5 лежит правее правого края явной зоны). Тот же middle, который лежит «раньше» между концом элемента (5) и началом явной зоны, попросту отбрасывается (в статье этот момент хорошо объясняется).
div style=»grid-column: -4 / span middle;» — начинается с 4ой линии правее крайней правой в явной зоне и длится до первой встретившейся middle в явной зоне, если же он её там не встретит, то пойдёт по тому же направлению искать в не явной…
Вот такие интерпритации, разобравшись с которыми понять примеры из «примера для самостоятельного изучения» не составило большого труда… Вообще статья классная! По крайней мере, после её прочтения понимания в указанном свойстве стало больше, спасибо автору и переводчикам!
Опечатка исправлена, спасибо!
Добрый день! Я только учусь всему и делаю для себя Пэт проект и появился вопрос. Смотрите, есть цикл for, который выводит картинки из массива в сетку grid, и делает он это начиная с левой верхней клетки и движется вправо и вниз, а мне нужно, чтобы вывод начинался с правой нижней и шел вверх, получается — справа на лево и снизу вверх одновременно поэлементно, т.е. каждый последующий элемент массива выводился левее предыдущего и когда упирался в левую границу grid, то следующий элемент появился выше на ряд, получается в ячейке над ячейкой с которой начался вывод и так дальше. Не могу сам придумать как так сделать и решение в интернете никак не найду, а тут вроде люди разбирающиеся, вдруг помогут:))
Подскажите, пожалуйста, как такое реализовать или ткните носом, где можно об этом почитать. Спасибо!
Как вариант, раз картинки выводятся циклом, можно этим же циклом проставить им свойство order по убыванию (у первого — равное кол-ву картинок, у второго — на единицу меньше, и так до последнего с единицей). Еще можно «отзеркалить» всю сетку по обеим осям сразу с помощью scale: -1 для контейнера, а картинки перевернуть этим же scale: -1 еще раз — тогда визуально как раз получится, что они стоят прямо, но в обратном порядке. Но вообще с любым неочевидным порядком элементов нужна осторожность, он часто мешает доступности.