Het nieuwste op het gebied van CSS en web-UI: I/O 2024 samenvatting

Het webplatform bruist van de innovatie, met CSS en web-UI-functies in de voorhoede van deze spannende evolutie. We leven in een gouden tijdperk voor web-UI, met nieuwe CSS-functies die in een ongekend tempo in browsers verschijnen en een wereld aan mogelijkheden openen voor het creëren van prachtige en boeiende webervaringen. Deze blogpost duikt diep in de huidige stand van zaken rond CSS en verkent enkele van de meest baanbrekende nieuwe functies die de manier waarop we webapplicaties bouwen herdefiniëren. Deze functies worden live gepresenteerd tijdens Google I/O 2024.

Nieuwe interactieve ervaringen

Een webervaring is in essentie een wisselwerking tussen jou en je gebruikers – daarom is het zo belangrijk om te investeren in kwalitatieve gebruikersinteracties. We hebben gewerkt aan een aantal grote verbeteringen die mogelijkheden ontsluiten die we nog nooit eerder op het web hadden voor het navigeren binnen webpagina's en het navigeren tussen pagina's.

Scrollgestuurde animaties

Browser Support

  • Chrome: 115.
  • Rand: 115.
  • Firefox: achter een vlag.
  • Safari: 26.

Source

Zoals de naam al doet vermoeden, stelt de scroll-driven animations API je in staat om dynamische, op scrollen gebaseerde animaties te creëren zonder gebruik te hoeven maken van scroll observers of andere complexe scripts.

Maak scroll-gestuurde animaties.

Net zoals bij tijdgebaseerde animaties op het platform, kun je nu de scrollvoortgang van een scrollbalk gebruiken om een ​​animatie te starten, pauzeren en omkeren. Als je vooruit scrollt, zie je de animatie vooruitgaan, en als je achteruit scrollt, gebeurt het omgekeerde. Dit stelt je in staat om gedeeltelijke of volledige pagina-visualisaties te creëren met elementen die in en binnen het zichtbare gedeelte van de pagina animeren, ook wel bekend als scrollytelling , voor een dynamisch visueel effect.

Scroll-gestuurde animaties kunnen worden gebruikt om belangrijke content te benadrukken, gebruikers door een verhaal te leiden of simpelweg een dynamisch element aan uw webpagina's toe te voegen.

Scrollgestuurde animatie visualisatie

Live demonstratie

@keyframes appear {
  from {
    opacity: 0;
    scale: 0.8;
  }
  to {
    opacity: 1;
    scale: 1;
  }
}

img {
  animation: appear linear;
  animation-timeline: view();
  animation-range: entry 25% cover 50%;
}

De bovenstaande code definieert een eenvoudige animatie die in de viewport verschijnt door de transparantie en schaal van een afbeelding te wijzigen. De animatie wordt aangestuurd door de scrollpositie. Om dit effect te creëren, moet je eerst de CSS-animatie instellen en vervolgens de animation-timeline definiëren. In dit geval volgt de functie view() met de standaardwaarden de afbeelding ten opzichte van de scrollport (die in dit geval ook de viewport is).

Het is belangrijk om rekening te houden met browserondersteuning en gebruikersvoorkeuren, vooral met het oog op toegankelijkheid. Gebruik daarom de @supports regel om te controleren of de browser scroll-gestuurde animaties ondersteunt, en plaats je scroll-gestuurde animatie in een query met gebruikersvoorkeuren zoals @media (prefers-reduced-motion: no-preference) om de bewegingsvoorkeuren van gebruikers te respecteren. Na deze controles weet je zeker dat je stijlen werken en dat de animatie geen problemen oplevert voor de gebruiker.

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* Apply scroll-driven animations here */
  }
}

Scrollgestuurde animaties kunnen leiden tot paginavullende scrollervaringen, maar ook tot subtielere animaties, zoals een headerbalk die kleiner wordt en een schaduw toont wanneer je door een webapplicatie scrollt.

Scrollgestuurde animatie visualisatie

Live demonstratie

@keyframes shrink-name {
  from {
    font-size: 2em;
  }
  to {
    font-size: 1.5em;
  }
}

@keyframes add-shadow {
  from {
    box-shadow: none;
  }
  to {
    box-shadow: 0 4px 2px -2px gray;
  }
}

header {
  animation: add-shadow linear both;
}

h2 {
  animation: shrink-name linear both;
}

header, h2 {
  animation-timeline: scroll();
  animation-range: 0 150px;
}

Deze demo maakt gebruik van een aantal verschillende keyframe-animaties – de header, tekst, navigatiebalk en achtergrond – en past vervolgens de bijbehorende scroll-gestuurde animatie op elk element toe. Hoewel ze elk een andere animatiestijl hebben, delen ze allemaal dezelfde animatietijdlijn, de dichtstbijzijnde scrollbalk en hetzelfde animatiebereik – van de bovenkant van de pagina tot 150 pixels.

Prestatievoordelen van scrollgestuurde animaties

Deze ingebouwde API vermindert de hoeveelheid code die u moet onderhouden, of het nu gaat om aangepaste scripts die u zelf hebt geschreven of om de toevoeging van een externe afhankelijkheid. Het maakt ook het meeleveren van verschillende scroll-observatoren overbodig, wat aanzienlijke prestatievoordelen oplevert. Dit komt doordat scroll-gestuurde animaties buiten de hoofdthread werken bij het animeren van eigenschappen die in de compositor geanimeerd kunnen worden, zoals transformaties en transparantie, ongeacht of u de nieuwe API rechtstreeks in CSS gebruikt of via JavaScript-hooks.

Tokopedia gebruikt sinds kort scroll-gestuurde animaties om de productnavigatiebalk te laten verschijnen tijdens het scrollen. Het gebruik van deze API heeft aanzienlijke voordelen opgeleverd, zowel voor het beheer van de code als voor de prestaties.

De productnavigatiebalk op Tokopedia wordt aangedreven door scroll-animaties wanneer u naar beneden scrollt.

