Introductie van de CSS-ankerpositionerings-API

Gepubliceerd: 10 mei 2024

De CSS Anchor Positioning API is een gamechanger in webontwikkeling omdat je hiermee elementen rechtstreeks ten opzichte van andere elementen kunt positioneren, ook wel ankers genoemd. Deze API vereenvoudigt complexe lay-outvereisten voor veel interfacefuncties zoals menu's en submenu's, tooltips, selectievelden, labels, kaarten, instellingendialoogvensters en nog veel meer. Doordat ankerpositionering in de browser is ingebouwd, kun je gelaagde gebruikersinterfaces bouwen zonder afhankelijk te zijn van externe bibliotheken, wat een wereld aan creatieve mogelijkheden opent.

Ankerpositionering is beschikbaar vanaf Chrome 125.

Browser Support

  • Chrome: 125.
  • Rand: 125.
  • Firefox Technology Preview: ondersteund.
  • Safari: 26.

Source

Kernconcepten: Ankers en gepositioneerde elementen

De kern van deze API wordt gevormd door de relatie tussen ankers en gepositioneerde elementen . Een anker is een element dat als referentiepunt is aangewezen met behulp van de eigenschap anchor-name . Een gepositioneerd element is een element dat ten opzichte van een anker wordt geplaatst met behulp van de eigenschap position-anchor of door expliciet anchor-name in de positioneringslogica te gebruiken.

Ankerelementen en gepositioneerde elementen.

Ankers plaatsen

Het maken van een anker is eenvoudig. Pas de eigenschap `anchor-name` toe op het geselecteerde element en ken er een unieke identificatiecode aan toe. Deze unieke identificatiecode moet, net als een CSS-variabele, voorafgegaan worden door een dubbele streep.

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

Zodra er een anchor-naam aan is toegewezen, fungeert .anchor-button als een anker, klaar om de plaatsing van andere elementen te begeleiden. Je kunt dit anker op twee manieren met andere elementen verbinden:

Impliciete ankers

De eerste manier om een ​​anker aan een ander element te koppelen is met een impliciet anker, zoals in het volgende codevoorbeeld. De eigenschap position-anchor wordt toegevoegd aan het element dat je aan je anker wilt koppelen en heeft de naam van het anker (in dit geval --anchor-el ) als waarde.

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

Met een impliciete ankerrelatie kunt u elementen positioneren met behulp van de functie anchor() zonder de ankernaam expliciet als eerste argument op te geven.

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

Expliciete ankers

Als alternatief kunt u de ankernaam direct in de ankerfunctie gebruiken (bijvoorbeeld: top: anchor(--anchor-el bottom )). Dit wordt een expliciet anker genoemd en kan handig zijn als u aan meerdere elementen wilt verankeren (lees verder voor een voorbeeld).

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

Plaats elementen ten opzichte van ankers.

Ankerpositioneringsdiagram met fysieke eigenschappen.

