API позиционирования привязки CSS позволяет позиционировать элементы относительно других элементов, известных как привязки . Этот API упрощает сложные требования к макету для многих функций интерфейса, таких как меню и подменю, всплывающие подсказки, элементы выбора, метки, карточки, диалоговые окна настроек и многое другое. Благодаря встроенному в браузер позиционированию привязки вы можете создавать многоуровневые пользовательские интерфейсы, не полагаясь на сторонние библиотеки, открывая мир творческих возможностей.
Основные понятия: привязки и позиционированные элементы.
В основе этого 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;
}
Несколько якорей
Элементы могут быть привязаны к нескольким якорям. Это означает, что вам может потребоваться установить значения позиции, расположенные относительно более чем одной привязки. Сделайте это, используя функцию 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);
}
Используйте привязку с элементами верхнего слоя, такими как всплывающее окно и диалоговое окно.
Позиционирование привязки работает невероятно хорошо с элементами верхнего слоя, такими как popover
. и <dialog>
. Хотя эти элементы размещаются на отдельном слое от остальной части поддерева DOM, позиционирование привязки позволяет вам привязать их обратно и прокручивать вместе с элементами, не входящими в верхний слой. Это огромная победа для многоуровневых интерфейсов.
В следующем примере набор всплывающих подсказок открывается с помощью кнопки. Кнопка является якорем, а всплывающая подсказка — позиционированным элементом. Вы можете стилизовать позиционированный элемент так же, как и любой другой привязанный элемент. В этом конкретном примере anchor-name
и position-anchor
являются встроенными стилями кнопки и всплывающей подсказки. Поскольку каждой привязке требуется уникальное имя привязки, при создании динамического контента самым простым способом сделать это является встраивание.
Отрегулируйте позиции привязки с помощью @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;
}
Ключевые слова для автоматического переворота позиции привязки
Если у вас есть базовая настройка, например переворот сверху вниз или слева направо (или и то, и другое), вы можете даже пропустить этап создания пользовательских объявлений @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-visibility
для якорей в субскроллере
В некоторых случаях вам может потребоваться закрепить элемент внутри субпрокрутки страницы. В этих случаях вы можете контролировать видимость привязки с помощью position-visibility
. Когда якорь остается в поле зрения? Когда оно исчезает? С помощью этой функции вы можете контролировать эти параметры. Вы используете position-visibility: anchors-visible
, когда хотите, чтобы позиционированный элемент оставался в поле зрения до тех пор, пока якорь не выйдет из поля зрения:
#tooltip {
position: fixed;
position-anchor: --anchor-top-anchor;
position-visibility: anchors-visible;
bottom: anchor(top);
}
В качестве альтернативы вы можете использовать position-visibility: no-overflow
, чтобы привязка не переполняла свой контейнер.
#tooltip {
position: absolute;
position-anchor: --anchor-top-anchor;
position-visibility: no-overflow;
bottom: anchor(top);
}
Обнаружение функций и полифиллинг
Поскольку поддержка браузеров в настоящее время ограничена, вы, вероятно, захотите использовать этот 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. Подробнее читайте в примечании о доступности в спецификации.