"We zijn erin geslaagd om tot 80% van onze code te verminderen in vergelijking met het gebruik van conventionele JavaScript-scrollgebeurtenissen en hebben geconstateerd dat het gemiddelde CPU-gebruik tijdens het scrollen is gedaald van 50% naar 2%. - Andy Wihalim, Senior Software Engineer, Tokopedia"

De toekomst van scroll-effecten

We weten dat deze effecten het web steeds aantrekkelijker zullen maken, en we denken nu al na over wat er nog meer zou kunnen komen. Dit omvat de mogelijkheid om niet alleen nieuwe animatietijdlijnen te gebruiken, maar ook om een ​​scrollpunt te gebruiken om het begin van een animatie te activeren, de zogenaamde scroll-getriggerde animaties.

En er komen in de toekomst nog meer scrollfuncties naar browsers. De volgende demo laat een combinatie van deze toekomstige functies zien. Er wordt gebruikgemaakt van CSS scroll-start-target om de begindatum en -tijd in de pickers in te stellen, en van de JavaScript ` scrollsnapchange gebeurtenis om de datum in de header bij te werken. Hierdoor is het heel eenvoudig om de gegevens te synchroniseren met de `scrollsnapchange`-gebeurtenis.

Bekijk de live demo op Codepen.

Je kunt dit ook uitbreiden om een ​​picker in realtime bij te werken met de JavaScript scrollsnapchanging -gebeurtenis.

Deze specifieke functies zijn momenteel alleen in de Canary-versie beschikbaar achter een vlag, maar ze ontsluiten mogelijkheden die voorheen onmogelijk of zeer moeilijk te realiseren waren op het platform en laten de toekomst van op scrollen gebaseerde interactiemogelijkheden zien.

Om meer te leren over het gebruik van scroll-gestuurde animaties, heeft ons team een ​​nieuwe videoserie gelanceerd op het Chrome for Developers YouTube-kanaal . Hierin leer je de basisprincipes van scroll-gestuurde animaties van Bramus Van Damme, inclusief hoe de functie werkt, de terminologie, verschillende manieren om effecten te creëren en hoe je effecten kunt combineren voor een rijke gebruikerservaring. Het is zeker de moeite waard om deze videoserie te bekijken.

Overgangen bekijken

We hebben zojuist een krachtige nieuwe functie besproken: animaties binnen webpagina's. Maar er is ook een krachtige nieuwe functie genaamd weergaveovergangen waarmee je tussen verschillende paginaweergaven kunt animeren en zo een naadloze gebruikerservaring kunt creëren. Weergaveovergangen voegen een nieuw niveau van vloeiendheid toe aan het web, waardoor je naadloze overgangen kunt maken tussen verschillende weergaven binnen één pagina, of zelfs tussen verschillende pagina's.

Browser Support

  • Chrome: 111.
  • Rand: 111.
  • Firefox: 144.
  • Safari: 18.

Source

Airbnb is een van de bedrijven die al experimenteert met het integreren van overgangen tussen weergaven in hun gebruikersinterface voor een soepele en naadloze navigatie-ervaring. Dit omvat de zijbalk van de advertentie-editor, het bewerken van foto's en het toevoegen van voorzieningen, allemaal binnen een vloeiende gebruikersflow.

Een overgang tussen verschillende documentweergaven, zoals te zien op Airbnb .
Het portfolio van Maxwell Barvian , met voorbeelden van vloeiende overgangen tussen verschillende perspectieven.

Hoewel deze paginavullende effecten prachtig en naadloos zijn, kun je ook micro-interacties creëren, zoals in dit voorbeeld waarbij je lijstweergave wordt bijgewerkt door gebruikersinteractie. Dit effect is eenvoudig te bereiken met behulp van weergaveovergangen.

Het snel inschakelen van weergaveovergangen in je single-page applicatie is heel eenvoudig: je hoeft alleen maar een interactie te omwikkelen met document.startViewTransition en ervoor te zorgen dat elk element dat een overgang ondergaat een view-transition-name heeft, inline of dynamisch met JavaScript tijdens het aanmaken van DOM-nodes.

Demo-visueel

Live demonstratie

document.querySelectorAll('.delete-btn').forEach(btn => {
  btn.addEventListener('click', () => {
    document.startViewTransition(() => {
      btn.closest('.card').remove();
    });
  })
});
/* Styles for the transition animation */
::view-transition-old(.card):only-child {
  animation: fade-out ease-out 0.5s;
}

Bekijk overgangsklassen

Je kunt weergaveovergangsnamen gebruiken om aangepaste animaties toe te passen op je weergaveovergang, maar dit kan omslachtig worden als veel elementen tegelijkertijd overgaan. De eerste nieuwe update voor weergaveovergangen dit jaar vereenvoudigt dit probleem en introduceert de mogelijkheid om weergaveovergangsklassen te creëren die kunnen worden toegepast op aangepaste animaties.

Browser Support

  • Chrome: 125.
  • Rand: 125.
  • Firefox: 144.
  • Safari: 18.2.

Source

Overgangstypen bekijken

Een andere belangrijke verbetering voor weergaveovergangen is de ondersteuning voor verschillende weergaveovergangstypen . Weergaveovergangstypen zijn handig wanneer u een ander soort visuele weergaveovergang wilt gebruiken bij het animeren van en naar paginaweergaven.

Browser Support

  • Chrome: 125.
  • Rand: 125.
  • Firefox: 144.
  • Safari: 18.

Source

Je wilt bijvoorbeeld dat een homepage op een andere manier naar een blogpagina animeert dan dat de blogpagina terug naar de homepage animeert. Of je wilt dat pagina's op verschillende manieren in- en uitklappen, zoals in dit voorbeeld, van links naar rechts en vice versa. Voorheen was dit omslachtig. Je kon klassen aan de DOM toevoegen om stijlen toe te passen, en moest die klassen vervolgens weer verwijderen. View-transition-types zorgen ervoor dat de browser oude overgangen automatisch opruimt, in plaats van dat je dit handmatig moet doen voordat je nieuwe overgangen start.

Opname van de pagineringsdemo . Typen bepalen welke animatie gebruikt moet worden. Stijlen worden in het stylesheet gescheiden dankzij actieve overgangstypen.

Je kunt typen instellen binnen je document.startViewTransition -functie, die nu een object accepteert. update is de callback-functie die de DOM bijwerkt, en types is een array met de typen.

document.startViewTransition({
  update: myUpdate,
  types: ['slide', 'forwards']
})

Overgangen tussen weergaven met meerdere pagina's

Wat het web zo krachtig maakt, is de enorme reikwijdte ervan. Veel applicaties bestaan ​​niet uit slechts één pagina, maar uit een robuust geheel van meerdere pagina's. Daarom zijn we zo blij om aan te kondigen dat we in Chromium 126 ondersteuning voor overgangen tussen documentweergaven in applicaties met meerdere pagina's gaan uitbrengen.

Browser Support

  • Chrome: 126.
  • Rand: 126.
  • Firefox: niet ondersteund.
  • Safari: 18.2.

Source

Deze nieuwe functionaliteit voor meerdere documenten omvat webervaringen binnen dezelfde oorsprong, zoals navigeren van web.dev naar web.dev/blog, maar niet het navigeren tussen verschillende oorsprongen, zoals navigeren van web.dev naar blog.web.dev of naar een ander domein zoals google.com.

Een van de belangrijkste verschillen met overgangen tussen pagina's binnen hetzelfde document is dat je de overgang niet hoeft te omwikkelen met document.startViewTransition() . In plaats daarvan kun je beide pagina's die bij de overgang betrokken zijn, selecteren met behulp van de CSS-regel @view-transition .

@view-transition {
  navigation: auto;
}

Voor een meer gepersonaliseerd effect kunt u JavaScript gebruiken met de nieuwe eventlisteners pageswap of pagereveal , waarmee u toegang krijgt tot het view transition-object.

Met pageswap kun je vlak voordat de oude momentopnamen worden gemaakt nog last-minute wijzigingen aanbrengen op de uitgaande pagina, en met pagereveal kun je de nieuwe pagina aanpassen voordat deze begint te renderen nadat deze is geïnitialiseerd.

window.addEventListener('pageswap', async (e) => {
    // ...
});

window.addEventListener('pagereveal', async (e) => {
    // ...
});
Weergaveovergangen in een app met meerdere pagina's. Zie de demo via de link .

In de toekomst willen we de weergaveovergangen uitbreiden, waaronder:

  • Scoped transitions : Hiermee kunt u een overgang beperken tot een DOM-substructuur, waardoor de rest van de pagina interactief blijft en meerdere weergaveovergangen tegelijkertijd kunnen worden uitgevoerd.
  • Weergaveovergangen op basis van gebaren : Gebruik sleep- of veegbewegingen om een ​​weergaveovergang tussen documenten te activeren voor een meer native-achtige ervaring op het web.
  • Navigatie-overgangen in CSS : Pas de overgang tussen pagina's rechtstreeks in uw CSS aan als alternatief voor het gebruik van pageswap en pagereveal gebeurtenissen in JavaScript. Voor meer informatie over overgangen tussen pagina's in applicaties met meerdere pagina's, inclusief hoe u deze het meest efficiënt kunt instellen met pre-rendering, kunt u de volgende presentatie van Bramus Van Damme bekijken:

Door de engine ondersteunde UI-componenten: Vereenvoudiging van complexe interacties

Het bouwen van complexe webapplicaties is geen sinecure, maar CSS en HTML ontwikkelen zich zodanig dat dit proces veel beheersbaarder wordt. Nieuwe functies en verbeteringen vereenvoudigen het maken van UI-componenten, waardoor je je kunt concentreren op het creëren van geweldige gebruikerservaringen. Dit wordt bereikt door een gezamenlijke inspanning van verschillende belangrijke standaardiseringsorganisaties en communitygroepen, waaronder de CSS Working Group, de Open UI Community Group en WHATWG (Web Hypertext Application Technology Working Group).

Een groot pijnpunt voor ontwikkelaars is een ogenschijnlijk eenvoudige vraag: de mogelijkheid om dropdownmenu's (het select-element) te stylen. Hoewel het op het eerste gezicht simpel lijkt, is dit een complex probleem dat veel onderdelen van het platform raakt; van lay-out en weergave tot scrollen en interactie, van styling voor gebruikersagenten en CSS-eigenschappen tot zelfs wijzigingen in de HTML zelf.

Selecteer met een datalijst van opties die subopties bevat, een triggerknop, een indicatorpijl en de geselecteerde optie.
Het ontleden van de onderdelen van een selectie

Een dropdownmenu bestaat uit vele onderdelen en omvat vele statussen waarmee rekening moet worden gehouden, zoals:

  • Toetsenbordtoewijzingen (om de interactie te starten/stoppen)
  • Klik hier om te sluiten
  • Actief popoverbeheer (sluit andere popovers wanneer er een wordt geopend)
  • Tab focusbeheer
  • De geselecteerde optiewaarde visualiseren
  • Pijl-interactiestijl
  • Staatsbeheer (openen/sluiten)

Het is momenteel lastig om al deze statusinformatie zelf te beheren, maar het platform maakt het ook niet makkelijk. Om dit op te lossen, hebben we de onderdelen opgesplitst en introduceren we een aantal eenvoudige functies waarmee je dropdownmenu's kunt stylen, maar die ook nog veel meer mogelijkheden bieden.

De Popover API

Allereerst hebben we een globaal attribuut genaamd popover uitgebracht, dat, zoals ik met trots kan aankondigen, een paar weken geleden de status 'nieuw beschikbaar' in de basisversie heeft bereikt.

Browser Support

  • Chrome: 114.
  • Rand: 114.
  • Firefox: 125.
  • Safari: 17.

Source

Popover-elementen zijn verborgen met display: none totdat ze worden geopend met een aanroeper, zoals een knop, of met JavaScript. Om een ​​eenvoudige popover te maken, stelt u het `popover`-attribuut in op het element en koppelt u de ID ervan aan een knop met popovertarget . Nu is de knop de aanroeper.

Demo-visueel

Live demonstratie

<button popovertarget="my-popover">Open Popover</button>

<div id="my-popover" popover>
  <p>I am a popover with more information.</p>
</div>

Doordat het popover-attribuut nu is ingeschakeld, handelt de browser veel belangrijke functionaliteiten af ​​zonder extra scripting, waaronder:

  • Promotie naar de bovenste laag : een aparte laag boven de rest van de pagina, zodat je niet hoeft te rommelen met z-index .
  • Functionaliteit voor het sluiten van het popovervenster: Klikken buiten het popovergebied sluit het popovervenster en geeft het venster zijn focus terug.
  • Standaard focusbeheer voor tabbladen: Bij het openen van de pop-up stopt het volgende tabblad binnen de pop-up.
  • Ingebouwde toetsenbordcombinaties : Door op de esc toets te drukken of twee keer te schakelen, sluit u de pop-up en krijgt u de focus terug.
  • Standaard componentbindingen: De browser koppelt een popover semantisch aan de trigger ervan.
GitHub startscherm
Menu op de GitHub- homepage.

Misschien gebruikt u deze popover-API zelfs al zonder het te beseffen. GitHub heeft popover geïmplementeerd in het "nieuw"-menu op hun homepage en in het overzicht van pull-requests. Ze hebben deze functie geleidelijk verbeterd met behulp van de popover-polyfill , ontwikkeld door Oddbird met aanzienlijke ondersteuning van Keith Cirkel van GitHub zelf, om oudere browsers te ondersteunen.

“Door over te stappen op Popover hebben we letterlijk duizenden regels code kunnen afschaffen. Popover helpt ons door de noodzaak voor ingewikkelde z-index-waarden te elimineren... Doordat de juiste toegankelijkheidsstructuur is vastgelegd met declaratief knopgedrag en ingebouwde focusfuncties, is het voor ons Design System aanzienlijk eenvoudiger om patronen op de juiste manier te implementeren.” - Keith Cirkel, Software Engineer, GitHub

Animeren van in- en uitstap-effecten

Bij pop-ups is het waarschijnlijk handig om er wat interactie aan toe te voegen. Er zijn vier nieuwe interactiefuncties die het afgelopen jaar zijn geïntroduceerd om animaties voor pop-ups te ondersteunen. Deze omvatten:

De mogelijkheid om display en content-visibility te animeren op een keyframe-tijdlijn.

De eigenschap transition-behavior met het trefwoord allow-discrete maakt overgangen van discrete eigenschappen zoals display mogelijk.

Browser Support

  • Chrome: 117.
  • Rand: 117.
  • Firefox: 129.
  • Safari: 17.4.

Source

De @starting-style regel zorgt ervoor dat instapeffecten van display: none naar de bovenste laag geanimeerd worden.

Browser Support

  • Chrome: 117.
  • Rand: 117.
  • Firefox: 129.
  • Safari: 17,5.

Source

De overlay-eigenschap om het gedrag van de bovenste laag tijdens een animatie te bepalen.

Browser Support

  • Chrome: 117.
  • Rand: 117.
  • Firefox: niet ondersteund.
  • Safari: niet ondersteund.

Source

Deze eigenschappen werken voor elk element dat je in de bovenste laag animeert, of het nu een pop-upvenster of een dialoogvenster is. Voor een dialoogvenster met een achtergrond ziet het er in totaal zo uit:

Demo-visueel

Live demonstratie

dialog, ::backdrop{
  opacity: 0;
  transition: opacity 1s, display 1s allow-discrete, overlay 1s allow-discrete;
}

[open], [open]::backdrop {
  opacity: 1;
}

@starting-style {
  [open], [open]::backdrop {
    opacity: 0;
  }
}

Stel eerst de @starting-style in, zodat de browser weet welke stijlen dit element in de DOM moet animeren. Dit geldt voor zowel het dialoogvenster als de achtergrond. Stijl vervolgens de open status voor beide elementen. Voor een dialoogvenster gebruik je hiervoor het open attribuut en voor een popover het pseudo-element ` ::popover-open . Animeer tot slot de opacity , display en overlay met behulp van het allow-discrete sleutelwoord om de animatiemodus in te schakelen waarin discrete eigenschappen kunnen overgaan.

