API позиционирования привязки CSS

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

Browser Support

  • Хром: 125.
  • Край: 125.
  • Firefox: не поддерживается.
  • Сафари: не поддерживается.

Source

Основные понятия: привязки и позиционированные элементы.

В основе этого API лежит взаимосвязь между якорями и позиционированными элементами . Якорь — это элемент, обозначенный как опорная точка с помощью свойства anchor-name . Позиционированный элемент — это элемент, размещенный относительно якоря с использованием свойства position-anchor или явного использования anchor-name в его логике позиционирования.

Якорные элементы и позиционированные элементы.

Настройка якорей

Создать якорь очень просто. Примените свойство привязки-name к выбранному элементу и присвойте ему уникальный идентификатор. Перед этим уникальным идентификатором необходимо поставить двойное тире, как в переменной CSS.

.anchor-button {
    anchor-name: --anchor-el;
}

После присвоения имени якоря .anchor-button служит якорем, готовым управлять размещением других элементов. Вы можете соединить этот якорь с другими элементами одним из двух способов:

Неявные якоря

Первый способ присоединить привязку к другому элементу — использовать неявную привязку, как показано в следующем примере кода. Свойство position-anchor добавляется к элементу, который вы хотите подключить к привязке, и имеет в качестве значения имя привязки (в данном случае --anchor-el ).

.positioned-notice {
    position-anchor: --anchor-el;
}

При неявном отношении привязки вы можете позиционировать элементы с помощью функции anchor() без явного указания имени привязки в ее первом аргументе.

.positioned-notice {
    position-anchor: --anchor-el;
    top: anchor(bottom);
}

Явные привязки

В качестве альтернативы вы можете использовать имя якоря непосредственно в функции якоря (например, top: anchor(--anchor-el bottom ). Это называется явным якорем и может быть удобно, если вы хотите привязать несколько элементов (см. для примера).

.positioned-notice {
    top: anchor(--anchor-el bottom);
}

Расположите элементы относительно якорей

Схема расположения якоря с физическими свойствами.

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

.positioned-notice {
    position-anchor: --anchor-el;
    /* absolutely position the positioned element */
    position: absolute;
    /* position the right of the positioned element at the right edge of the anchor */
    right: anchor(right);
    /* position the bottom of the positioned element at the top edge of the anchor */
    bottom: anchor(top);
}
Схема расположения ребер на позиционируемом элементе.

Теперь у вас есть один элемент, привязанный к другому, вот так:

Демонстрация базового якоря.

Скриншот демо.

Чтобы использовать логическое позиционирование для этих значений, эквиваленты следующие:

  • top = inset-block-start
  • left = inset-inline-start
  • bottom = inset-block-end
  • right = inset-inline-end

Центрировать позиционированный элемент с помощью anchor-center

Чтобы упростить центрирование элемента, позиционируемого привязкой, относительно его привязки, существует новое значение, называемое anchor-center , которое можно использовать со свойствами justify-self , align-self , justify-items и align-items .

Этот пример модифицирует предыдущий, используя justify-self: anchor-center для центрирования позиционированного элемента поверх его привязки.

.positioned-notice {
  position: absolute;
  /*  Anchor reference  */
  position-anchor: --anchor-el;
  /*  Position bottom of positioned elem at top of anchor  */
  bottom: anchor(top);
  /*  Center justification to the anchor */
  justify-self: anchor-center;
}
Демонстрация привязки по центру с помощью justify-center .

Скриншот демо.

Несколько якорей

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

.anchored {
  position: absolute;
  top: anchor(--one bottom);
  left: anchor(--one right);
  right: anchor(--two left);
  bottom: anchor(--two top);
}
Демо, показывающее несколько якорей.

Скриншот демо.

Позиция с position-area

API привязки включает новый механизм макета, использующий свойство position-area .

Это свойство позволяет размещать элементы с привязкой относительно соответствующих им привязок и работает в сетке из 9 ячеек с привязывающим элементом в центре.

Чтобы использовать position-area а не абсолютное позиционирование, используйте свойство position-area с физическими или логическими значениями. Например:

  • Вверху по центру: position-area: top или position-area: block-start
  • Слева по центру: position-area: left или position-area: inline-start
  • Внизу по центру: position-area: bottom или position-area: block-end
  • Справа по центру: position-area: right или position-area: inline-end
Демо, показывающее несколько якорей.

Скриншот демо.

Для дальнейшего изучения этих позиций воспользуйтесь следующим инструментом:

Инструмент привязки для позиций по областям.

Размер элементов с помощью anchor-size()

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

Следующий код CSS показывает пример использования этого параметра для высоты: использование anchor-size(height) в функции calc() , чтобы установить максимальную высоту всплывающей подсказки в два раза больше высоты привязки.

.positioned-notice {
  position-anchor: --question-mark;

  /*  set max height of the tooltip to 2x height of the anchor  */
  max-height: calc(anchor-size(height) * 2);
}
Демо для anchor-size

Скриншот демо.

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

Позиционирование привязки работает невероятно хорошо с элементами верхнего слоя, такими как popover . и <dialog> . Хотя эти элементы размещаются на отдельном слое от остальной части поддерева DOM, позиционирование привязки позволяет вам привязать их обратно и прокручивать вместе с элементами, не входящими в верхний слой. Это огромная победа для многоуровневых интерфейсов.

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

Демо с использованием привязки с popover

Скриншот демо.

Отрегулируйте позиции привязки с помощью @position-try

Определив начальную позицию привязки, вы можете отрегулировать ее, если привязка достигает краев содержащего ее блока. Чтобы создать альтернативные позиции привязки, вы можете использовать директиву @position-try вместе со свойством position-try-fallbacks .

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

Если для этого подменю недостаточно места по горизонтали, вы можете вместо этого переместить его под меню. Для этого сначала настройте исходное положение:

#submenu {
  position: absolute;
  position-anchor: --submenu;

  /* initial position */
  margin-left: var(--padding);
  position-area: right span-bottom;
}

