Представляем API позиционирования привязки CSS

Опубликовано: 10 мая 2024 г.

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

Функция позиционирования якоря доступна начиная с Chrome версии 125.

Browser Support

  • Chrome: 125.
  • Edge: 125.
  • Firefox Technology Preview: поддерживается.
  • Сафари: 26.

Source

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

В основе этого 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: left or inset-area: inline-start
  • Bottom-center: inset-area: bottom or inset-area: block-end
  • Right-center: inset-area: right or inset-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. Подробнее об этом см. в примечании о доступности в спецификации.

Заключение

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

Дополнительная информация