Ankerpositionering

Popover was nog maar het begin. Een zeer interessante update is dat vanaf Chrome versie 125 ondersteuning voor anchor-positionering beschikbaar is.

Browser Support

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

Source

Met behulp van ankerpositionering kan de browser met slechts een paar regels code de logica afhandelen om een ​​gepositioneerd element aan een of meer ankerelementen te koppelen. In het volgende voorbeeld is een eenvoudige tooltip aan elke knop gekoppeld, die zich in het midden onderaan bevindt.

Demo-visueel

Live demonstratie

Stel een anker-positioneringsrelatie in CSS in door de eigenschap anchor-name te gebruiken op het ankerelement (in dit geval de knop) en de eigenschap position-anchor op het gepositioneerde element (in dit geval de tooltip). Pas vervolgens absolute of vaste positionering toe ten opzichte van het anker met behulp van de functie anchor() . De volgende code positioneert de bovenkant van de tooltip aan de onderkant van de knop.

.anchor {
  anchor-name: --my-anchor;
}

.positioned {
  position: absolute;
  position-anchor: --my-anchor;
}

Als alternatief kunt u de anchor-name direct in de anchor-functie gebruiken en de position-anchor eigenschap overslaan. Dit kan handig zijn wanneer u aan meerdere elementen wilt verankeren.

.anchor {
  anchor-name: --my-anchor;
}

.positioned {
  position: absolute;
  top: anchor(--my-anchor bottom);
}

Gebruik tot slot het nieuwe trefwoord anchor-center voor de eigenschappen justify en align om het gepositioneerde element te centreren ten opzichte van het anker.

.anchor {
  anchor-name: --my-anchor;
}

.positioned {
  position: absolute;
  top: anchor(--my-anchor bottom);
  justify-self: anchor-center;
}

Hoewel het erg handig is om ankerpositionering te gebruiken in combinatie met een popover, is een popover absoluut geen vereiste. Ankerpositionering kan met elk willekeurig tweetal (of meer) elementen worden gebruikt om een ​​visuele relatie te creëren. De volgende demo, geïnspireerd op een artikel van Roman Komarov , laat bijvoorbeeld zien hoe een onderstreepstijl wordt verankerd aan lijstitems wanneer je er met de muis overheen beweegt of er met de tabtoets overheen gaat.

Demo-visueel

Live demonstratie

Dit voorbeeld gebruikt de ankerfunctie om de ankerpositie in te stellen met behulp van de fysieke eigenschappen left , right en bottom . Wanneer je met de muis over een van de links beweegt, verandert het doelanker en verschuift de browser het doel om de positionering toe te passen. Tegelijkertijd wordt ook de kleur geanimeerd voor een fraai effect.

