Introductie van de CSS-ankerpositionerings-API

Gepubliceerd: 10 mei 2024

De CSS Anchor Positioning API is een game-changer in webontwikkeling omdat u hiermee elementen native kunt positioneren ten opzichte van andere elementen, ook wel ankers genoemd. Deze API vereenvoudigt complexe lay-outvereisten voor veel interfacefuncties, zoals menu's en submenu's, tooltips, selecties, labels, kaarten, instellingendialogen en nog veel meer. Doordat de ankerpositionering in de browser is ingebouwd, kunt u gelaagde gebruikersinterfaces bouwen zonder afhankelijk te zijn van bibliotheken van derden, waardoor er een wereld aan creatieve mogelijkheden opengaat.

Ankerpositionering is beschikbaar vanaf Chroom 125.

Browserondersteuning

  • Chroom: 125.
  • Rand: 125.
  • Firefox: niet ondersteund.
  • Safari: niet ondersteund.

Bron

Kernconcepten: Ankers en gepositioneerde elementen

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

Ankerelementen en gepositioneerde elementen.

Ankers opzetten

Het maken van een anker is eenvoudig. Pas de eigenschap anchor-name toe op het geselecteerde element en wijs er een unieke identificatie aan toe. Deze unieke identificatie moet worden voorafgegaan door een dubbel streepje, net als bij een CSS-variabele.

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

Zodra een ankernaam is toegewezen, fungeert .anchor-button als anker, klaar om de plaatsing van andere elementen te begeleiden. U 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 u aan uw 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 expliciet de ankernaam op te geven bij het eerste argument.

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

Expliciete ankers

Als alternatief kunt u de ankernaam rechtstreeks 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 op voor een voorbeeld).

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

Plaats elementen ten opzichte van ankers

Ankerpositioneringsdiagram met fysieke eigenschappen.

Ankerpositionering bouwt voort op absolute CSS-positionering. Om positioneringswaarden te gebruiken, moet u position: absolute aan uw gepositioneerde element toevoegen. Gebruik vervolgens de functie anchor() om positioneringswaarden toe te passen. Om bijvoorbeeld een verankerd element linksboven op het verankeringselement te plaatsen, gebruikt u 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 positioneringsranden op het gepositioneerde element.

Nu heb je het ene element aan het andere verankerd, zoals weergegeven in de volgende afbeelding.

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 gemakkelijker te maken om uw ankergepositioneerde element ten opzichte van het anker te centreren, 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 wijzigt het vorige door justify-self: anchor-center te gebruiken om het gepositioneerde element bovenop 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 anker worden vastgemaakt. Dit betekent dat u mogelijk positiewaarden moet instellen die ten opzichte van meer dan één anker zijn gepositioneerd. Doe dit door de functie anchor() te gebruiken en expliciet te vermelden naar welk anker u verwijst in het eerste argument. In het volgende voorbeeld is de linkerbovenhoek van een gepositioneerd element verankerd aan de rechteronderzijde van één anker, en is de rechterbenedenhoek van het gepositioneerde element verankerd aan de linkerbovenhoek van het tweede anker:

.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 vanuit absolute positionering, is er een nieuw lay-outmechanisme opgenomen in de verankerings-API, genaamd inset area.

Het inzetgebied maakt het eenvoudig om op anker gepositioneerde elementen ten opzichte van hun respectievelijke ankers te plaatsen, en werkt op een raster met 9 cellen met het verankeringselement in het midden.

Verschillende mogelijke positioneringsopties voor het inzetgebied, weergegeven op het 9-cellenraster

Als u inzetgebied wilt gebruiken in plaats van absolute positionering, gebruikt u de eigenschap inset-area , met fysieke of logische waarden. Bijvoorbeeld:

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

Screenshot van de demo.

Grootte-elementen met anchor-size()

De functie anchor-size() , ook onderdeel van de API voor ankerpositionering, kan worden gebruikt om de grootte of positie van een ankergepositioneerd element te bepalen op basis van de grootte van het anker (breedte, hoogte, of inline- en blokgroottes).

De volgende CSS toont een voorbeeld van het gebruik hiervan voor hoogte, waarbij anchor-size(height) wordt gebruikt binnen een calc() functie om de maximale hoogte van de tooltip in te stellen op twee keer 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 anker met elementen uit de bovenste laag, zoals popover en dialoog

Ankerpositionering werkt ongelooflijk goed met elementen uit de bovenste laag, zoals popover . en <dialog> . Hoewel deze elementen in een aparte laag van de rest van de DOM-substructuur worden geplaatst, kunt u met de ankerpositionering ze terugkoppelen aan en mee scrollen met elementen die zich niet in de bovenste laag bevinden. Dit is een enorme overwinning voor gelaagde interfaces.

