Статьи

Пошаговое руководство по алгоритму автоматического размещения в CSS Grid

Алгоритм автоматического размещения в модуле CSS Grid Layout

В этом уроке я расскажу обо всех шагах, которые выполняет алгоритм автоматического размещения модуля CSS Grid Layout при позиционировании элементов. Эти шаги контролируются свойством grid-auto-flow .

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

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

Основные понятия для лучшего понимания алгоритма автоматического размещения

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

  • Анонимные элементы сетки — если вы поместите некоторый текст непосредственно в контейнер сетки, не заключая его в какой-либо тег, он сформирует свой собственный элемент анонимной сетки. Вы не можете стилизовать анонимный элемент сетки, потому что нет элемента для стилизации, но он все еще наследует правила стиля из своего родительского контейнера. С другой стороны, обратите внимание, что пустое пространство внутри контейнера сетки не будет создавать свой собственный анонимный элемент сетки
  • Значение промежутков сетки — в отличие от позиций сетки, алгоритм не имеет специальных правил для определения значения промежутков сетки. Если явно не указано, их значение устанавливается равным 1 (элемент занимает только свою собственную ячейку)
  • Неявная сетка . Сетка, построенная на основе значений свойств, таких как grid-template-columns , grid-template-columns и grid-template-areas , называется явной сеткой . Теперь, если вы укажете положение элемента сетки таким образом, чтобы он находился за пределами явной сетки, браузер сгенерирует дополнительные линии сетки для размещения элемента. Эти линии вместе с явной сеткой образуют неявную сетку. Подробнее об этом вы можете прочитать в разделе «Где все находится» в рабочем проекте макета CSS . Алгоритм автоматического размещения может также привести к созданию дополнительных строк или столбцов в неявной сетке.

Наконец, я хотел бы сделать следующее предварительное замечание. Значением по умолчанию свойства grid-auto-flow , которое является свойством, управляющим алгоритмом, является row . Это также значение, которое я собираюсь принять в следующем объяснении алгоритма автоматического размещения. С другой стороны, если вы явно устанавливаете указанное выше свойство в column , не забудьте заменить экземпляры строки термина на термин столбца в моем объяснении алгоритма. Например, шаг «Размещение элементов с заданной позицией строки, но без заданной позиции столбца» станет «Размещение элементов с заданной позицией столбца, но без установленной позиции строки».

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

Шаг № 1: Генерация анонимных элементов сетки

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

Разметка ниже генерирует анонимный элемент сетки из межэлементного текста:

 <div class="container"> <span class="nonan">1</span> Anonymous Item <div class="nonan floating">2</div> <div class="nonan">3</div> <div class="nonan floating">4</div> <div class="nonan">5</div> </div> 

Помимо создания анонимного элемента, еще одна вещь, которую следует отметить в демонстрации ниже, — это то, что алгоритм размещения сетки игнорирует CSS-плавающие элементы, применяемые к div 2 и div 4 .

Шаг № 2: Размещение элементов с явно указанной позицией

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

Вот соответствующая разметка:

 <div class="container"> <div class="item a">A</div> <div class="item b">B</div> <div class="item c">C</div> <div class="item d">D</div> <div class="item e">E</div> <div class="item f">F</div> <div class="item f">G</div> <div class="item f">H</div> <div class="item f">I</div> </div> 

Первые элементы, которые должны быть размещены в сетке, это те, которые имеют явно установленную позицию , а в приведенном ниже примере это элементы A и B. Просто пока игнорируйте все остальные элементы в сетке. Вот CSS, который явно устанавливает положение A и B:

 .a { grid-area: 1 / 2 / 2 / 3; } .b { grid-area: 2 / 1 / 4 / 3; } 

Элементы алгоритма автоматического размещения CSS Grid с явным расположением строк и столбцов: A и B

Алгоритм позиционирует элементы A и B в соответствии со значениями их соответствующего свойства grid-area . В частности, алгоритм:

  • Устанавливает положение верхнего левого угла как A, так и B, используя первое и второе значение свойства grid-area
  • Устанавливает положение нижнего правого угла как A, так и B, используя третье и четвертое значение свойства grid-area .

Демонстрация ниже иллюстрирует окончательное размещение A и B после этого шага:

Шаг № 3: размещение элементов с заданным положением строки, но без заданного положения столбца

Затем алгоритм размещает элементы, чья позиция строки была установлена ​​явно , используя свойства grid-row-start и grid-row-end .

Для этого примера я буду устанавливать только значения строки сетки элемента C и элемента D, чтобы дать им определенную позицию строки. Вот CSS для размещения их обоих:

 .c { grid-row-start: 1; grid-row-end: 3; } .d { grid-row-start: 1; grid-row-end: 2; } 

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

  • редкая упаковка (по умолчанию)
  • плотная упаковка

Разреженная упаковка на шаге № 3

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

Алгоритм автоматического размещения CSS Grid: элементы с заданной строкой, но без заданной позиции столбца: C и D

Чтобы прояснить этот момент далее, элемент D в демонстрационном примере ниже не сдвинулся слева от элемента A, даже если он мог поместиться там без какого-либо наложения. Это связано с тем, что алгоритм не позволяет размещать какой- либо элемент с явно установленной позицией строки, но не устанавливает позицию столбца перед любым другим аналогично позиционированным элементом в этой конкретной строке (элемент C в данном случае). Фактически, если вы удалите правила строк сетки, примененные к элементу C, элемент D переместится влево от элемента A.

Короче говоря, элемент D, который имеет определенную позицию строки, но не имеет явно установленной позиции столбца, может в конечном итоге быть помещен перед элементом A, но только если C не вмешивается (в этом случае возникают помехи, поскольку C, как и D, имеет определенная позиция строки, но не заданная позиция столбца и находится в той же строке, что и D).

Плотная упаковка на шаге № 3

Если вы хотите заполнить это пустое пространство перед элементом A элементом D, вам нужно будет установить значение свойства grid-auto-flow на row dense .

 .container { grid-auto-flow: row dense; } 

Алгоритм автоматического размещения CSS Grid: размещение элементов C и D на шаге 3 в режиме плотной упаковки

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

Шаг № 4: Определение количества столбцов в неявной сетке

Затем алгоритм пытается определить количество столбцов в неявной сетке. Это делается, выполнив ряд шагов:

  • Алгоритм начинается с количества столбцов в явной сетке.
  • Затем он проходит через все элементы сетки с определенной позицией столбца и добавляет столбцы в начало и конец неявной сетки для размещения всех этих элементов.
  • Наконец, он проходит через все элементы сетки без определенной позиции столбца. Если самый большой диапазон столбцов среди этих элементов превышает ширину неявной сетки, он добавляет столбцы в конце сетки для размещения этого диапазона столбцов.

Шаг № 5: Размещение оставшихся предметов

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

Прежде чем мы углубимся в подробности, вы должны знать о термине « курсор автоматического размещения» . Он определяет текущую точку вставки в сетку, указанную в виде пары строк сетки и столбцов. Для начала, курсор автоматического размещения размещается в самой начальной строке и столбце в неявной сетке.

Еще раз, режим упаковки, определяемый значением свойства grid-auto-flow , контролирует расположение этих элементов.

Разреженная упаковка на шаге № 5

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

Если элемент не имеет определенной позиции по какой-либо оси:

  • Алгоритм увеличивает позицию столбца курсора до:
    а) либо нет перекрытия между уже размещенными предметами и текущим предметом
    б) или позиция столбца курсора плюс диапазон столбцов элемента переполняют количество столбцов в неявной сетке.
  • Если такая непересекающаяся позиция найдена, алгоритм устанавливает значения начала row-start элемента и row-start column-start для текущей позиции курсора. В противном случае он увеличивает позицию строки на 1, устанавливает для column-start самой начальной строки в неявной сетке и повторяет предыдущий шаг.

Если элемент имеет определенную позицию в столбце:

  • Положение столбца курсора автоматического размещения устанавливается на column-start строку column-start элемента. Если значение этой новой позиции меньше позиции предыдущего столбца курсора, позиция строки увеличивается на единицу.
  • Затем положение строки увеличивается на единицу, пока алгоритм не достигнет значения, при котором элемент сетки не перекрывается ни с одной из занятых ячеек сетки. При необходимости дополнительные строки могут быть добавлены в неявную сетку. Теперь начальная строка строки элемента установлена ​​в положение курсора, а конечная строка строки элемента — в соответствии с его диапазоном.

Давайте поясним шаги, перечисленные выше, с тем, что происходит в следующей демонстрации.

Алгоритм автоматического размещения CSS Grid: размещение E, F, G и H с режимом разреженной упаковки по умолчанию

Размещение предметов E и F без определенной позиции в любой из осей

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

Следующий элемент без явно установленной позиции столбца или строки — F. В этот момент позиция столбца для курсора автоматического размещения увеличивается до 2. Однако строка позиции 1 / столбец 2 уже занята элементом A. Это означает, что алгоритм должен будет продолжать увеличивать позицию столбца. Это продолжается до тех пор, пока курсор автоматического размещения не достигнет столбца 4. Поскольку столбцов больше нет, положение строки для курсора автоматического размещения увеличивается на 1, а положение столбца устанавливается на 1. Теперь положение строки равно 2, а позиция столбца равна 1. Алгоритм снова начинает увеличивать позицию столбца на 1, пока не достигнет столбца 4. Пробел в строке 2 и столбце 4 в настоящее время пуст и может быть занят элементом F. Алгоритм помещает элемент F туда и переходит к следующему элементу.

Размещение элементов G и H с определенной позицией столбца

Остальные элементы с определенной позицией столбца в нашей демонстрации — это G и H. Давайте рассмотрим G. Положение столбца курсора автоматического размещения устанавливается равным значению свойства grid-column-start для элемента G, которое равно 3. Поскольку это новое значение меньше, чем предыдущее значение столбца (которое было 4), положение строки увеличивается на единицу. Текущие позиции строки и столбца теперь 3 и 3 соответственно. Пространство в строке 3 и столбце 3 в настоящее время пусто, и элемент G можно разместить там без какого-либо перекрытия. Поэтому алгоритм размещает там элемент G. Затем те же шаги повторяются для размещения элемента H.

Плотная упаковка на шаге № 5

Вещи обрабатываются немного по-другому, когда свойство grid-auto-flow установлено в row dense . При размещении элемента сетки без определенной позиции текущая позиция курсора устанавливается на самую начальную строку и строку столбца в неявной сетке до того, как будет определена позиция элемента.

Алгоритм автоматического размещения CSS Grid: размещение оставшихся элементов на шаге 5 в режиме плотной упаковки

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

Вывод

В этой статье я рассмотрел все этапы алгоритма автоматического размещения модуля CSS Grid Layout, контролируемого свойством grid-auto-flow .

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

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