ul::before {
  content: "";
  position: absolute;
  left:   anchor(var(--target) left);
  right:  anchor(var(--target) right);
  bottom: anchor(var(--target) bottom);
  ...
}

li:nth-child(1) { --anchor: --item-1 }
ul:has(:nth-child(1) a:is(:hover, :focus-visible)) {
  --target: --item-1;
  --color: red;
}

positionering inset-area

Naast de standaard directionele absolute positionering die u waarschijnlijk al eerder hebt gebruikt, is er een nieuw lay-outmechanisme toegevoegd als onderdeel van de ankerpositionerings-API, genaamd insetgebied. Insetgebied maakt het eenvoudig om gepositioneerde elementen ten opzichte van hun respectievelijke ankers te plaatsen en werkt met een raster van 9 cellen, waarbij het ankerelement in het midden staat. Bijvoorbeeld: inset-area: top plaatst het gepositioneerde element bovenaan, en inset-area: bottom plaatst het gepositioneerde element onderaan.

Een vereenvoudigde versie van de eerste ankerdemo ziet er als volgt uit met inset-area :

.anchor {
  anchor-name: --my-anchor;
}

.positioned {
  position: absolute;
  position-anchor: --my-anchor;
  inset-area: bottom;
}

Je kunt deze positionele waarden combineren met `span`-keywords om te beginnen in het midden en vervolgens naar links, rechts of volledig uit te breiden om alle beschikbare kolommen of rijen te vullen. Je kunt ook logische eigenschappen gebruiken. Om dit lay-outmechanisme beter te visualiseren en te begrijpen, kun je deze tool in Chrome 125+ bekijken:

Omdat deze elementen verankerd zijn, beweegt het gepositioneerde element dynamisch mee op de pagina wanneer het ankerpunt verschuift. In dit geval hebben we dus kaartelementen in de stijl van containerqueries, die van grootte veranderen op basis van hun intrinsieke afmetingen (iets wat niet mogelijk is met mediaqueries), en het verankerde menu verschuift mee met de nieuwe lay-out wanneer de gebruikersinterface van de kaart verandert.

Demo-visueel

Live demonstratie

Dynamische ankerposities met position-try-options

Menu's en submenu's zijn veel gemakkelijker te maken met een combinatie van popover- en anchor-positionering. En wanneer je verankerde element de rand van een viewport bereikt, kun je de browser de positioneringswijziging voor je laten afhandelen. Dit kan op verschillende manieren. De eerste is door je eigen positioneringsregels te maken. In dit geval wordt het submenu aanvankelijk rechts van de "storefront"-knop geplaatst. Maar je kunt een @position-try blok maken voor het geval er niet genoeg ruimte rechts van het menu is, met een aangepaste identifier van --bottom . Vervolgens verbind je dit @position-try -blok met de anchor via position-try-options .

De browser schakelt nu tussen deze verankerde staten, waarbij eerst de rechterpositie wordt geprobeerd en vervolgens naar beneden wordt verschoven. En dit kan met een vloeiende overgang worden gedaan.

Demo-visueel

Live demonstratie

#submenu {
  position-anchor: --submenu;
  top: anchor(top);
  left: anchor(right);
  margin-left: var(--padding);

  position-try-options: --bottom;

  transition: top 0.25s, left 0.25s;
  width: max-content;
}

@position-try --bottom {
  top: anchor(left);
  left: anchor(bottom);
  margin-left: var(--padding);
}

Naast de expliciete positioneringslogica biedt de browser een aantal trefwoorden voor basisinteracties, zoals het spiegelen van je anker in het blok of inline-navigatie.

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

Voor een eenvoudige flip-ervaring kunt u gebruikmaken van deze `flip`-keywordwaarden en het schrijven van een position-try -definitie helemaal overslaan. Zo kunt u nu met slechts een paar regels CSS een volledig functioneel, locatie-responsief anker-element positioneren.

Demo-visueel

Live demonstratie

.tooltip {
  inset-area: top;
  position-try-options: flip-block;
}

Leer meer over het gebruik van ankerpositionering .

De toekomst van gelaagde UI

We zien overal gekoppelde ervaringen, en de functies die in dit bericht worden getoond, vormen een uitstekend begin om creativiteit te ontketenen en betere controle te krijgen over gepositioneerde elementen en gelaagde interfaces. Maar dit is slechts het begin. Zo werkt popover momenteel alleen met knoppen als aanroepend element, of met JavaScript. Voor iets als previews in Wikipedia-stijl, een patroon dat overal op het webplatform te zien is, moet het mogelijk zijn om te interageren met een link en een popover te activeren vanuit een link en wanneer de gebruiker interesse toont zonder dat er per se op geklikt hoeft te worden, bijvoorbeeld door te hoveren of de focus op een tabblad te zetten.

Als volgende stap voor de popover API werken we aan interesttarget om aan deze behoeften te voldoen en het gemakkelijker te maken deze ervaringen na te bootsen met de juiste toegankelijkheidsfuncties. Dit is een uitdagend toegankelijkheidsprobleem, met veel open vragen over ideaal gedrag, maar het oplossen en normaliseren van deze functionaliteit op platformniveau zou deze ervaringen voor iedereen moeten verbeteren.