Ankerpositionering bouwt voort op CSS absolute positionering. Om positioneringswaarden te gebruiken, moet je position: absolute toevoegen aan het element dat je wilt positioneren. Gebruik vervolgens de anchor() `-functie om de positioneringswaarden toe te passen. Om bijvoorbeeld een verankerd element linksboven het verankerende element te positioneren, gebruik je de volgende positionering:

.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);
}
Diagram van de positionering van randen op het gepositioneerde element.

Nu is een element aan een ander element verankerd, zoals in de volgende afbeelding te zien is.

Screenshot van de demo.

Om logische positionering voor deze waarden te gebruiken, zijn de equivalenten als volgt:

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

Centreer een gepositioneerd element met anchor-center

Om het centreren van een gepositioneerd ankerelement ten opzichte van het ankerpunt te vereenvoudigen, is er een nieuwe waarde genaamd anchor-center die kan worden gebruikt met de eigenschappen justify-self , align-self , justify-items en align-items .

Dit voorbeeld is een aanpassing van het vorige, waarbij justify-self: anchor-center wordt gebruikt om het gepositioneerde element boven zijn anker te centreren.

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

Screenshot van de demo.

Meerdere ankers

Elementen kunnen aan meer dan één ankerpunt gekoppeld zijn. Dit betekent dat u mogelijk positiewaarden moet instellen die relatief zijn ten opzichte van meerdere ankerpunten. Doe dit door de functie anchor() te gebruiken en in het eerste argument expliciet aan te geven naar welk ankerpunt u verwijst. In het volgende voorbeeld is de linkerbovenhoek van een gepositioneerd element gekoppeld aan de rechteronderhoek van het ene ankerpunt, en de rechteronderhoek van het gepositioneerde element is gekoppeld aan de linkerbovenhoek van het tweede ankerpunt:

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

Screenshot van de demo.

Positie met inset-area

Naast de standaard directionele positionering via absolute positionering, is er een nieuw lay-outmechanisme opgenomen in de anchoring API, genaamd inset area.

Met het inzetgebied is het eenvoudig om elementen met ankerpunten ten opzichte van hun respectievelijke ankerpunten te plaatsen, en het werkt met een raster van 9 cellen waarbij het ankerelement in het midden staat.

Verschillende mogelijke positioneringsopties voor het inzetgebied, weergegeven op het raster van 9 cellen.

Om een ​​inzetgebied in plaats van een absolute positionering te gebruiken, gebruikt u de eigenschap inset-area met fysieke of logische waarden. Bijvoorbeeld:

  • Boven in het midden: inset-area: top of inset-area: block-start
  • Links-midden: inset-area: left of inset-area: inline-start
  • Onder-midden: inset-area: bottom of inset-area: block-end
  • Rechts-midden: inset-area: right of inset-area: inline-end

Screenshot van de demo.

Bepaal de grootte van elementen met anchor-size()

De functie anchor-size() , die ook deel uitmaakt van de anchor-positionerings-API, kan worden gebruikt om de grootte of positie van een gepositioneerd ankerelement aan te passen op basis van de grootte van het anker (breedte, hoogte of inline- en blokgrootte).

De volgende CSS toont een voorbeeld van het gebruik hiervan voor de hoogte, waarbij anchor-size(height) binnen een calc() -functie wordt gebruikt om de maximale hoogte van de tooltip in te stellen op tweemaal de hoogte van het anker.

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

Screenshot van de demo.

Gebruik een ankerpunt bij elementen op het hoogste niveau, zoals popovers en dialogen.

Ankerpositionering werkt ongelooflijk goed met elementen op de bovenste laag, zoals popover ` en <dialog> . Hoewel deze elementen zich in een aparte laag van de DOM-structuur bevinden, kunt u ze dankzij ankerpositionering koppelen aan elementen die zich niet in de bovenste laag bevinden en ermee meescrollen. Dit is een enorme winst voor interfaces met meerdere lagen.

In het volgende voorbeeld worden een aantal tooltip-popovers geopend met behulp van een knop. De knop is het anker en de tooltip is het gepositioneerde element. Je kunt het gepositioneerde element op dezelfde manier stylen als elk ander verankerd element. In dit specifieke voorbeeld zijn de anchor-name en position-anchor inline stijlen voor de knop en de tooltip. Omdat elk anker een unieke ankernaam nodig heeft, is inlining de eenvoudigste manier om dit te doen bij het genereren van dynamische content.

Screenshot van de demo.

Pas ankerposities aan met @position-try

Zodra je de initiële ankerpositie hebt bepaald, wil je deze wellicht aanpassen als het anker de randen van het omringende blok bereikt. Om alternatieve ankerposities te creëren, kun je de @position-try richtlijn gebruiken in combinatie met de position-try-options eigenschap.

In het volgende voorbeeld verschijnt een submenu rechts van een menu. Menu's en submenu's zijn een uitstekende toepassing van de anchor positioning API in combinatie met het popover-attribuut , aangezien deze menu's vaak aan een triggerknop zijn gekoppeld.

Als er horizontaal onvoldoende ruimte is voor dit submenu, kunt u het eronder plaatsen. Stel hiervoor eerst de beginpositie in:

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

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

Stel vervolgens uw fallback-verankerde posities in met behulp van @position-try :

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

Verbind de twee ten slotte met position-try-options . Het geheel ziet er als volgt uit:

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

Ankerpositie automatisch omdraaien trefwoorden

Als je een eenvoudige aanpassing wilt maken, zoals van boven naar beneden of van links naar rechts (of beide), kun je zelfs de stap van het aanmaken van aangepaste @position-try -declaraties overslaan en de ingebouwde, door de browser ondersteunde trefwoorden voor spiegelen gebruiken, zoals flip-block en flip-inline . Deze fungeren als vervanging voor aangepaste @position-try -declaraties en kunnen in combinatie met elkaar worden gebruikt.

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

Met Flip Keywords kunt u uw ankercode aanzienlijk vereenvoudigen. Met slechts een paar regels kunt u een volledig functioneel anker met alternatieve posities creëren:

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

position-visibility voor ankers in subscrollers

Er zijn situaties waarin u een element wilt verankeren binnen een subscroller van de pagina. In deze gevallen kunt u de zichtbaarheid van het anker beheren met position-visibility . Wanneer blijft het anker zichtbaar? Wanneer verdwijnt het? Met deze functie hebt u controle over deze opties. U gebruikt position-visibility: anchors-visible wanneer u wilt dat het gepositioneerde element zichtbaar blijft totdat het anker niet meer zichtbaar is.

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

Als alternatief kunt u position-visibility: no-overflow gebruiken om te voorkomen dat het anker buiten de container valt.

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

Kenmerkdetectie en polyfilling

Omdat de browserondersteuning momenteel beperkt is, is het raadzaam om deze API met de nodige voorzichtigheid te gebruiken. Ten eerste kunt u de ondersteuning rechtstreeks in CSS controleren met behulp van de @supports functiequery. Dit doet u door uw ankerstijlen als volgt te omwikkelen:

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

  /* Anchor styles here */

}

Daarnaast kunt u de ankerpositioneringsfunctie polyfillen met de CSS-ankerpositioneringspolyfill van Oddbird , die werkt vanaf Firefox 54, Chrome 51, Edge 79 en Safari 10. Deze polyfill ondersteunt de meeste basisfuncties voor ankerpositionering, hoewel de huidige implementatie niet compleet is en enkele verouderde syntax bevat. U kunt de unpkg-link gebruiken of de polyfill rechtstreeks importeren in een pakketbeheerder.

Een opmerking over toegankelijkheid

Hoewel de anchor-positionerings-API het mogelijk maakt om een ​​element ten opzichte van andere elementen te positioneren, creëert deze niet inherent een betekenisvolle semantische relatie tussen deze elementen. Als er wél een semantische relatie bestaat tussen het anchor-element en het gepositioneerde element (bijvoorbeeld als het gepositioneerde element een commentaar in de zijbalk is over de anchor-tekst), kan dit worden bereikt door aria-details te gebruiken om vanuit het anchor-element naar de gepositioneerde elementen te verwijzen. Schermleessoftware is nog in ontwikkeling wat betreft de omgang met aria-details, maar de ondersteuning verbetert.

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

Als u ankerpositionering gebruikt met het popover attribuut of met een <dialog> -element, zal de browser de focusnavigatiecorrecties voor een goede toegankelijkheid afhandelen. U hoeft uw popovers of dialogen dus niet in de DOM-volgorde te plaatsen. Lees meer over toegankelijkheid in de specificatie.

Conclusie

Dit is een gloednieuwe functie en we zijn erg benieuwd wat jullie ermee gaan doen. We hebben tot nu toe al een aantal erg leuke voorbeelden gezien van toepassingen vanuit de community, zoals dynamische labels in grafieken, verbindingslijnen, voetnoten en visuele kruisverwijzingen. Terwijl jullie experimenteren met ankerpositionering, horen we graag jullie feedback. En als jullie bugs vinden, laat het ons dan weten .

Verder lezen