Затем настройте резервные закрепленные позиции с помощью @position-try :

/* alternate position */
@position-try --bottom {
  margin: var(--padding) 0 0 var(--padding);
  posotion-area: bottom;
}

Наконец, соедините их с помощью position-try-fallbacks . Все вместе это выглядит так:

#submenu {
  position: absolute;
  position-anchor: --submenu;
  /* initial position */
  margin-left: var(--padding);
  position-area: right span-bottom;
  */ connect with position-try-fallbacks */
  position-try-fallbacks: --bottom;
}

/* alternate position */
@position-try --bottom {
  margin: var(--padding) 0 0 var(--padding);
  position-area: bottom;
}
Демо с использованием привязки с popover

Ключевые слова для автоматического переворота позиции привязки

Если у вас есть базовая настройка, например переворот сверху вниз или слева направо (или и то, и другое), вы можете даже пропустить этап создания пользовательских объявлений @position-try и использовать встроенные ключевые слова переворота, поддерживаемые браузером, например flip-block и flip-inline . Они работают как дублеры пользовательских объявлений @position-try и могут использоваться в сочетании друг с другом:

position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;

Перевернутые ключевые слова могут значительно упростить ваш код привязки. Всего несколькими строками вы можете создать полнофункциональный якорь с альтернативными позициями:

#my-tooltip {
  position-anchor: --question-mark;
  position-area: top;
  position-try-fallbacks: flip-block;
}
Использование автоматического переворота с position-try-fallbacks: flip-block

position-visibility для якорей в субскроллере

В некоторых случаях вам может потребоваться закрепить элемент внутри субпрокрутки страницы. В этих случаях вы можете контролировать видимость привязки с помощью position-visibility . Когда якорь остается в поле зрения? Когда оно исчезает? С помощью этой функции вы можете контролировать эти параметры. Вы используете position-visibility: anchors-visible , когда хотите, чтобы позиционированный элемент оставался в поле зрения до тех пор, пока якорь не выйдет из поля зрения:

#tooltip {
  position: fixed;
  position-anchor: --anchor-top-anchor;
  position-visibility: anchors-visible;
  bottom: anchor(top);
}
position-visibility: anchors-visible Демо

В качестве альтернативы вы можете использовать position-visibility: no-overflow , чтобы привязка не переполняла свой контейнер.

#tooltip {
  position: absolute;
  position-anchor: --anchor-top-anchor;
  position-visibility: no-overflow;
  bottom: anchor(top);
}
position-visibility: no-overflow Демо

Обнаружение функций и полифиллинг

Поскольку поддержка браузеров в настоящее время ограничена, вы, вероятно, захотите использовать этот API с некоторыми предосторожностями. Во-первых, вы можете проверить наличие поддержки непосредственно в CSS, используя запрос функции @supports . Чтобы сделать это, нужно обернуть стили привязки следующим образом:

@supports (anchor-name: --myanchor) {

  /* Anchor styles here */

}

Кроме того, вы можете заполнить функцию позиционирования привязки с помощью полифила позиционирования привязки CSS от Oddbird , который работает в Firefox 54, Chrome 51, Edge 79 и Safari 10. Этот полифилл поддерживает большинство основных функций позиции привязки, хотя текущая реализация не полный и содержит устаревший синтаксис. Вы можете использовать ссылку unpkg или импортировать ее непосредственно в менеджере пакетов.

Примечание о доступности

Хотя API позиционирования привязки позволяет позиционировать элемент относительно других, он по своей сути не создает каких-либо значимых семантических отношений между ними. Если между элементом привязки и позиционируемым элементом действительно существует семантическая связь (например, позиционируемый элемент представляет собой комментарий на боковой панели к тексту привязки), один из способов сделать это — использовать aria-details чтобы указать от элемента привязки к элементу привязки. позиционированный элемент(ы). Программное обеспечение для чтения с экрана все еще учится работать с деталями арии, но поддержка улучшается.

<div class="anchor" aria-details="sidebar-comment">Main content</div>
<div class="positioned" id="sidebar-comment">Sidebar content</div>
.anchor {
  anchor-name: --anchor;
}

.positioned {
  position: fixed;
  position-anchor: --anchor;
}

Если вы используете позиционирование привязки с атрибутом popover или с элементом <dialog> , браузер будет обрабатывать корректировки навигации по фокусу для обеспечения надлежащей доступности, поэтому вам не нужно размещать всплывающие окна или диалоги в порядке DOM. Подробнее читайте в примечании о доступности в спецификации.

Дальнейшее чтение