<a interesttarget="my-tooltip">Hover/Focus to show the tooltip</a>

<span popover=hint id="my-toolip">This is the tooltip</span>

Daarnaast is er nog een toekomstgerichte algemene aanroeper ( invoketarget ) beschikbaar om te testen in Canary, dankzij het werk van twee externe ontwikkelaars, Keith Cirkel en Luke Warlow. invoketarget ondersteunt de declaratieve ontwikkelaarservaring die popovertarget biedt voor popovers, genormaliseerd voor alle interactieve elementen, waaronder <dialog> , <details> , <video> , <input type="file"> en meer.

<button invoketarget="my-dialog">
  Open Dialog
</button>

<dialog id="my-dialog">
  Hello world!
</dialog>

We weten dat er gebruiksscenario's zijn die nog niet door deze API worden gedekt. ​​Bijvoorbeeld het stylen van de pijl die een verankerd element met zijn anker verbindt, met name wanneer de positie van het verankerde element verandert, en het mogelijk maken dat een element "schuift" en in het zichtbare gedeelte van het scherm blijft in plaats van naar een andere positie te springen die wordt ingesteld wanneer het de begrenzingsbox bereikt. Hoewel we dus enthousiast zijn over de implementatie van deze krachtige API, kijken we er ook naar uit om de mogelijkheden ervan in de toekomst verder uit te breiden.

Stijlbaar selecteren

Door popover en anchor te combineren, heeft het team vooruitgang geboekt met het realiseren van een aanpasbare selectiedropdown. Het goede nieuws is dat er veel vooruitgang is geboekt. Het slechte nieuws is dat deze API zich momenteel nog in een experimentele fase bevindt. Ik ben echter enthousiast om enkele live demo's en updates over onze voortgang te delen en hoop op jullie feedback. Ten eerste is er vooruitgang geboekt met de manier waarop gebruikers zich kunnen aanmelden voor de nieuwe, aanpasbare selectie-ervaring. De huidige, nog in ontwikkeling zijnde manier om dit te doen, is door een `appearance`-eigenschap in CSS in te stellen op appearance: base-select . Zodra `appearance` is ingesteld, meldt u zich aan voor een nieuwe, aanpasbare selectie-ervaring.

select {
  appearance: base-select;
}

Naast de appearance: base-select zijn er ook een paar nieuwe HTML-updates. Zo kun je je opties in een datalist plaatsen voor aanpassing en kun je willekeurige, niet-interactieve content zoals afbeeldingen aan je opties toevoegen. Je krijgt ook toegang tot een nieuw element, <selectedoption> , dat de inhoud van de opties weergeeft en die je vervolgens naar eigen wens kunt aanpassen. Dit element is erg handig.

Demo-visueel

vlagdemonstratie

Live demonstratie

<select>
  <button type=popover>
    <selectedoption></selectedoption>
  </button>
  <datalist>
    <option value="" hidden>
      <p>Select a country</p>
    </option>
    <option value="andorra">
      <img src="Flag_of_Andorra.svg" />
      <p>Andorra</p>
    </option>
    <option value="bolivia">
      <img src="Flag_of_Bolivia.svg" />
      <p>Bolivia</p>
    </option>
...
  </datalist>
</select>

