Опубликовано: 10 мая 2024 г.
API позиционирования CSS Anchor Positioning кардинально меняет веб-разработку, поскольку позволяет позиционировать элементы относительно других элементов, известных как якоря . Этот API упрощает сложные требования к компоновке для многих элементов интерфейса, таких как меню и подменю, всплывающие подсказки, выпадающие списки, метки, карточки, диалоговые окна настроек и многое другое. Благодаря встроенному в браузер позиционированию якорей вы сможете создавать многоуровневые пользовательские интерфейсы, не полагаясь на сторонние библиотеки, что открывает мир творческих возможностей.
Функция позиционирования якоря доступна начиная с Chrome версии 125.
Основные понятия: опорные элементы и элементы позиционирования.
В основе этого API лежит взаимосвязь между якорями и позиционированными элементами . Якорь — это элемент, обозначенный в качестве опорной точки с помощью свойства anchor-name . Позиционированный элемент — это элемент, размещенный относительно якоря с помощью свойства position-anchor или явно с использованием anchor-name в своей логике позиционирования.

Установка якорей
Создать якорь очень просто. Примените свойство anchor-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);
}

Расположение с inset-area
В дополнение к позиционированию по умолчанию на основе абсолютного позиционирования, в API привязки добавлен новый механизм компоновки, называемый областью вставки.
Встроенная область упрощает размещение элементов, расположенных относительно соответствующих точек крепления, и работает на сетке из 9 ячеек с элементом крепления в центре.
Различные варианты размещения вставной области, показанные на 9-ячеечной сетке.
Чтобы использовать область отступа вместо абсолютного позиционирования, используйте свойство inset-area с физическими или логическими значениями. Например:
- Top-center:
inset-area: topилиinset-area: block-start - Left-center:
inset-area: leftorinset-area: inline-start - Bottom-center:
inset-area: bottomorinset-area: block-end - Right-center:
inset-area: rightorinset-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-options .
В следующем примере подменю появляется справа от основного меню. Меню и подменю отлично подходят для использования API позиционирования привязки вместе с атрибутом popover , поскольку такие меню обычно привязаны к кнопке-триггеру.
Если для этого подменю недостаточно места по горизонтали, вы можете переместить его под меню. Для этого сначала установите начальное положение:
#submenu {
position: absolute;
position-anchor: --submenu;
/* initial position */
margin-left: var(--padding);
inset-area: right span-bottom;
}
Затем настройте резервные закрепленные позиции, используя @position-try :
/* alternate position */
@position-try --bottom {
margin: var(--padding) 0 0 var(--padding);
inset-area: bottom;
}
Наконец, соедините их с помощью position-try-options . В итоге это будет выглядеть так:
#submenu {
position: absolute;
position-anchor: --submenu;
/* initial position */
margin-left: var(--padding);
inset-area: right span-bottom;
*/ connect with position-try options */
position-try-options: --bottom;
}
/* alternate position */
@position-try --bottom {
margin: var(--padding) 0 0 var(--padding);
inset-area: bottom;
}
Ключевые слова для автоматического переворота в позиции якоря
Если вам требуется базовая настройка, например, перелистывание сверху вниз или слева направо (или и то, и другое), вы можете даже пропустить этап создания пользовательских объявлений @position-try и использовать встроенные в браузер ключевые слова для перелистывания, такие как flip-block и flip-inline . Они работают как заменители пользовательских объявлений @position-try и могут использоваться в сочетании друг с другом:
position-try-options: flip-block, flip-inline, flip-block flip-inline;
Использование ключевых слов с перестановкой позиций может значительно упростить код якоря. Всего несколькими строками кода вы можете создать полностью функциональный якорь с альтернативными позициями:
#my-tooltip {
position-anchor: --question-mark;
inset-area: top;
position-try-options: 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 anchor positioning от Oddbird , который работает в Firefox 54, Chrome 51, Edge 79 и Safari 10. Этот полифил поддерживает большинство основных функций позиционирования якорей, хотя текущая реализация не является полной и содержит устаревший синтаксис. Вы можете использовать ссылку unpkg или импортировать его напрямую в менеджере пакетов.
Примечание о доступности
Хотя API позиционирования якоря позволяет позиционировать элемент относительно других, он по своей сути не создает между ними какой-либо значимой семантической связи. Если между элементом якоря и позиционируемым элементом действительно существует семантическая связь (например, позиционируемый элемент — это комментарий в боковой панели к тексту якоря), один из способов это сделать — использовать aria-details , указывающий от элемента якоря к позиционируемому элементу (элементам). Программы для чтения с экрана все еще учатся работать с атрибутом 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. Подробнее об этом см. в примечании о доступности в спецификации.
Заключение
Это совершенно новая функция, и мы с нетерпением ждём, что вы с ней создадите. На данный момент мы уже увидели несколько действительно интересных примеров её использования от сообщества, таких как динамические метки на диаграммах, соединительные линии, сноски и визуальные перекрестные ссылки. Пока вы экспериментируете с позиционированием якорей, мы будем рады услышать ваши отзывы, и если вы обнаружите какие-либо ошибки, сообщите нам .