Introductie van de CSS-ankerpositionerings-API

Gepubliceerd: 10 mei 2024

De CSS Anchor Positioning API is een game-changer in webontwikkeling, omdat je hiermee elementen relatief ten opzichte van andere elementen, ankers genaamd, kunt positioneren. Deze API vereenvoudigt complexe lay-outvereisten voor veel interfacefuncties zoals menu's en submenu's, tooltips, selecties, labels, kaarten, instellingendialoogvensters en nog veel meer. Met de ingebouwde ankerpositionering in de browser 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

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

Source

Kernconcepten: Ankers en gepositioneerde elementen

De kern van deze API is 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 plaatsen

Het maken van een anker is eenvoudig. Pas de eigenschap anchor-name toe op het geselecteerde element en wijs er een unieke identificatiecode aan toe. Deze unieke identificatiecode moet voorafgegaan worden 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 aan andere elementen koppelen:

Impliciete ankers

De eerste manier om een ​​anker met een ander element te verbinden, is met een impliciet anker, zoals in het volgende codevoorbeeld. De eigenschap position-anchor wordt toegevoegd aan het element dat u met uw anker wilt verbinden 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 dat u de ankernaam expliciet bij het eerste argument hoeft op te geven.

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

Expliciete ankers

U kunt de ankernaam ook rechtstreeks in de ankerfunctie gebruiken (bijvoorbeeld top: anchor(--anchor-el bottom ). Dit wordt een expliciete 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);
}

Positie-elementen ten opzichte van ankers

Diagram van ankerpositie met fysieke eigenschappen.

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

Nu is één element aan een ander element verankerd, zoals in de volgende afbeelding wordt getoond.

Schermafbeelding 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 uw anker-gepositioneerde element ten opzichte van het anker te vergemakkelijken, is er een nieuwe waarde genaamd anchor-center die kan worden gebruikt met de eigenschappen justify-self , align-self , justify-items en align-items .

In dit voorbeeld wordt het vorige voorbeeld gewijzigd door justify-self: anchor-center te gebruiken om het gepositioneerde element boven op 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;
}

Schermafbeelding van de demo.

Meerdere ankers

Elementen kunnen aan meer dan één ankerpunt worden gekoppeld. Dit betekent dat u mogelijk positiewaarden moet instellen die relatief ten opzichte van meer dan één ankerpunt zijn gepositioneerd. Doe dit door de functie anchor() te gebruiken en expliciet aan te geven naar welk ankerpunt u verwijst in het eerste argument. In het volgende voorbeeld is de linkerbovenhoek van een gepositioneerd element verankerd aan de rechteronderhoek van het ene ankerpunt, en de rechteronderhoek van het gepositioneerde element is verankerd 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);
}

Schermafbeelding van de demo.

Positie met inset-area

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

Dankzij het inzetgebied kunt u ankerposities eenvoudig ten opzichte van hun bijbehorende ankers plaatsen. De inzet werkt op een raster van 9 cellen, waarbij het verankeringselement zich in het midden bevindt.

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

Om inset-area te 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
  • Onder-midden: inset-area: bottom of inset-area: block-end
  • Rechts-midden: inset-area: right of inset-area: inline-end

Schermafbeelding van de demo.

Grootte-elementen met anchor-size()

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

De volgende CSS toont een voorbeeld van het gebruik hiervan voor hoogte, waarbij anchor-size(height) binnen een calc() functie wordt gebruikt 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);
}

Schermafbeelding van de demo.

Gebruik anker met elementen op de bovenste laag, zoals popover en dialoog

Ankerpositionering werkt ongelooflijk goed met elementen in de bovenste laag, zoals popover en <dialog> . Hoewel deze elementen in een aparte laag van de rest van de DOM-subtree worden geplaatst, kunt u ze met ankerpositionering koppelen aan elementen die zich niet in de bovenste laag bevinden en ermee meescrollen. Dit is een enorme winst voor gelaagde interfaces.

In het volgende voorbeeld wordt een set popovers met tooltips geopend met een knop. De knop is het anker en de tooltip is het gepositioneerde element. U kunt het gepositioneerde element net als elk ander verankerd element stylen. 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 inline-ing de eenvoudigste manier om dit te doen bij het genereren van dynamische content.

Schermafbeelding van de demo.

Pas ankerposities aan met @position-try

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

In het volgende voorbeeld verschijnt een submenu rechts van een menu. Menu's en submenu's maken uitstekend gebruik van de ankerpositionerings-API in combinatie met het popover-kenmerk , omdat deze menu's vaak aan een triggerknop zijn gekoppeld.

Als er horizontaal onvoldoende ruimte is voor dit submenu, kunt u het onder het menu 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 . Alles bij elkaar ziet het er zo 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 ankerpositie

Als je een basisaanpassing hebt, zoals van boven naar beneden of van links naar rechts (of beide), kun je zelfs de stap overslaan om aangepaste @position-try declaraties te maken en de ingebouwde, door de browser ondersteunde flip-trefwoorden zoals flip-block en flip-inline te gebruiken. Deze werken 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;

Flip-keywords kunnen je ankercode aanzienlijk vereenvoudigen. Met slechts een paar regels kun je een volledig functioneel anker met alternatieve posities maken:

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

position-visibility voor ankers in subscrollers

Er zijn gevallen waarin u een element mogelijk wilt verankeren binnen een subscroller van de pagina. In deze gevallen kunt u de zichtbaarheid van het anker regelen met position-visibility . Wanneer blijft het anker zichtbaar? Wanneer verdwijnt het? Met deze functie kunt u deze opties regelen. U gebruikt position-visibility: anchors-visible wanneer u wilt dat het gepositioneerde element zichtbaar 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 over de rand van de container stroomt.

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

Kenmerkdetectie en polyfilling

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

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

  /* Anchor styles here */

}

Daarnaast kunt u de ankerpositioneringsfunctie polyfillen met de CSS-ankerpositioneringspolyfill van Oddbird , die werkt in 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 verouderde syntaxis bevat. U kunt de unpkg-link gebruiken of deze rechtstreeks importeren in een pakketbeheerder.

Een opmerking over toegankelijkheid

Hoewel de API voor ankerpositionering het mogelijk maakt om elementen relatief ten opzichte van andere elementen te positioneren, creëert dit niet automatisch een betekenisvolle semantische relatie tussen de elementen. Als er daadwerkelijk een semantische relatie bestaat tussen het ankerelement en het gepositioneerde element (bijvoorbeeld: het gepositioneerde element is een zijbalkcommentaar over de ankertekst), is een manier om dat te doen door aria-details te gebruiken om van het ankerelement naar het/de gepositioneerde element(en) te verwijzen. Schermlezersoftware is nog aan het leren hoe om te gaan 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, verwerkt de browser de focusnavigatiecorrecties voor correcte toegankelijkheid. U hoeft uw popovers of dialoogvensters dus niet in DOM-volgorde te plaatsen. Lees meer over de opmerking over toegankelijkheid in de specificatie.

Conclusie

Dit is een gloednieuwe functie en we zijn benieuwd wat jullie ermee gaan bouwen. Tot nu toe hebben we een aantal erg leuke use cases uit de community gezien, zoals dynamische labels in diagrammen, verbindingslijnen, voetnoten en visuele kruisverwijzingen. Terwijl jullie experimenteren met ankerpositionering, horen we graag jullie feedback. Laat het ons weten als jullie bugs vinden.

Verder lezen