Beweging is een kernonderdeel van elke digitale ervaring en begeleidt uw gebruiker van de ene interactie naar de volgende. Maar er zijn een paar hiaten in vloeiende animaties op het webplatform. Deze omvatten de mogelijkheid om eenvoudig animaties bij binnenkomst en vertrek te animeren, en om soepel van en naar de bovenste laag te animeren voor verwijderbare elementen zoals dialogen en popovers.
Om deze hiaten op te vullen, bevatten Chrome 116 en 117 vier nieuwe webplatformfuncties, die vloeiende animaties en overgangen voor discrete eigenschappen mogelijk maken.
Deze vier nieuwe functies omvatten:
- De mogelijkheid om
display
encontent-visibility
te animeren op een keyframe-tijdlijn (vanaf Chrome 116). - De eigenschap
transition-behavior
met het sleutelwoordallow-discrete
om overgangen van discrete eigenschappen zoalsdisplay
mogelijk te maken (vanaf Chrome 117). - De
@starting-style
om invoereffecten vandisplay: none
en in de bovenste laag (vanaf Chrome 117). - De
overlay
eigenschap om het gedrag van de bovenste laag tijdens een animatie te regelen (vanaf Chrome 117).
Geef animaties weer in keyframes
Vanaf Chrome 116 kunt u display
en content-visibility
gebruiken in sleutelframeregels. Deze zullen dan wisselen op het moment dat het keyframe optreedt. Er zijn geen aanvullende nieuwe waarden vereist om dit te ondersteunen:
.card {
animation: fade-out 0.5s forwards;
}
@keyframes fade-out {
100% {
opacity: 0;
display: none;
}
}
In het voorgaande voorbeeld wordt de dekking gedurende een periode van 0,5 seconde naar 0 geanimeerd en vervolgens wordt de weergave op nul ingesteld. Bovendien zorgt het trefwoord forwards
ervoor dat de animatie in de eindstatus blijft, zodat het element waarop het wordt toegepast, display: none
en opacity: 0
.
Dit is een eenvoudig voorbeeld dat nabootst wat u met een transitie kunt doen (zie demo in de sectie Overgang ). Overgangen kunnen echter geen complexere animaties maken, zoals in het volgende voorbeeld:
.card {
animation: spin-and-delete 1s ease-in forwards;
}
@keyframes spin-and-delete {
0% {
transform: rotateY(0);
filter: hue-rotate(0);
}
80% {
transform: rotateY(360deg);
filter: hue-rotate(180deg);
opacity: 1;
}
100% {
opacity: 0;
display: none;
}
}
De spin-and-delete
-animatie is een exit-animatie. Eerst draait de kaart op de y-as, doorloopt hij een tintrotatie en vervolgens met 80%
door de tijdlijn, verandert de dekking van 1 naar 0. Ten slotte wisselt de kaart van display: block
naar display: none
.
Voor deze exit-animaties kunt u, in plaats van ze rechtstreeks op een element toe te passen, een trigger voor de animaties instellen. Bijvoorbeeld door een gebeurtenislistener aan een knop te koppelen die een klasse activeert om de animatie toe te passen, zoals:
.spin-out {
animation: spin-and-delete 1s ease-in forwards;
}
document.querySelector('.delete-btn').addEventListener('click', () => {
document.querySelector('.card').classList.add('spin-out');
})
Het bovenstaande voorbeeld heeft nu de eindstatus display:none
. Er zijn veel gevallen waarin u verder wilt gaan en het DOM-knooppunt met een time-out wilt verwijderen, zodat de animatie eerst kan worden voltooid.
Overgang van discrete animaties
Anders dan bij het animeren van discrete eigenschappen met keyframes, moet u voor het overzetten van discrete eigenschappen de gedragsmodus allow-discrete
overgangen gebruiken.
De eigenschap transition-behavior
De allow-discrete
modus maakt discrete overgangen mogelijk, en is een waarde van de eigenschap transition-behavior
. transition-behavior
accepteert twee waarden: normal
en allow-discrete
.
.card {
transition: opacity 0.25s, display 0.25s;
transition-behavior: allow-discrete; /* Note: be sure to write this after the shorthand */
}
.card.fade-out {
opacity: 0;
display: none;
}
De transition
steno stelt deze waarde ook in, dus u kunt de eigenschap weglaten en in plaats daarvan het trefwoord allow-discrete
aan het einde van de transition
steno voor elke transitie gebruiken.
.card {
transition: opacity 0.5s, display 0.5s allow-discrete;
}
.card.fade-out {
opacity: 0;
display: none;
}
Als u meerdere afzonderlijke eigenschappen animeert, moet u allow-discrete
toevoegen na elke eigenschap die u wilt animeren. Bijvoorbeeld:
.card {
transition: opacity 0.5s, display 0.5s allow-discrete, overlay 0.5s allow-discrete;
}
.card.fade-out {
opacity: 0;
display: none;
}
De @starting-style
voor invoeranimaties
Tot nu toe heeft dit artikel exit-animaties behandeld. Om entry-animaties te maken, moet je de @starting-style
regel gebruiken.
Gebruik @starting-style
om een stijl toe te passen die de browser kan opzoeken voordat het element op de pagina wordt geopend. Dit is de 'before-open'-status (waarvandaan je animeert).
/* 0. IS-OPEN STATE */
/* The state at which the element is open + transition logic */
.item {
height: 3rem;
display: grid;
overflow: hidden;
transition: opacity 0.5s, transform 0.5s, height 0.5s, display 0.5s allow-discrete;
}
/* 1. BEFORE-OPEN STATE */
/* Starting point for the transition */
@starting-style {
.item {
opacity: 0;
height: 0;
}
}
/* 2. EXITING STATE */
/* While it is deleting, before DOM removal in JS, apply this
transformation for height, opacity, and a transform which
skews the element and moves it to the left before setting
it to display: none */
.is-deleting {
opacity: 0;
height: 0;
display: none;
transform: skewX(50deg) translateX(-25vw);
}
Nu heb je zowel een entry- als een exit-status voor deze TODO-lijstitems:
Animatie van elementen van en naar de bovenste laag
Om elementen van en naar de bovenste laag te animeren, specificeert u de @starting-style
in de status "open" om de browser te vertellen waar vandaan moet worden geanimeerd. Voor een dialoog wordt de open status gedefinieerd met het [open]
attribuut. Gebruik voor een popover de :popover-open
pseudo-klasse.
Een eenvoudig voorbeeld van een dialoogvenster zou er als volgt uit kunnen zien:
/* 0. IS-OPEN STATE */
dialog[open] {
translate: 0 0;
}
/* 1. BEFORE-OPEN STATE */
@starting-style {
dialog[open] {
translate: 0 100vh;
}
}
/* 2. EXIT STATE */
dialog {
transition: translate 0.7s ease-out, overlay 0.7s ease-out allow-discrete, display 0.7s ease-out allow-discrete;
translate: 0 100vh;
}
In het volgende voorbeeld zijn de entry- en exit-effecten verschillend. Ga naar binnen door vanaf de onderkant van de viewport naar boven te animeren en verlaat het effect naar de bovenkant van de viewport. Het is ook geschreven met geneste CSS voor meer visuele inkapseling.
Wanneer u een popover animeert, gebruikt u de :popover-open
pseudo-klasse in plaats van het eerder gebruikte open
-attribuut.
.settings-popover {
&:popover-open {
/* 0. IS-OPEN STATE */
/* state when popover is open, BOTH:
what we're transitioning *in* to
and transitioning *out* from */
transform: translateY(0);
opacity: 1;
/* 1. BEFORE-OPEN STATE */
/* Initial state for what we're animating *in* from,
in this case: goes from lower (y + 20px) to center */
@starting-style {
transform: translateY(20px);
opacity: 0;
}
}
/* 2. EXIT STATE */
/* Initial state for what we're animating *out* to ,
in this case: goes from center to (y - 50px) higher */
transform: translateY(-50px);
opacity: 0;
/* Enumerate transitioning properties,
including display and allow-discrete mode */
transition: transform 0.5s, opacity 0.5s, display 0.5s allow-discrete;
}
overlay
eigenschap
Als u ten slotte een popover
of dialog
uit de bovenste laag wilt vervagen, voegt u de eigenschap overlay
toe aan uw lijst met overgangen. popover
en dialog
ontsnappen aan voorouderclips en transformaties, en plaatsen de inhoud ook in de bovenste laag. Als u overlay
niet overschakelt, wordt uw element onmiddellijk weer geknipt, getransformeerd en bedekt, en ziet u de overgang niet gebeuren.
[open] {
transition: opacity 1s, display 1s allow-discrete;
}
Neem in plaats daarvan overlay
op in de overgang of animatie om overlay
samen met de rest van de functies te animeren en ervoor te zorgen dat deze tijdens het animeren in de bovenste laag blijft. Dit zal er veel soepeler uitzien.
[open] {
transition: opacity 1s, display 1s allow-discrete, overlay 1s allow-discrete;
}
Als u meerdere elementen open heeft in de bovenste laag, helpt overlay u bovendien de vloeiende overgang in en uit de bovenste laag te regelen. Je kunt het verschil zien in dit eenvoudige voorbeeld . Als u bij het overbrengen geen overlay
op de tweede popover toepast, zal deze eerst uit de bovenste laag komen en achter de andere popover springen voordat de overgang wordt gestart. Dit is geen erg vloeiend effect.
Een opmerking over weergaveovergangen
Als u DOM-wijzigingen aanbrengt, zoals het toevoegen en verwijderen van elementen uit de DOM, zijn weergaveovergangen een andere geweldige oplossing voor vloeiende animaties. Hier zijn twee van de bovenstaande voorbeelden gebouwd met behulp van weergaveovergangen.
In deze eerste demo zullen weergave-overgangen, in plaats van @starting-style
en andere CSS-transformaties in te stellen, de overgang afhandelen. De weergaveovergang is als volgt opgezet:
Geef eerst in CSS elke kaart een individuele view-transition-name
.
.card-1 {
view-transition-name: card-1;
}
.card-2 {
view-transition-name: card-2;
}
/* etc. */
Verpak vervolgens in JavaScript de DOM-mutatie (in dit geval het verwijderen van de kaart) in een weergaveovergang.
deleteBtn.addEventListener('click', () => {
// Check for browser support
if (document.startViewTransition) {
document.startViewTransition(() => {
// DOM mutation
card.remove();
});
}
// Alternative if no browser support
else {
card.remove();
}
})
Nu kan de browser de fade-out en morph van elke kaart naar de nieuwe positie afhandelen.
Een ander voorbeeld van waar dit handig kan zijn is de demo voor het toevoegen/verwijderen van lijstitems. In dit geval moet u er rekening mee houden dat u voor elke gemaakte kaart een unieke view-transition-name
moet toevoegen.
Conclusie
Deze nieuwe platformfuncties brengen ons een stap dichter bij soepele in- en uitstapanimaties op het webplatform. Bekijk deze links voor meer informatie: