Spec-Zone.ru › CSS

Использование позиционирования CSS якоря

Модуль позиционирования CSS якоря определяет возможности привязки элементов друг к другу. Элементы могут быть определены как элементы якоря и элементы с позиционированием по якорю. Элементы с позиционированием по якорю могут быть связаны с элементами якоря. Затем размер и положение элементов с позиционированием по якорю могут быть установлены относительно размера и местоположения элементов якоря, к которым они привязаны.

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

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

Основные концепции

Очень часто требуется привязать или объединить один элемент к другому. Например:

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

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

Местоположение элементов с позиционированием относительно элемента якоря должно поддерживаться и корректироваться по мере перемещения или изменения конфигурации элемента якоря (например, при прокрутке, изменении размера области просмотра, перетаскивании и т. д.). Например, если элемент, такой как поле формы, приближается к краю области просмотра, его подсказка может оказаться вне экрана. Как правило, вы хотите привязать подсказку к полю формы и убедиться, что подсказка полностью видна на экране, пока поле формы видно, автоматически перемещая подсказку при необходимости. Вы могли заметить такое поведение по умолчанию в своей операционной системе, когда вы нажимаете правую кнопку мыши (Ctrl + щелчок) контекстные меню на своём рабочем столе или ноутбуке.

Исторически для объединения элемента с другим элементом и динамического изменения местоположения и размера элемента с позиционированием на основе положения якоря требовался JavaScript, что добавляло сложность и проблемы с производительностью. Также не было гарантии, что это будет работать во всех ситуациях. Функции, определённые в модуле позиционирования CSS якоря, позволяют реализовывать такие случаи использования производительно и декларативно с помощью CSS (и HTML) вместо JavaScript.

Объединение элементов якоря и элементов с позиционированием

Для объединения элемента с якорем необходимо сначала объявить, какой элемент является якорем, а затем указать, какой(ие) элемент(ы) с позиционированием следует объединить с этим якорем. Это можно сделать с помощью CSS или атрибута HTML anchor.

Метод только с CSS

Для объявления элемента как якоря с помощью CSS необходимо установить имя якоря на нём с помощью свойства anchor-name. Имя якоря должно быть <dashed-ident>. В этом примере мы также устанавливаем width якоря на fit-content, чтобы получить небольшой квадратный якорь, который лучше демонстрирует эффект привязки.

.anchor {
  anchor-name: --myAnchor;
  width: fit-content;
}

Для преобразования элемента в элемент с позиционированием по якорю требуются два шага: необходимо установить абсолютное или фиксированное позиционирование с помощью свойства position. Затем нужно установить свойство position-anchor элемента с позиционированием на значение свойства anchor-name элемента якоря, чтобы объединить их:

.infobox {
  position: fixed;
  position-anchor: --myAnchor;
}

Мы применим указанный выше CSS к следующему HTML:

<div class="anchor">⚓︎</div>

<div class="infobox">
  <p>This is an information box.</p>
</div>

Это будет отображаться следующим образом:

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

Метод HTML

Для объединения элемента с позиционированием с якорем в HTML можно использовать атрибут anchor. Необходимо задать id элементу якоря. Атрибут anchor устанавливается затем на элементе с позиционированием, со значением, равным id элемента якоря, с которым вы хотите его объединить.

Мы сделали это в HTML ниже:

<div class="anchor" id="example-anchor">⚓︎</div>

<div class="infobox" anchor="example-anchor">
  <p>This is an information box.</p>
</div>

Для объединения элементов необходимо установить абсолютное или фиксированное позиционирование, поэтому мы задаём для информационной подсказки значение position равное fixed:

.infobox {
  position: fixed;
}

Это даёт тот же результат, что и ранее с помощью CSS. Мы объединили элемент с позиционированием с элементом якоря, используя атрибут anchor на элементе с позиционированием, а не свойство anchor-name элемента якоря и свойство position-anchor элемента с позиционированием.

Примечание: Атрибут anchor в настоящее время поддерживается менее активно, чем его CSS-аналог. Смотрите таблицу совместимости атрибута anchor для получения дополнительной информации.

Мы объединили два элемента, но они ещё не привязаны. Для привязки элемента с позиционированием к якорю требуется позиционирование элемента с позиционированием относительно якоря, что выполняется с помощью CSS.

Позиционирование элементов относительно их якоря

Как мы видели выше, объединение элемента с позиционированием с якорем само по себе мало чем помогает. Наша цель — разместить элемент с позиционированием относительно связанного с ним элемента якоря. Это делается либо путём установки значения функции CSS anchor() на свойстве отступа, указанием position-area или центрированием элемента с позиционированием с помощью значения размещения anchor-center.

Примечание: Элемент якоря должен быть видимым узлом DOM для функционирования объединения и позиционирования. Если он скрыт (например, с помощью display: none), элемент с позиционированием по якорю будет позиционироваться относительно ближайшего предка с позиционированием. Мы обсудим, как скрыть элемент с позиционированием по якорю, когда его якорь исчезает, в разделе Условное скрытие с помощью position-visibility.

END_OF_DOCUMENT_MARKER

Использование свойств inset со значениями функции anchor()

Обычные элементы с абсолютным и фиксированным позиционированием явно позиционируются путем задания значений <length> или <percentage> для свойств inset. С помощью position: absolute, это значение inset представляет собой абсолютное расстояние относительно краев ближайшего позиционированного предка. С помощью position: fixed, значение inset — это абсолютное расстояние относительно области просмотра.

Позиционирование CSS по якорю изменяет эту парадигму, позволяя элементам, позиционированным по якорю, размещаться относительно краев связанного якоря (или якорей). Модуль определяет функцию anchor(), которая является допустимым значением для каждого из свойств inset. При использовании функция устанавливает значение inset как абсолютное расстояние относительно элемента якоря, определяя элемент якоря, сторону элемента якоря, относительно которой позиционируется элемент, и расстояние от этой стороны.

Компоненты функции выглядят так:

anchor(<anchor-name> <anchor-side>, <fallback>)
<anchor-name>

Значение свойства anchor-name элемента якоря, относительно которого вы хотите позиционировать сторону элемента. Это значение <dashed-ident>. Если значение опущено, используется стандартный якорь элемента. Это якорь, указанный в свойстве position-anchor, или связанный с элементом посредством атрибута HTML anchor.

Примечание: Указание <anchor-name> позиционирует элемент относительно этого якоря, но не обеспечивает связь элементов. Только свойство position-anchor и атрибуты anchor создают эту связь. Хотя вы можете позиционировать стороны элемента относительно нескольких якорей, указав различные значения <anchor-name> внутри разных функций anchor() для одного и того же элемента, позиционируемый элемент связан только с одним якорем.

<anchor-side>

Определяет положение относительно стороны (или сторон) якоря. Допустимые значения включают стороны якоря, физические (top, left, и т.д.) или логические (start, self-end, и т.д.) стороны якоря, или <percentage> между началом (0%) и концом (100%) оси свойства inset, на котором установлено значение anchor(). Если используется значение, которое не совместимо со свойством inset, для которого установлена функция anchor(), используется значение по умолчанию.

<fallback>

<length-percentage>, определяющий расстояние для использования в качестве значения по умолчанию, если элемент не имеет абсолютного или фиксированного позиционирования, если значение <anchor-side> несовместимо со свойством inset, для которого задана функция anchor(), или если элемент якоря не существует.

Возвращаемое значение функции anchor() — это значение длины, рассчитанное на основе положения якоря. Если вы задаёте длину или процент непосредственно в свойстве inset элемента, позиционированного по якорю, он позиционируется так, как если бы не был связан с элементом якоря. Это то же поведение, которое наблюдается, если значение <anchor-side> несовместимо со свойством inset, для которого оно задано, и используется значение по умолчанию. Эти два объявления эквивалентны:

bottom: anchor(right, 50px);
bottom: 50px;

Оба случая поместят позиционированный элемент 50px выше нижнего края ближайшего позиционированного предка элемента (если таковой имеется) или начального контейнера.

Наиболее часто используемые параметры anchor() будут относиться к стороне стандартного якоря. Вы также часто будете либо добавлять margin для создания отступа между краем якоря и позиционированным элементом, либо использовать anchor() в функции calc() для добавления этого отступа.

Например, это правило позиционирует правый край позиционированного элемента вплотную к левому краю элемента якоря, а затем добавляет некоторый margin-left для создания промежутка между краями:

.positionedElement {
  right: anchor(left);
  margin-left: 10px;
}

Возвращаемое значение функции anchor() — это значение длины. Это означает, что вы можете использовать его в функции calc(). Это правило позиционирует логический край блока позиционированного элемента на 10px от логического края старта блока элемента якоря, добавляя отступ с помощью функции calc() для того, чтобы не использовать margin:

.positionedElement {
  inset-block-end: calc(anchor(start) + 10px);
}

anchor() пример

Давайте посмотрим на пример использования anchor() в действии. Мы использовали тот же HTML, что и в предыдущих примерах, но добавили текст для заполнения, помещенный под и над ним, чтобы вызвать переполнение содержимого контейнера и прокрутку. Мы также зададим элементу якоря то же значение anchor-name , что и в предыдущих примерах:

.anchor {
  anchor-name: --myAnchor;
}

