Apresentação da API de posicionamento de âncoras CSS

Publicado em: 10 de maio de 2024

A API CSS Anchor Positioning é uma inovação no desenvolvimento da Web porque permite posicionar elementos de forma nativa em relação a outros elementos, conhecidos como âncoras. Essa API simplifica requisitos de layout complexos para muitos recursos de interface, como menus e submenus, dicas, seleções, rótulos, cards, caixas de diálogo de configurações e muito mais. Com o posicionamento de âncora integrado ao navegador, você poderá criar interfaces de usuário em camadas sem depender de bibliotecas de terceiros, abrindo um mundo de possibilidades criativas.

O posicionamento da âncora está disponível a partir do Chrome 125.

Browser Support

  • Chrome: 125.
  • Edge: 125.
  • Firefox Technology Preview: supported.
  • Safari: 26.

Source

Conceitos principais: âncoras e elementos posicionados

A relação entre âncoras e elementos posicionados é a base dessa API. Uma âncora é um elemento designado como um ponto de referência usando a propriedade anchor-name. Um elemento posicionado é um elemento colocado em relação a uma âncora usando a propriedade position-anchor ou explicitamente usando anchor-name na lógica de posicionamento.

Elementos de fixação e posicionados.

Como configurar âncoras

Criar uma âncora é simples. Aplique a propriedade "anchor-name" ao elemento selecionado e atribua a ele um identificador exclusivo. Esse identificador exclusivo precisa ser precedido por um traço duplo, assim como uma variável CSS.

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

Depois de receber um nome de âncora, .anchor-button serve como uma âncora, pronta para orientar a posição de outros elementos. É possível conectar essa âncora a outros elementos de duas maneiras:

Âncoras implícitas

A primeira maneira de conectar uma âncora a outro elemento é com uma âncora implícita, como no exemplo de código a seguir. A propriedade position-anchor é adicionada ao elemento que você quer conectar à âncora e tem o nome dela (neste caso, --anchor-el) como valor.

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

Com uma relação de ancoragem implícita, é possível posicionar elementos usando a função anchor() sem especificar explicitamente o nome da âncora no primeiro argumento.

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

Âncoras explícitas

Como alternativa, use o nome da âncora diretamente na função (por exemplo, top: anchor(--anchor-el bottom). Isso é chamado de âncora explícita e pode ser útil se você quiser ancorar vários elementos (leia um exemplo abaixo).

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

Posicionar elementos em relação a âncoras

Diagrama de posicionamento de âncora com propriedades físicas.

O posicionamento de âncora se baseia no posicionamento absoluto do CSS. Para usar valores de posicionamento, adicione position: absolute ao elemento posicionado. Em seguida, use a função anchor() para aplicar valores de posicionamento. Por exemplo, para posicionar um elemento ancorado na parte superior esquerda do elemento de ancoragem, use o seguinte posicionamento:

.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);
}
Diagrama das bordas de posicionamento no elemento posicionado.

Agora você tem um elemento ancorado a outro, como mostrado na imagem a seguir.

Captura de tela da demonstração.

Para usar o posicionamento lógico desses valores, os equivalentes são os seguintes:

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

Centralizar um elemento posicionado com anchor-center

Para facilitar o posicionamento centralizado do elemento ancorado em relação à âncora, há um novo valor chamado anchor-center, que pode ser usado com as propriedades justify-self, align-self, justify-items e align-items.

Este exemplo modifica o anterior usando justify-self: anchor-center para centralizar o elemento posicionado em cima da âncora.

.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;
}

Captura de tela da demonstração.

Várias âncoras

Os elementos podem ser vinculados a mais de uma âncora. Isso significa que talvez seja necessário definir valores de posição relativos a mais de uma âncora. Para fazer isso, use a função anchor() e declare explicitamente qual âncora você está referenciando no primeiro argumento. No exemplo a seguir, a parte superior esquerda de um elemento posicionado está fixada na parte inferior direita de uma âncora, e a parte inferior direita do elemento posicionado está fixada na parte superior esquerda da segunda âncora:

.anchored {
  position: absolute;
  top: anchor(--one bottom);
  left: anchor(--one right);
  right: anchor(--two left);
  bottom: anchor(--two top);
}

Captura de tela da demonstração.

Posição com inset-area

Além do posicionamento direcional padrão do posicionamento absoluto, há um novo mecanismo de layout incluído na API de ancoragem chamado área de encarte.

A área de encarte facilita a colocação de elementos posicionados em relação às respectivas âncoras e funciona em uma grade de nove células com o elemento de ancoragem no centro.

Várias opções de posicionamento possíveis da área de encarte, mostradas na grade de nove células

Para usar a área de encarte em vez do posicionamento absoluto, use a propriedade inset-area com valores físicos ou lógicos. Exemplo:

  • Centralizado na parte de cima: inset-area: top ou inset-area: block-start
  • Esquerda-centro: inset-area: left ou inset-area: inline-start
  • Parte central inferior: inset-area: bottom ou inset-area: block-end
  • Central à direita: inset-area: right ou inset-area: inline-end

Captura de tela da demonstração.

Dimensionar elementos com anchor-size()

A função anchor-size(), que também faz parte da API de posicionamento de âncora, pode ser usada para dimensionar ou posicionar um elemento ancorado com base no tamanho da âncora (largura, altura ou tamanhos inline e de bloco).