De volgende code laat zien hoe je <selectedoption> in de Gmail-interface kunt aanpassen. Een visueel pictogram geeft het geselecteerde antwoordtype weer om ruimte te besparen. Je kunt basisweergavestijlen gebruiken binnen selectedoption om de opmaak van de optie te onderscheiden van de voorvertoning. In dit geval kan tekst die in de optie wordt weergegeven, visueel worden verborgen in ` selectedoption .

Demo-visueel

Gmail-demo

Live demonstratie

selectedoption .text {
  display: none;
}

Een van de grootste voordelen van het hergebruiken van het <select> -element voor deze API is de achterwaartse compatibiliteit. In dit landselectieveld ziet u een aangepaste gebruikersinterface met vlagafbeeldingen in de opties, waardoor de inhoud gemakkelijker te interpreteren is voor de gebruiker. Omdat browsers die de API niet ondersteunen de regels negeren die ze niet begrijpen, zoals de aangepaste knop, datalist, selectedoption en afbeeldingen in de opties, zal de fallback vergelijkbaar zijn met de huidige standaard gebruikersinterface van het selectieveld.

Niet-ondersteunde browsers krijgen de huidige selectie-ervaring te zien.
De visuele weergave van een ondersteunde browser aan de linkerkant, en de alternatieve weergave voor niet-ondersteunde browsers aan de rechterkant.

Met aanpasbare selecties zijn de mogelijkheden eindeloos. Ik ben vooral dol op deze landkiezer in Airbnb-stijl, omdat de stijl slim is afgestemd op responsive design. Dit en nog veel meer kun je doen met de binnenkort verschijnende, aanpasbare selectie, waardoor het een zeer welkome toevoeging aan het webplatform is.

Demo-visueel

Live demonstratie

Exclusieve accordeon

Het oplossen van de stylingproblemen met select-elementen (en alles wat daarbij komt kijken) is niet het enige UI-onderdeel waar het Chrome-team zich op heeft gericht. De eerste extra componentupdate is de mogelijkheid om exclusieve accordions te creëren, waarbij slechts één item in de accordion tegelijk geopend kan worden.

Browser Support

  • Chrome: 120.
  • Rand: 120.
  • Firefox: 130.
  • Safari: 17.2.

Dit kan door dezelfde naamwaarde toe te passen op meerdere detailelementen, waardoor een verbonden groep details ontstaat, vergelijkbaar met een groep keuzerondjes.

Exclusieve accordeondemonstratie
<details name="learn-css" open>
  <summary>Welcome to Learn CSS!</summary>
</details>

<details name="learn-css">
  <summary>Box Model</summary>
  <p>...</p>
</details>

<details name="learn-css">
  <summary>Selectors</summary>
  <p>...</p>
</details>

:user-valid en :user-invalid

Een andere verbetering van de UI-componenten zijn de pseudo-klassen :user-valid en :user-invalid . Deze zijn sinds kort stabiel in alle :user-valid en gedragen zich vergelijkbaar met de pseudo-klassen :valid en :invalid :user-invalid maar komen pas overeen met een formulierbesturingselement nadat een gebruiker significant met het invoerveld heeft gecommuniceerd. Dit betekent dat er aanzienlijk minder code nodig is om te bepalen of er interactie is geweest met een formulierwaarde, of dat deze "gewijzigd" is geraakt. Dit kan erg nuttig zijn voor het geven van feedback aan de gebruiker en vermindert de hoeveelheid scriptwerk die hiervoor in het verleden nodig was.

Browser Support

  • Chrome: 119.
  • Rand: 119.
  • Firefox: 88.
  • Safari: 16.5.

Source

Demo-screencast

Live demonstratie

input:user-valid,
select:user-valid,
textarea:user-valid {
    --state-color: green;
    --bg: linear-gradient(...);
}

input:user-invalid,
select:user-invalid,
textarea:user-invalid {
    --state-color: red;
    --bg: linear-gradient(...);
}

Leer meer over het gebruik van pseudo-elementen user-* voor formuliervalidatie .

field-sizing: content

Een andere handige componentupdate die onlangs is uitgebracht, is field-sizing: content , die kan worden toegepast op formulierbesturingselementen zoals inputvelden en tekstvakken. Hiermee kan de grootte van het invoerveld meegroeien (of krimpen) afhankelijk van de inhoud. field-sizing: content kan met name handig zijn voor tekstvakken, omdat je niet langer gebonden bent aan vaste afmetingen waarbij je mogelijk omhoog moet scrollen om te zien wat je eerder in je prompt hebt geschreven in een te klein invoerveld.

Browser Support

  • Chrome: 123.
  • Rand: 123.
  • Firefox: niet ondersteund.
  • Safari Technology Preview: ondersteund.

Source

Demo-screencast

Live demonstratie

textarea, select, input {
  field-sizing: content;
}

Leer meer over veldafmetingen .

<hr> in <select>

De mogelijkheid om het <hr> -element, oftewel de horizontale lijn, in selectielijsten in te schakelen, is een andere kleine maar nuttige componentfunctie. Hoewel dit niet veel semantisch nut heeft, helpt het wel om content binnen een selectielijst netjes te scheiden, met name content die je misschien niet per se wilt groeperen met een optgroup, zoals een placeholderwaarde.

Selecteer schermafbeelding

Screenshot van hr in select met een licht en donker thema in Chrome

Selecteer Live Demo

<select name="majors" id="major-select">
  <option value="">Select a major</option>
  <hr>
  <optgroup label="School of Fine Arts">
    <option value="arthist">
Art History
  </option>
  <option value="finearts">
    Fine Arts
  </option>
...
</select>

Leer meer over het gebruik van hr in select

Verbeteringen in de levenskwaliteit

We zijn constant bezig met verbeteringen, en dat geldt niet alleen voor interacties en componenten. Er zijn het afgelopen jaar ook veel andere updates doorgevoerd die de gebruiksvriendelijkheid verhogen.

Nestelen met vooruitblik

Native CSS-nesting werd vorig jaar in alle browsers geïntroduceerd en is sindsdien verbeterd met ondersteuning voor lookahead, waardoor de & voor elementnamen niet langer vereist is. Dit maakt nesting veel ergonomischer en vergelijkbaar met wat ik in het verleden gewend was.

Browser Support

  • Chrome: 120.
  • Rand: 120.
  • Firefox: 117.
  • Safari: 17.2.

Source

Een van de dingen die ik het fijnst vind aan geneste CSS is dat je componenten visueel kunt blokkeren en binnen die componenten statussen en modifiers kunt opnemen, zoals containerqueries en mediaqueries. Voorheen plaatste ik al deze queries onderaan het bestand om ze overzichtelijk te houden. Nu kun je ze op een logische manier schrijven, direct naast de rest van je code.

.card {
  /* card base styles */

  h2 {
    /* child element style */
  }

  &.highlight {
    /* modifier style */
  }

  &:hover, &:focus {
    /* state styles */
  }

  @container (width >= 300px) {
    /* container query styles */
  }
}

Lijn de inhoud uit voor de blokindeling

Een andere erg prettige verandering is de mogelijkheid om centreermechanismen zoals align-content te gebruiken in bloklay-outs. Dit betekent dat je nu dingen kunt doen zoals verticaal centreren binnen een `div` zonder dat je `flex` of `grid`-lay-out hoeft toe te passen, en zonder ongewenste neveneffecten zoals het voorkomen van `margin-collapse`, die je misschien niet wilt van die lay-outalgoritmes.

Browser Support

  • Chrome: 123.
  • Rand: 123.
  • Firefox: 125.
  • Safari: 17.4.

Schermafbeelding

Live demonstratie

div {
  align-content: center;
}

Tekstterugloop: evenwichtig en mooi

Over de opmaak gesproken, de tekstopmaak is flink verbeterd met de toevoeging van text-wrap: balance en `text-wrap: pretty . text-wrap: balance zorgt voor een meer uniforme tekstblok, terwijl text-wrap: pretty zich richt op het verminderen van het aantal afzonderlijke tekens op de laatste regel van de tekst.

Demo-screencast

Live demonstratie

In de volgende demo kunt u, door de schuifregelaar te verslepen, de effecten van balance en pretty op een kop en een alinea vergelijken. Probeer de demo eens in een andere taal te vertalen!
h1 {
  text-wrap: balance;
}

Leer meer over tekstterugloop: balans .

Internationale typografie-updates

De typografische opmaak van CJK-tekstfuncties is het afgelopen jaar flink verbeterd, zoals de functie word-break: auto-phrase die de regel automatisch afbreekt bij de natuurlijke grens van een zin.

Browser Support

  • Chrome: 119.
  • Rand: 119.
  • Firefox: niet ondersteund.
  • Safari: niet ondersteund.

word-break: auto-phrase breekt de regel af bij de natuurlijke zinsgrens.
Vergelijking van word-break: normal en word-break: auto-phrase