In het volgende voorbeeld wordt een reeks tooltip-popovers geopend met behulp van een knop. De knop is het anker en de tooltip is het gepositioneerde element. U kunt het gepositioneerde element op dezelfde manier opmaken als elk ander verankerd element. Voor dit specifieke voorbeeld zijn de anchor-name en position-anchor inlinestijlen op de knop en knopinfo. Omdat elk anker een unieke ankernaam nodig heeft, is inlining bij het genereren van dynamische inhoud de gemakkelijkste manier om dit te doen.

Screenshot van de demo.

Pas ankerposities aan met @position-try

Zodra u uw initiële ankerpositie heeft bepaald, wilt u wellicht de positie aanpassen als het anker de randen van het bijbehorende blok bereikt. Om alternatieve ankerposities te creëren, kunt u de @position-try richtlijn samen met de eigenschap position-try-options gebruiken.

In het volgende voorbeeld verschijnt rechts van een menu een submenu. Menu's en submenu's vormen samen met het popover-attribuut een goed gebruik van de anchor positioning API, omdat deze menu's vaak aan een triggerknop zijn verankerd.

Als er voor dit submenu niet voldoende ruimte horizontaal is, kunt u het onder het menu verplaatsen. Om dit te doen, stelt u 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 @position-try :

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

Verbind ten slotte de twee met position-try-options . Alles bij elkaar ziet het 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;
}

Auto-flip trefwoorden voor ankerposities

Als u een basisaanpassing heeft, zoals het omdraaien van boven naar beneden of van links naar rechts (of beide), kunt u zelfs de stap overslaan van het maken van aangepaste @position-try -declaraties en de ingebouwde browserondersteunde flip-trefwoorden gebruiken, zoals flip-block en flip-inline . Deze werken als stand-ins voor aangepaste @position-try declaraties en kunnen in combinatie met elkaar worden gebruikt:

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

Flip-trefwoorden kunnen uw ankercode aanzienlijk vereenvoudigen. Met slechts een paar lijnen kunt u een volledig functioneel anker creëren met alternatieve posities:

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

position-visibility voor ankers in subscrollers

Er zijn enkele gevallen waarin u mogelijk een element in een subscroller van de pagina wilt verankeren. In deze gevallen kunt u de zichtbaarheid van het anker bepalen met behulp van position-visibility . Wanneer blijft het anker in zicht? Wanneer verdwijnt het? Met deze functie heeft u controle over deze opties. Je gebruikt position-visibility: anchors-visible als je wilt dat het gepositioneerde element in beeld blijft totdat het anker uit beeld 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 zijn container overstroomt.

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

Functiedetectie en polyfilling

Omdat browserondersteuning momenteel beperkt is, wilt u deze API waarschijnlijk met enkele voorzorgsmaatregelen gebruiken. Ten eerste kunt u rechtstreeks in CSS controleren op ondersteuning door de functiequery @supports te gebruiken. De manier om dit te doen is door uw ankerstijlen als volgt in te pakken:

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

  /* Anchor styles here */

}

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

Een opmerking over de toegankelijkheid

Hoewel de API voor ankerpositionering het mogelijk maakt een element ten opzichte van andere te positioneren, creëert het niet inherent een betekenisvolle semantische relatie tussen de elementen. Als er feitelijk een semantische relatie bestaat tussen het ankerelement en het gepositioneerde element (het gepositioneerde element is bijvoorbeeld een commentaar in de zijbalk over de ankertekst), is een manier om dat te doen het gebruik van aria-details om van het ankerelement naar het ankerelement te verwijzen. gepositioneerde element(en). Schermlezersoftware leert nog steeds hoe om te gaan met aria-details, maar de ondersteuning wordt steeds beter.

<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 afhandelen voor een goede toegankelijkheid, zodat u uw popovers of dialoogvensters niet in DOM-volgorde hoeft te hebben. Lees meer over de opmerking over toegankelijkheid in de specificatie.

Conclusie

Dit is een geheel nieuwe functie en we zijn benieuwd wat je ermee bouwt. Tot nu toe hebben we een aantal hele mooie gebruiksscenario's uit de community gezien, zoals dynamische labels in diagrammen, verbindingslijnen, voetnoten en visuele kruisverwijzingen. Terwijl u experimenteert met ankerpositionering, horen we graag uw feedback. Als u bugs tegenkomt, kunt u ons dit laten weten .

Verder lezen