Информационный блок связан с якорем по имени якоря и имеет фиксированное позиционирование. Включив свойства inset-block-start и inset-inline-start (которые эквивалентны top и left в горизонтальных режимах письма слева направо), мы привязали его к якорю. Мы добавили margin к информационному блоку, чтобы добавить отступ между позиционированным элементом и его якорем:

.infobox {
  position-anchor: --myAnchor;
  position: fixed;
  inset-block-start: anchor(end);
  inset-inline-start: anchor(self-end);
  margin: 5px 0 0 5px;
}

Давайте подробнее рассмотрим объявления позиционирования свойства inset:

  • inset-block-start: anchor(end): Это устанавливает начальный край блока позиционированного элемента в край конца блока якоря, рассчитанный с помощью функции anchor(end).
  • inset-inline-start: anchor(self-end): Это устанавливает начальный край строки позиционированного элемента в край конца строки якоря, рассчитанный с помощью функции anchor(self-end).

Это даёт нам следующий результат:

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

END_OF_DOCUMENT_MARKER

Установка позиции position-area

Свойство position-area предоставляет альтернативу функции anchor() для позиционирования элементов относительно якорей. Свойство position-area работает с концепцией 3x3 сетки плиток, где элемент якоря является центральной плиткой. Свойство position-area может использоваться для позиционирования элемента, связанного с якорем, в любой из девяти плиток или для его разнесения на две или три плитки.

The position-area grid, as described below

Плитки сетки разбиты на строки и столбцы:

  • Три строки представлены физическими значениями top, center, и bottom. У них также есть логические эквиваленты, такие как start, center, и end, и координатные эквиваленты, такие как y-start, center, и y-end.
  • Три столбца представлены физическими значениями left, center, и right. У них также есть логические эквиваленты, такие как start, center, и end, и координатные эквиваленты, такие как x-start, center, и x-end.

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

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

Например:

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

  • top left (логический эквивалент start start) разместит позиционируемый элемент в левом верхнем углу.
  • bottom center (логический эквивалент end center) разместит позиционируемый элемент в нижнем центральном квадрате.

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

  • top span-left размещает позиционируемый элемент в верхней строке и разносит его по центральной и левой плитке этой строки.
  • y-end span-x-end размещает позиционируемый элемент в конце столбца y и разносит его по центральной и правой плитке этого столбца.
  • block-end span-all размещает позиционируемый элемент в конечной строке блока и разносит его по плиткам «начало строки», «центр» и «конец строки» этой строки.

Если задано только одно значение, эффект отличается в зависимости от установленного значения:

  • Физическое значение стороны (top, bottom, left, или right) или координатное значение (y-start, y-end, x-start, или x-end) действует так, как будто другое значение равно span-all. Например, top даёт тот же эффект, что и top span-all.
  • Логическое значение стороны (start или end). Действует так, как будто другое значение установлено в то же значение; например, start даёт тот же эффект, что и start start.
  • Значение center действует так, как будто оба значения установлены в center (так, center center).

Примечание: См. страницу справки по значению <position-area> для подробного описания всех доступных значений. Смешивание логического значения с физическим значением сделает объявление недействительным.

Давайте продемонстрируем некоторые из этих значений; этот пример использует тот же HTML и базовые стили CSS, что и предыдущий пример, за исключением того, что мы добавили элемент <select> для изменения значения position-area позиционируемого элемента.

Информационной панели задано фиксированное позиционирование и она связана с якорем с помощью CSS. При загрузке она привязана к якорю значением position-area: top;, что размещает ее в верхней части сетки области позиционирования. Это значение будет переопределено после выбора других значений в меню <select>.

.infobox {
  position: fixed;
  position-anchor: --myAnchor;
  position-area: top;
}

Мы также включили короткий скрипт для применения новых значений position-area, выбранных из меню <select> для информационной панели:

const infobox = document.querySelector(".infobox");
const selectElem = document.querySelector("select");

selectElem.addEventListener("change", () => {
  const area = selectElem.value;

  // Set the position-area to the value chosen in the select box
  infobox.style.positionArea = area;
});

Попробуйте выбрать новые значения position-area из меню <select> для наблюдения за их влиянием на позицию информационной панели:

Ширина позиционируемого элемента

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

Когда позиционируемый элемент помещается в ячейки сетки position-area без явного задания размеров, он выравнивается с указанной областью сетки и ведет себя так, как если бы width был установлен на max-content. Его размер определяется размером его блока размещения, который равен ширине его содержимого. Этот размер был задан установкой position: fixed. Автоматически размеренные элементы с абсолютным и фиксированным позиционированием автоматически масштабируются, расширяясь до необходимой ширины для размещения текстового содержимого, но ограниченные границей области просмотра. В этом случае, при размещении слева в сетке с любым значением left или inline-start, текст переносится на следующую строку. Если размер позиционируемого элемента уже меньше или короче, чем размер якоря, они не будут масштабироваться, чтобы соответствовать размеру якоря.

