- Gebruik
clip-pathenmask-imagevoor aangepaste geometrische onthullingen en vloeiende fade-outs. - Gebruik Scroll-Driven Animations (
animation-timeline: scroll()) voor niet-essentiële scrollgebonden effecten in plaats van JS-listeners. - Gebruik Weergaveovergangen om naadloos te animeren tussen complexe indelingsstatussen.
Prestaties
- Gebruik bij voorkeur animaties voor
opacityentransform(waaronder afzonderlijke transformatie-eigenschappen, bijvoorbeeldtranslatein plaats vanleft/right/top/bottom) om te zorgen dat animaties in de samensteller-thread blijven. - Gebruik
transition-behavior: allow-discrete,@starting-styleen (voor elementen op de bovenste laag zoals<dialog>of[popover])overlayom afzonderlijke begin- en eindstatussen native te animeren. Ga naar Het begin en einde van elementen animeren en Elementen animeren naar en van de bovenste laag.
.popover-reveal {
/* Transition discrete display and top-layer overlay alongside opacity */
transition:
opacity ease-out,
display,
overlay;
transition-duration: 0.2s;
transition-behavior: allow-discrete;
}
Toegankelijkheid
Gebruik prefers-reduced-motion-mediaquery's om zware beweging uit te zetten voor gebruikers die dat liever hebben.
- Zorg voor een pauzemechanisme: Sta gebruikers toe om automatisch uitgevoerde carrousels, banners of andere permanente animaties te stoppen.
- Standaard statische weergaven: Overweeg om standaard statische statussen te gebruiken en gebruikers de mogelijkheid te geven zich aan te melden voor beweging.
- Overschrijd de flitslimieten niet (3 per seconde): Gebruik nooit snel flitsen van licht naar donker. Deze effecten kunnen epileptische aanvallen veroorzaken.
Pas animation-duration: 0.01ms; NIET wereldwijd toe, omdat bepaalde animaties hierdoor meer schokkerig kunnen worden.
In plaats daarvan kun je bewegingsvoorkeuren per geval afhandelen met een van de 2 benaderingen. Nest de query @media in de regel zodat beide versies bij elkaar blijven:
- Begin met animaties die standaard aanstaan en maak ze minder opvallend met
@media (prefers-reduced-motion: reduce):
/* Good: Dampen spin states or slow down animations for reduced motion */
.spinner {
animation: spin 1s linear infinite;
@media (prefers-reduced-motion: reduce) {
animation: none;
opacity: 0.5;
}
}
progress:not([value]) {
animation: slide 1s infinite linear;
@media (prefers-reduced-motion: reduce) {
animation-duration: 20s;
}
}
- Begin standaard zonder animaties en zet ze aan met
@media (prefers-reduced-motion: no-preference):
/* Good: Default to static or gentle states and opt-in to full motion */
.spinner {
opacity: 0.5;
@media (prefers-reduced-motion: no-preference) {
opacity: 1;
animation: spin 1s linear infinite;
}
}
progress:not([value]) {
animation: slide 20s infinite linear;
@media (prefers-reduced-motion: no-preference) {
animation-duration: 1s;
}
}
Werken met animatie- en overgangsgebeurtenissen in JavaScript
In zowel de AnimationEvent-interface (animationstart, animationiteration, animationend, animationcancel) als de TransitionEvent-interface (transitionrun, transitionstart, transitionend, transitioncancel) geeft event.target je het oorspronkelijke DOM-element. Gebruik de alleen-lezen eigenschap event.animation om toegang te krijgen tot het specifieke Animation-object (Animation, CSSAnimation of CSSTransition) dat de gebeurtenis heeft geactiveerd.
Als event.animation niet beschikbaar is, kun je de Animation-instantie meestal vinden door event.target.getAnimations() aan te roepen en te filteren op event.animationName (of event.propertyName voor overgangen). We raden u aan event.animation rechtstreeks te gebruiken om verschillende scenario's te vermijden waarin deze reserveoptie die event.target.getAnimations() filtert, niet werkt zoals verwacht:
- Animaties van de Web Animations API (
element.animate()) hebben geenanimationName, dus ze kunnen niet op naam worden gevonden als je filtert opevent.target.getAnimations(). - Filteren op
animationNamevoorAnimationEvent's is dubbelzinnig als meerdere animaties met dezelfde naam aan hetzelfde element zijn gekoppeld.- Je kunt filteren op
transitionPropertyvoorTransitionEvent's omdat er maar één gebeurtenis per overgangseigenschap is.
- Je kunt filteren op
event.targetverwijst altijd naar het oorspronkelijke DOM-element, dus er wordt geen onderscheid gemaakt tussen animaties die worden uitgevoerd op het element zelf en een van de pseudo-elementen, terwijlevent.animation.effect.pseudoElementhet doel-pseudo-element rechtstreeks blootstelt.
// Works in most basic CSS animation cases, but fails for WAAPI animations,
// duplicate animation names on the same element, or pseudo-elements.
document.addEventListener('animationstart', (event) => {
const animation = event.target
.getAnimations()
.find((anim) => anim.animationName === event.animationName);
console.log(animation);
});
// PREFERRED: Directly access the exact Animation object via event.animation
document.addEventListener('animationstart', (event) => {
const animation = event.animation;
console.log(animation);
});
Je kunt ondersteuning voor functieherkenning gebruiken met 'animation' in AnimationEvent.prototype (of 'animation' in TransitionEvent.prototype).