En text-spacing-trim , dat spatiëring tussen leestekens toepast om de leesbaarheid van Chinese, Japanse en Koreaanse typografie te verbeteren voor een visueel aantrekkelijker resultaat.

Browser Support

  • Chrome: 123.
  • Rand: 123.
  • Firefox: niet ondersteund.
  • Safari: niet ondersteund.

Source

De rechterhelft van de CJK-punt wordt verwijderd met text-spacing-trim.
Als leestekens achter elkaar voorkomen, moet de rechterhelft van de CJK-punt worden verwijderd.

Syntaxis voor relatieve kleuren

Op het gebied van kleurenthema's zagen we een grote update met betrekking tot de syntaxis voor relatieve kleuren.

In this example, the colors here use Oklch-based theming. As the hue-value adjusts based on the slider, the entire theme changes. This can be achieved with relative color syntax. The background uses the primary color, based on the hue, and adjusts the lightness, chroma, and hue channels to adjust its value. --i is the sibling index in the list for the gradation of values, showing how you can combine stepping with custom properties and relative color syntax to build themes.

Demo Screencast

Live demonstratie

In the following demo you can compare by dragging the slider, the effects of balance and pretty on a heading and a paragraph. Try translating the demo into another language!
:root {
  --hue: 230;
  --primary: oklch(70% .2 var(--hue));
}

li {
  --_bg: oklch(from var(--primary)
    calc(l - (var(--i) * .05))
    calc(c - (var(--i) * .01))
    calc(h - (var(--i) + 5)));
}

light-dark() function

Along with the light-dark() function, theming has become much more dynamic and simplified.

Browser Support

  • Chrome: 123.
  • Edge: 123.
  • Firefox: 120.
  • Safari: 17.5.

Source

The light-dark() function is an ergonomic improvement that simplifies color theming options so that you can write theme styles in a more concise way, as demonstrated so nicely in this visual diagram by Adam Argyle. Before, you would need two different blocks of code, (your default theme and a user preference query), to set up theme options. Now, you can write these style options for both light and dark themes in the same line of CSS using the light-dark() function.

Visualization of light-dark() . See demo for more.
html {
  color-scheme: light dark;
}

button {
    background-color: light-dark(lightblue, darkblue);
}

If the user selected a light theme, the button will have a light blue background. If the user selected a dark theme, the button will have a dark blue background.

:has() selector

And I would be remiss to talk about modern UI without mentioning one of the most impactful interop highlights from the past year, which has to be the :has() selector, landing across browsers in December of last year. This API is a game-changer for writing logical styles.

Browser Support

  • Chrome: 105.
  • Edge: 105.
  • Firefox: 121.
  • Safari: 15.4.

Source

The :has() selector enables you to check if a child element has specific children, or if those children are in a specific state, and essentially can function as a parent selector as well.

Demo of has() being used to style comparison blocks on Tokopedia .

:has() has already shown to be particularly useful for many companies , including PolicyBazaar, who use :has() to style blocks based on their interior content, such as in the compare section, where the style adjusts if there is a plan to compare in the block, or if its empty.

“With the :has() selector, we were able to eliminate JavaScript based validation of the user's selection and replace it with a CSS solution which is working seamlessly for us with the same experience as before.–Aman Soni, Tech Lead, PolicyBazaar”

Containerquery's

Another key addition to the web that is now newly available and growing in usage is container queries, which enable the ability to query an element parent's intrinsic size to apply styles: a much more fine-toothed comb than media queries, which only query the viewport size.

Browser Support

  • Chrome: 105.
  • Edge: 105.
  • Firefox: 110.
  • Safari: 16.

Source

Angular recently launched a beautiful new documentation site on angular.dev using container queries to style the header blocks based on their available space on the page. So even if the layout changes, and goes from a multicolumn sidebar layout to a single-column layout, the header blocks can self-adjust.

Angular.dev site showcasing container queries in the header cards.

Without container queries, doing something like this was quite hard to achieve, and damaging for performance, requiring resize observers and element observers. Now, it's trivial to style an element based on its parent size.

Demo Screencast

Live demonstratie

Recreating the Angular header card container query.

@property

And finally very soon, we are excited to see @property land in Baseline. This is a key feature for providing semantic meaning to CSS custom properties (also known as CSS variables), and enables a slew of new interaction features. @property also enables contextual meaning, typechecking, defaults, and fallback values in CSS. Opening the doors for even more robust features like range style queries. This is a feature that was never possible before, and now provides so much depth to the language of CSS.

Browser Support

  • Chrome: 85.
  • Edge: 85.
  • Firefox: 128.
  • Safari: 16.4.

Source

Demo Screencast

Live demonstratie

@property --card-bg {
  syntax: "<color>";
  inherits: false;
  initial-value: #c0bae8;
}

Conclusie

With all of these new powerful UI capabilities landing across browsers, the possibilities are endless. Novel interactive experiences with scroll-driven animations and view transitions make the web more fluid and interactive in ways we've never seen before. And next level UI components make it easier than ever to build robust, beautifully customized components without ripping out the entire native experience. And finally, quality of life improvements in architecture, layout, typography, and responsive design not only solve the little big things, but also give developers the tools they need to build complex interfaces that work on a variety of devices, form factors, and user needs.

These new features you should be able to remove third-party scripting for performance-heavy features like scrollytelling and tethering elements to each other with anchor positioning, build fluid page transitions, finally style dropdowns, and improve the overall structure of your code natively.

It's never been a better time to be a web developer. There hasn't been so much energy and excitement since the announcement of CSS3. Features we've needed but have only dreamed of actually landing in the past, are finally becoming a reality and a part of the platform. And it's because of your voice that we're able to prioritize and finally bring these capabilities to life. We're working on making it easier to do the hard, tedious stuff natively so you can spend more time building the things that matter–like the core features and design details that set your brand apart.

To learn more about these new features as they land, follow along at developer.chrome.com and web.dev, where our team shares the latest news in web technologies. Try out scroll driven animations, view transitions, anchor positioning, or even the stylable select, and let us know what you think. We're here to listen and we're here to help.