Если позиционируемый элемент центрирован по вертикали, например, с position-area: bottom center, он выравнивается с указанной ячейкой сетки, а ширина будет такой же, как у элемента якоря. В этом случае минимальная высота будет равна размеру блока размещения элемента якоря. Он не будет выходить за пределы, так как min-width равен min-content, что означает, что он будет как минимум такой ширины, как самое длинное слово.

Центрирование на якоре с помощью anchor-center

Хотя вы можете центрировать элемент, привязанный к якорю, с помощью значений position-area's center, свойства вставки в сочетании с функцией anchor() обеспечивают больший контроль над точным расположением. Позиционирование по якорю в CSS предоставляет способ центрирования элемента, привязанного к якорю, относительно своего якоря, когда свойства вставки, а не position-area, используются для привязки.

Свойства justify-self, align-self, justify-items, и align-items (и их сокращения place-items и place-self) существуют, чтобы разработчики могли легко выравнивать элементы в строчном или блочном направлении внутри различных систем макета, например, вдоль основной или поперечной оси в случае дочерних элементов flex. CSS-позиционирование по якорю предоставляет дополнительное значение для этих свойств, anchor-center, которое выравнивает позиционируемый элемент по центру его стандартного якоря.

В этом примере используется тот же HTML и базовые CSS, что и в предыдущем примере. Информационной панели задано фиксированное позиционирование и она привязана к нижнему краю якоря. Затем justify-self: anchor-center используется для обеспечения горизонтального центрирования на центральной оси якоря:

.infobox {
  position: fixed;
  position-anchor: --myAnchor;
  top: calc(anchor(bottom) + 5px);
  justify-self: anchor-center;
}

Это центрирует элемент, привязанный к якорю, внизу его якоря:

END_OF_DOCUMENT_MARKER

Изменение размера элементов на основе размера якоря

Помимо позиционирования элемента относительно позиции его якоря, вы также можете изменять размер элемента относительно размера его якоря, используя функцию anchor-size() в значении свойства размера.

Свойства размера, которые могут принимать значение anchor-size(), включают:

  • width
  • height
  • min-width
  • min-height
  • max-width
  • max-height
  • block-size
  • inline-size
  • min-block-size
  • min-inline-size
  • max-block-size
  • max-inline-size

Функции anchor-size() преобразуются в значения <length>. Их синтаксис выглядит следующим образом:

anchor-size(<anchor-name> <anchor-size>, <length-percentage>)
<anchor-name>

Имя якоря, заданное как значение свойства anchor-name элемента якоря, относительно которого вы хотите изменить размер элемента. Если опущено, используется стандартный якорь элемента, который указан в свойстве position-anchor.

<anchor-size>

Указывает размер элемента якоря, относительно которого будет изменён размер позиционированного элемента. Это может быть выражено с использованием физических (width или height) или логических (inline, block, self-inline, или self-block) значений.

<length-percentage>

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

Наиболее часто используемые функции anchor-size() будут ссылаться на размер стандартного якоря. Вы также можете использовать их внутри функций calc() для изменения размера, применённого к позиционированному элементу.

Например, это правило устанавливает ширину позиционированного элемента равной ширине стандартного элемента якоря:

.elem {
  width: anchor-size(width);
}

Это правило устанавливает размер позиционированного элемента по горизонтали в 4 раза больше размера элемента якоря по горизонтали, при этом умножение выполняется внутри функции calc():

.elem {
  inline-size: calc(anchor-size(self-inline) * 4);
}

Рассмотрим пример. HTML и базовые CSS аналогичны предыдущим примерам, за исключением того, что элементу якоря задан атрибут tabindex="0" для обеспечения возможности фокусировки. Информационная панель получает фиксированное позиционирование и связывается с якорем аналогично предыдущим примерам. Однако в этот раз она прикрепляется к правому краю якоря с помощью position-area, а её ширина устанавливается в пять раз больше ширины якоря:

.infobox {
  position: fixed;
  position-anchor: --myAnchor;
  position-area: right;
  margin-left: 5px;
  width: calc(anchor-size(width) * 5);
}

Кроме того, мы увеличиваем ширину width элемента якоря при наведении :hover и нажатии клавиши табуляции :focus и задаём свойство transition для анимации при изменении состояния.

.anchor {
  text-align: center;
  width: 30px;
  transition: 1s width;
}

.anchor:hover,
.anchor:focus {
  width: 50px;
}

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

См. также

  • Модуль позиционирования CSS якоря
  • Обработка переполнения: попытка альтернатив и условного скрытия
  • Позиционирование
  • Модуль логических свойств и значений CSS
  • Изменение размеров элементов в CSS

© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_anchor_positioning/Using

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API