O CSS a seguir mostra um exemplo de uso para altura,usando anchor-size(height) em uma função calc() para definir a altura máxima da dica como duas vezes a altura da âncora.

.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);
}

Captura de tela da demonstração.

Usar âncora com elementos de camada superior, como popover e caixa de diálogo

O posicionamento de âncora funciona muito bem com elementos da camada superior, como popover. e <dialog>. Embora esses elementos sejam colocados em uma camada separada do restante da subárvore DOM, o posicionamento de âncora permite que você os vincule de volta e role junto com elementos que não estão na camada superior. Isso é uma grande vitória para interfaces em camadas.

No exemplo a seguir, um conjunto de popovers de dica é aberto usando um botão. O botão é a âncora, e a dica é o elemento posicionado. É possível estilizar o elemento posicionado como qualquer outro elemento ancorado. Neste exemplo específico, anchor-name e position-anchor são estilos inline no botão e na dica. Como cada âncora precisa de um nome exclusivo, a inclusão em linha é a maneira mais fácil de fazer isso ao gerar conteúdo dinâmico.

Captura de tela da demonstração.

Ajustar posições de âncora com @position-try

Depois de ter a posição inicial da âncora, talvez seja necessário ajustar a posição se ela atingir as bordas do bloco de contêiner. Para criar posições de âncora alternativas, use a diretiva @position-try com a propriedade position-try-options.

No exemplo a seguir, um submenu aparece à direita de um menu. Menus e submenus são um ótimo uso da API de posicionamento de âncora com o atributo popover, já que esses menus tendem a ser ancorados a um botão de acionamento.

Para esse submenu, se não houver espaço suficiente na horizontal, mova-o para baixo do menu. Para fazer isso, primeiro defina a posição inicial:

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

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

Em seguida, configure as posições fixas de substituição usando @position-try:

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

Por fim, conecte os dois com position-try-options. Juntando tudo, fica assim:

#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;
}

Palavras-chave de inversão automática da posição da âncora

Se você tiver um ajuste básico, como inverter de cima para baixo ou da esquerda para a direita (ou ambos), poderá até pular a etapa de criação de declarações @position-try personalizadas e usar as palavras-chave de inversão integradas compatíveis com o navegador, como flip-block e flip-inline. Elas funcionam como substitutas para declarações @position-try personalizadas e podem ser usadas em combinação:

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

As palavras-chave de inversão podem simplificar significativamente o código de âncora. Com apenas algumas linhas, é possível criar uma âncora totalmente funcional com posições alternativas:

#my-tooltip {
  position-anchor: --question-mark;
  inset-area: top;
  position-try-options: flip-block;
}

position-visibility para âncoras em subscrollers

Em alguns casos, talvez seja necessário ancorar um elemento em um subscroller da página. Nesses casos, é possível controlar a visibilidade da âncora usando position-visibility. Quando a âncora permanece visível? Quando ele desaparece? Com esse recurso, você tem controle sobre essas opções. Use position-visibility: anchors-visible quando quiser que o elemento posicionado permaneça visível até que a âncora saia da visualização:

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

Outra opção é usar position-visibility: no-overflow para evitar que a âncora transborde o contêiner.

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

Detecção de recursos e polyfilling

Como o suporte do navegador é limitado no momento, é recomendável usar essa API com algumas precauções. Primeiro, você pode verificar o suporte diretamente no CSS usando a consulta de recursos @supports. Para fazer isso, coloque seus estilos de âncora no seguinte:

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

  /* Anchor styles here */

}

Além disso, é possível fazer o polyfill do recurso de posicionamento de âncora com o polyfill de posicionamento de âncora CSS da Oddbird, que funciona no Firefox 54, Chrome 51, Edge 79 e Safari 10. O polyfill é compatível com a maioria dos recursos básicos de posição de âncora, mas a implementação atual não está completa e contém uma sintaxe desatualizada. Você pode usar o link do unpkg ou importar diretamente em um gerenciador de pacotes.

Observação sobre acessibilidade

Embora a API de posicionamento de âncora permita que um elemento seja posicionado em relação a outros, ela não cria inerentemente nenhuma relação semântica significativa entre eles. Se houver uma relação semântica entre o elemento âncora e o elemento posicionado (por exemplo, o elemento posicionado é um comentário na barra lateral sobre o texto âncora), uma maneira de fazer isso é usar aria-details para apontar do elemento âncora para o elemento ou elementos posicionados. Os softwares de leitor de tela ainda estão aprendendo a lidar com aria-details, mas a compatibilidade está melhorando.

<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;
}

Se você estiver usando o posicionamento de âncora com o atributo popover ou com um elemento <dialog>, o navegador vai processar as correções de navegação por foco para acessibilidade adequada. Assim, não é necessário ter popovers ou caixas de diálogo na ordem do DOM. Leia mais sobre a observação sobre acessibilidade na especificação.

Conclusão

Esse é um recurso novo, e estamos ansiosos para ver o que você vai criar com ele. Até agora, vimos alguns casos de uso muito interessantes da comunidade, como rótulos dinâmicos em gráficos, linhas de conector, notas de rodapé e referências cruzadas visuais. Enquanto você testa o posicionamento da âncora, gostaríamos de receber seu feedback. Se encontrar algum bug, avise a gente.

Leitura adicional