Gepubliceerd: 14 augustus 2025
Nu het Google I/O-evenementenseizoen ten einde loopt, vatten we in dit bericht de belangrijkste hoogtepunten op het gebied van CSS en Web UI samen die we dit jaar tijdens onze evenementen hebben gedeeld.
Ongelooflijk krachtige functies waar ontwikkelaars ooit alleen maar van konden dromen, zijn nu beschikbaar in browsers en bereiken sneller dan ooit tevoren compatibiliteit met andere browsers. Ondanks deze vooruitgang blijven sommige van de meest voorkomende UI-patronen echter verrassend moeilijk correct te implementeren. Je moet vaak vertrouwen op JavaScript-frameworks, complexe CSS-trucs en bergen aan aangepaste code om componenten te bouwen die ogenschijnlijk eenvoudiger zouden moeten zijn.
Het Chrome-team richt zich, in samenwerking met andere browserleveranciers, standaardisatie-instellingen zoals de CSSWG en WHATWG en communitygroepen zoals Open UI, op het daadwerkelijk eenvoudig implementeren van deze fundamentele UI-patronen.
Aanpasbare selectiemenu's
Het <select>
-element is essentieel voor formulieren, maar de interne structuur ervan werd historisch gezien afgeschermd door de browser, waardoor consistente en uitgebreide CSS-stijl vrijwel onmogelijk was. Om een betere <select>
te bouwen, is inzicht nodig in de bouwstenen ervan: de Popover API en de CSS Anchor Positioning API.
De Popover API: nu in de basislijn
Een aangepaste dropdown heeft een zwevend vak met opties nodig dat boven alle andere gebruikersinterface-elementen verschijnt, eenvoudig te negeren is en de focus correct beheert. De Popover API verwerkt dit allemaal en heeft sinds dit jaar de status Baseline Newly Available bereikt, wat betekent dat deze stabiel is in elke grote browser.
Het maken van een popover bestaat uit twee onderdelen: een triggerelement (zoals een <button>
) en het popoverelement zelf. Verbind deze door de popover een id
en het [popover]
-kenmerk te geven en vervolgens naar die id
te verwijzen in het [popovertarget]
-kenmerk van de knop.
De Popover API beheert de volledige levenscyclus van het element en biedt:
- Rendering op de bovenste laag : geen gedoe meer met de z-index.
- Optionele licht-afsluitmogelijkheden : Deze sluiten wanneer een gebruiker buiten het popover-gebied klikt.
- Automatisch focusbeheer : de browser regelt de tabbladnavigatie in en uit de pop-over.
- Toegankelijke bindingen : Het onderliggende interactie-model wordt native afgehandeld.
Het <dialog>
-element krijgt een upgrade
Hoewel popovers krachtig zijn, zijn ze niet altijd de juiste keuze. Bij paginablokkerende interacties die feedback van gebruikers vereisen, is een modale <dialog>
bijvoorbeeld geschikter.
<dialog>
miste voorheen enkele van de gemakken van [popover]
, maar dat verandert. Met het nieuwe closedby="any"
-attribuut ondersteunen modale dialoogvensters nu de functionaliteit voor het sluiten van vensters wanneer de gebruiker ergens anders klikt of op de Escape-toets drukt.
Bovendien bieden opdrachtaanroepers ( [command]
en [commandfor]
) een declaratieve, JavaScript-vrije manier om een knop aan een actie te koppelen, zoals het openen van een dialoogvenster met command="show-modal"
.
<dialog> Element + closedby=any + commando-aanroepers | [popover] kenmerk | |
---|---|---|
Primair gebruik | Modale interactie (gebruikersovereenkomsten, walkthroughs, etc.) | Tijdelijke gebruikersinterface (menu's, tooltips, kaarten, toastmeldingen) |
Licht afneembaar | Ja | Ja |
Vallen Focus | Ja | Nee |
Inerts pagina | Ja | Nee |
Declaratieve activering | Ja | Ja |
Uitvoering | Element | Attribuut |
Renders in bovenste laag | Ja | Ja |
Volledig stylebaar | Ja | Ja |
CSS-ankerpositionering
Zodra een pop-over verschijnt, moet deze worden gepositioneerd ten opzichte van het element dat deze heeft geopend. Het handmatig berekenen hiervan met JavaScript is kwetsbaar en kan de prestaties negatief beïnvloeden.
Vanaf Chrome 125 kun je de CSS Anchor Positioning API gebruiken. Deze nieuwe mogelijkheid koppelt één element declaratief aan een ander element en verwerkt automatisch de herpositionering wanneer het de rand van het scherm nadert. Deze functie maakt deel uit van Interop 2025 , een browseronafhankelijk initiatief om veelgevraagde functies te implementeren. We verwachten dat deze functie eind 2025 in alle belangrijke browsers beschikbaar zal zijn.

Hoewel je elementen expliciet kunt koppelen met de eigenschappen anchor-name
en position-anchor
, creëert een update in de specificatie en in Chrome 133 een impliciete ankerrelatie tussen een <popover>
en de aanroepende <button>
. Dit vereenvoudigt de code aanzienlijk en betekent dat je de popover nu kunt positioneren met één regel CSS, zoals: position-area: bottom span-left
.
Met de ankertool van chrome.dev leert u hoe u position-area
kunt gebruiken om de gewenste plaatsing te krijgen:
Ga nog een stap verder en laat de browser je ankers herpositioneren, zodat ze niet meer buiten het scherm vallen, door fallbacks te definiëren met position-try-fallbacks
. De volgende demo toont een pop-up die deze eigenschap gebruikt voor ingebouwde herpositioneringslogica:
Een echt aanpasbare <select>
Nu deze bouwstenen in eerdere versies aanwezig zijn, is web-native styling voor <select>
-elementen eindelijk beschikbaar in Chrome 134. Dit omvat een nieuwe eigenschap appearance
, nieuwe pseudo-elementen en het <selectedcontent>
-element.
Om de aanpassingsmogelijkheden te ontgrendelen, past u appearance: base-select;
toe op het <select>
-element en het nieuwe pseudo-element ::picker(select)
, dat zich richt op de vervolgkeuzelijst met opties. Dit maakt nieuwe interne onderdelen voor styling beschikbaar, waaronder:
-
<selectedcontent>
: Geeft de inhoud van de geselecteerde optie weer die in de knop wordt weergegeven. -
::picker-icon
: Het pictogram met de vervolgkeuzepijl -
<option>:checked
en::checkmark
: Voor het stylen van de geselecteerde optie en de bijbehorende vinkje-indicator

Dit zorgt voor rijke content binnen de opties en nauwkeurige controle over de weergave. U kunt bijvoorbeeld een pictogram en ondertitel weergeven in de optielijst, maar deze verbergen in de gesloten toestand met display: none
within selectedcontent
.
Het mooiste is dat deze API geleidelijk kan worden uitgebreid. In browsers die deze functies niet ondersteunen, krijgen gebruikers nog steeds een functionele web-native select. Je krijgt een aangepaste look, maar behoudt de ingebouwde toegankelijkheid, toetsenbordnavigatie en formulierintegratie van het web-native select-element.
Carrousels
Carrousels vind je overal op het web, en niet alleen in hero-secties. Dit omvat horizontaal scrollbare content in strakke lay-outs zoals een app store-interface. Maar het bouwen van carrousels op het web is nog steeds een uitdaging, met veel overwegingen zoals statusbeheer, scroll-jank, interactiviteit en toegankelijkheid. Maar als je erover nadenkt, zijn carrousels in wezen mooie scrollgebieden met extra gebruikersinterfacemogelijkheden.
Aan de slag met scrollers
Om een carrousel te bouwen, begin je met een lijst met items die buiten hun container vallen. Om de horizontale schuifbalk te verbergen en de inhoud scrollbaar te houden, gebruik je scrollbar-width: none
. Om de scroller "snappy" te maken, gebruik je daarnaast scroll-snap-type
en scroll-snap-align
. Deze zorgen ervoor dat items op hun plaats klikken terwijl de gebruiker scrollt.
Vorige en volgende met een ::scroll-button
Het nieuwe pseudo-element ::scroll-button()
, dat in Chrome 135 verscheen, vertelt de browser om stateful, toegankelijke "volgende" en "vorige" knoppen te genereren. De browser verwerkt automatisch de juiste ARIA-rollen en tabvolgorde en schakelt de knoppen zelfs uit wanneer u het begin of einde bereikt – allemaal zonder extra JavaScript.
Om de scrollknoppen te activeren, geeft u ze inhoud en een toegankelijk label, zoals hier:
.carousel {
&::scroll-button(left) {
content: "⬅" / "Scroll Previous";
}
&::scroll-button(right) {
content: "⮕" / "Scroll Next";
}
}

Geef deze knoppen stijl en positioneer ze ten opzichte van de bovenliggende carrousel met CSS-ankerpositionering. Dit is de aanbevolen aanpak.
Directe navigatie met ::scroll-marker
Voor puntindicatoren of miniaturen koppelen de pseudo-elementen ::scroll-marker
en ::scroll-marker-group
navigatiemarkeringen rechtstreeks aan de items in uw scrollcontainer. De browser behandelt de groep als een tablist
en verwerkt de toetsenbordnavigatie.
Net als bij scrollknoppen, initieer je de scrollmarkeringen door je aan te melden met de content
eigenschap en geef je een toegankelijk label. In het volgende voorbeeld wordt een data-attribuut gebruikt om het label voor de scrollmarkering in te stellen. Positioneer de scrollmarkten daarnaast in ::scroll-marker-group
met behulp van de scroll-marker-group
eigenschap. Style ten slotte de actieve markering met de nieuwe pseudo-klasse :target-current
. Hier is een voorbeeld van hoe dit eruit zou kunnen zien voor een eenvoudige carrousel:
.carousel {
scroll-marker-group: after;
> li::scroll-marker {
content: ''/ attr(data-name);
}
> li::scroll-marker:target-current {
background: blue;
}
}

Scroll-status query's
Met nieuwe scroll-gerelateerde CSS-functies kun je dynamischere en interactievere carrousels maken. De scroll-state query is een nieuwe mediaquery die wordt toegepast op basis van de status van een scroller. Er zijn drie verschillende typen scroll-state query's, die toegankelijk zijn via scroll-state()
in een @container
statement. Deze zijn:
-
scroll-state(snapped)
: Komt overeen wanneer een element zich in de "snapped" positie bevindt. In carrousels is dat wanneer het element in het midden van de carrousel is gesnapt. -
scroll-state(stuck)
: Geef een element de stijl, zoals een header, wanneer het bovenliggende element 'sticky' wordt. -
scroll-state(scrollable)
: Voeg visuele indicatoren toe, zoals een fade, om aan te geven dat er nog meer inhoud is om naartoe te scrollen.
Alles bij elkaar brengen
Een combinatie van nieuwe CSS-carrousel-primitieven, scroll-state queries en ankerpositionering maakt het eenvoudiger om aangepaste en interactieve carrousels te bouwen. Ga nog een stap verder door scroll-gestuurde animaties te integreren en deze direct aan de scrollpositie te koppelen. Zo creëer je performante effecten, zoals het schalen en vervagen van items terwijl ze in beeld komen. Deze animaties lopen los van de hoofdthread, wat zorgt voor een zijdezachte ervaring.
Deze interactieve carrousel combineert scroll-state()
query's, ::scroll-button
, ::scroll-marker
, CSS-ankerpositionering :target-current
.
Bovendien kunt u een nieuwe eigenschap genaamd interactivity
gebruiken om gebruikers te helpen zich te concentreren op de actieve inhoud. interactivity: inert
kan de gebruiker inertheid toepassen met behulp van CSS, waardoor carrouselitems buiten het scherm niet meer kunnen worden gefocust en uit de toegankelijkheidsboom worden verwijderd.
Meer informatie over CSS-carrousels .
Interactieve zweefkaarten
Hovercards – de uitgebreide pop-ups die verschijnen wanneer je met de muis over een gebruikersnaam of link beweegt – zijn ongelooflijk handig, maar notoir lastig om correct te bouwen. Het kost een toegewijd team maanden om de vertragingen, gebeurtenisafhandeling en ondersteuning voor meerdere apparaten goed te krijgen. Maar we werken aan een nieuwe declaratieve oplossing die dit probleem voor eens en altijd zou moeten oplossen.
Door interesse geactiveerde popovers met [interestfor]
De kern van declaratieve hovercards is het [interestfor]
-attribuut. Deze nieuwe functie biedt de kracht van popovers, maar activeert ze op basis van de "interesse" van de gebruiker. Gebruikersinteresse op een pointerapparaat kan bijvoorbeeld bestaan uit een cursor-hover, tabbladnavigatie met een toetsenbord of lang indrukken of tikken op touchscreens. De mobiele interactie moet nog worden opgelost.
Om een klikgebaseerde pop-over om te zetten in een interessegebaseerde, bouwt u een aanroepend element, dat een <button>
of een <a>
kan zijn, en geeft u dit een [interestfor]
-kenmerk dat gelijk is aan de id
van het [popover]
-element. In HTML ziet het er zo uit:
<button interestfor="profile-callout">
...
</button>
<div id="profile-callout" popover>
...
</div>
De browser verwerkt alle complexe gebeurtenislogica, waaronder:
- Gebeurtenissen in- en uitschakelen: invoer met de muis op apparaten met een fijne aanwijzer, tabbladnavigatie met het toetsenbord, lang indrukken of aanraken op apparaten met een grove aanwijzer.
- Gebeurtenisvertragingen: beheer de in- en uitgangsvertragingen met één enkele CSS-eigenschap.
Deze functie ondersteunt andere popover-functies, zoals ondersteuning voor de bovenste laag, waarbij de popover wordt weergegeven op een nieuwe laag boven de rest van de DOM-boom. De semantische componentbindingen en het onderliggende toegankelijkheidsboommodel worden native afgehandeld.
Styling van interesse-opwekkers
Interest-invokers bevatten enkele nieuwe mogelijkheden. Een daarvan is de mogelijkheid om in- en uitloopvertragingen te regelen met een CSS-eigenschap: interest-target-delay
. Een andere is de mogelijkheid om het aanroepende element te stylen op basis van of het interesse heeft of niet, met behulp van de pseudo-klasse :has-interest
.
[interesttarget] {
interest-target-delay: 0s 1s;
&:has-interest {
background: yellow;
}
}
popover="hint"
en multifunctionele gebruikersinterface
Een belangrijk puzzelstukje voor interesse-opwekkers is een nieuw popovertype: popover="hint"
. Het belangrijkste verschil met andere popovers is dat een hint-popover andere popovers niet sluit wanneer deze wordt geopend. Dit is perfect voor tooltips of voorbeeldkaarten die moeten verschijnen zonder een reeds geopend menu of chatvenster te sluiten.
Browser Support
popover=auto | popover=manual | popover=hint | |
---|---|---|---|
Licht sluiten (via klik-weg of esc toets) | Ja | Nee | Ja |
Sluit andere popover=auto -elementen wanneer deze worden geopend | Ja | Nee | Nee |
Sluit andere popover=hint -elementen wanneer deze geopend zijn | Ja | Nee | Ja |
Sluit andere popover=manual elementen wanneer geopend | Nee | Nee | Nee |
Kan popover openen en sluiten met JS ( showPopover() of hidePopover() ) | Ja | Ja | Ja |
Standaard focusbeheer voor volgende tabstop | Ja | Ja | Ja |
Kan worden verborgen of in-/uitgeschakeld met popovertargetaction | Ja | Ja | Ja |
Kan binnen de bovenliggende popover worden geopend om de bovenliggende popover open te houden | Ja | Ja | Ja |
Hiermee kun je declaratief een krachtige, multifunctionele gebruikersinterface bouwen. Eén knop kan nu een automatische pop-up hebben met popovertarget
voor de primaire klikactie (zoals het openen van een meldingenpaneel) en een pop-up met hints die je interesses oproepen om een handige tooltip te tonen bij het bewegen van de muisaanwijzer.
De toekomst is declaratief
De hier besproken functies vertegenwoordigen een fundamentele verschuiving naar een krachtiger en declaratiever webplatform. Door de browser het complexe, repetitieve werk van statusbeheer en toegankelijkheid te laten afhandelen, kunnen we bergen JavaScript verwijderen, de prestaties verbeteren en ons richten op waar we het beste in zijn: het creëren van innovatieve en boeiende gebruikerservaringen. Dit is echt een gouden tijdperk voor web-UI's, en het is nog maar net begonnen. Volg ons hier terwijl we werken aan een krachtiger web, dat nog eenvoudiger is gemaakt.
Verdere bronnen: