In- en uitgangeffecten zijn animaties die worden geactiveerd wanneer een element de viewport binnenkomt of verlaat. Dit kan worden gebruikt om aantrekkelijke en dynamische gebruikerservaringen te maken. U kunt bijvoorbeeld een ingangseffect gebruiken om een element in te faden terwijl het in beeld scrollt, of een uitgangseffect om het te verkleinen terwijl het uit beeld scrollt.
Hoe wordt dit geïmplementeerd
Als u effecten voor binnenkomst en vertrek aan een element wilt toevoegen, moet u een aantal CSS-eigenschappen combineren. Hier volgt een stapsgewijze handleiding:
Maak afzonderlijke
@keyframesvoor de animaties bij openen en sluiten. De animatie voor binnenkomst wordt toegepast als het element het kijkvenster binnenkomt en de animatie voor verlaten wordt toegepast als het element het kijkvenster verlaat.@keyframes slide-in { from { transform: translateX(-100%); } } @keyframes slide-out { to { transform: translateX(100%); } }Koppel de begin- en eindkeyframes aan het element. Je kunt dit doen door meerdere animaties te definiëren in de eigenschap
animation.- Geef de animatie bij openen een
animation-fill-modevanbackwards, zodat de beginstatus wordt toegepast voordat de animatie begint. - Geef de animatie voor verbergen een
animation-fill-modevanforwards, zodat de uiteindelijke status behouden blijft nadat de animatie is voltooid.
.animated-element { animation: slide-in 1s linear backwards, slide-out 1s linear forwards; }- Geef de animatie bij openen een
Maak een View Timeline en koppel deze aan de animaties. Een weergavetijdlijn is een type tijdlijn dat is gekoppeld aan de zichtbaarheid van een element in de viewport. U kunt er een maken met de functie
view()en deze daarna toepassen op uw animaties met de eigenschapanimation-timeline..animated-element { animation-timeline: view(); }Standaard volgt
view()het element op deblock-as. Als je dit op deinline-as wilt bijhouden, kun jeview(inline)gebruiken.Beperk de animaties tot de bereiken
entryenexit. Met de propertyanimation-rangekunt u aangeven op welk deel van de tijdlijn een animatie moet worden uitgevoerd.- Het bereik
entryomvat de tijd vanaf het moment dat het element voor het eerst in de viewport komt tot het moment dat het volledig zichtbaar is. - Het bereik
exitomvat de tijd vanaf het moment dat het element het kijkvenster begint te verlaten totdat het helemaal verborgen is.
.animated-element { animation-range: entry, exit; }- Het bereik
Voorbeeldcode
Deze code animeert de directe onderliggende elementen van de scroller bij scrollen met een anonieme weergavetijdlijn:
@media (prefers-reduced-motion: no-preference) {
@supports ((animation-timeline: view()) and (animation-range: entry)) {
@keyframes grow {
from {
scale: 0.5;
}
}
@keyframes shrink {
to {
scale: 0.5;
}
}
.scroller > * {
animation:
grow auto linear backwards,
shrink auto linear forwards;
animation-timeline: view(inline);
animation-range: entry, exit;
}
}
}
Als de elementen de scrollport binnenkomen, wordt de animatie grow afgespeeld. Als ze de scrollport verlaten, wordt de animatie shrink afgespeeld.
De volgende code heeft hetzelfde visuele resultaat, maar animeert de directe onderliggende elementen van de scroller bij scrollen met een benoemde weergavetijdlijn:
@media (prefers-reduced-motion: no-preference) {
@supports ((animation-timeline: view()) and (animation-range: entry)) {
@keyframes grow {
from {
scale: 0.5;
}
}
@keyframes shrink {
to {
scale: 0.5;
}
}
.scroller > * {
view-timeline: --tl inline;
animation:
grow auto linear backwards,
shrink auto linear forwards;
animation-timeline: --tl;
animation-range: entry, exit;
}
}
}
Praktische tips
Als je scrollgestuurde animaties gebruikt, is het belangrijk dat je een aantal best practices volgt om een soepele en toegankelijke gebruikerservaring te bieden:
- WEL functiedetectie opnemen: Niet alle browsers ondersteunen scrollgestuurde animaties. Gebruik
@supports ((animation-timeline: view()) and (animation-range: entry))om te controleren op ondersteuning en een fallback te bieden voor browsers die dit niet ondersteunen.- De
(animation-range: entry)-controle MOET hier worden opgenomen om browsers met slechts gedeeltelijke ondersteuning weg te filteren. - Gebruik het
scroll-timeline-polyfill-pakket NIET voor de fallback-strategie, omdat het niet alle functies bevat en veel bekende problemen heeft. - Als de animatie alleen als decoratief wordt beschouwd, kies je voor progressive enhancement en bied je GEEN fallback.
- De
- WEL: Respecteer gebruikersvoorkeuren. Sommige gebruikers geven de voorkeur aan minder beweging op het web. Gebruik de mediaquery
prefers-reduced-motionom je animaties uit te zetten of te verminderen voor deze gebruikers. - WEL proberen alleen animaties te maken voor presterende CSS-property's: Voor de soepelste animaties maak je alleen animaties voor property's die kunnen worden verwerkt door de compositor-thread van de browser, zoals
transformenopacity. Als je andere eigenschappen animeert, zoalswidthofheight, kan dit leiden tot prestatieproblemen. - Gebruik WEL de juiste declaratievolgorde: Als je de verkorte eigenschap
animationgebruikt, declareer jeanimation-timelineerna om te voorkomen dat de verkorte eigenschap de tijdlijn reset.
Als je de functie view() gebruikt om een scrollgestuurde animatie te maken, geldt het volgende:
- OPTIONEEL Wees expliciet over de as die je wilt bijhouden: Als je niet de standaardas
blocktarget (zoals in een horizontale scroller), wees dan expliciet over welke as je wilt bijhouden metview(block)ofview(inline). - Als de animatie niet wordt toegepast op het gevolgde onderwerp zelf, gebruik je een tijdlijn met een benoemde weergave.
Als je de eigenschap view-timeline gebruikt om een scrollgestuurde animatie te maken:
- WEL een CSS
<dashed-ident>gebruiken voor de naam. - OPTIONEEL Wees expliciet over de as die moet worden bijgehouden: Als je niet de standaardas
blocktarget (zoals in een horizontale scroller), wees dan expliciet over welke as moet worden bijgehouden metview-timeline-axis. - Zorg dat het bereik van de zoekopdracht werkt: Als het element dat de
view-timelinedeclareert, geen voorouder van de platte structuur van het geanimeerde element is, verhoog je de zichtbaarheid van de naam van deview-timelinedoortimeline-scopete gebruiken voor een gedeelde voorouder.
Geef de voorkeur aan een benoemde view-timeline als meerdere elementen of onderliggende elementen van het gevolgde onderwerp moeten worden geanimeerd.
Browserondersteuning en fallback-strategieën
Daarom is meestal een reservestrategie vereist.
Voor browsers die geen scrollgestuurde animaties ondersteunen, kun je een fallback gebruiken om de visuele effecten opnieuw te maken. De fallbacks worden meestal gemaakt met een scroll-listener (voor ScrollTimeline-effecten) of de IntersectionObserver API (voor ViewTimeline-effecten).
In browsers met ingebouwde ondersteuning voor scrollgestuurde animaties gebruik je ALTIJD de native CSS-implementatie, omdat die beter presteert.
Niet elk effect kan opnieuw worden gemaakt met de reserveaanpak.
Specifiek voor deze use case past het volgende script de fallback toe voor browsers die geen scrollgestuurde animaties ondersteunen. De functie gebruikt een IntersectionObserver om de zichtbaarheid van het element .wrapper bij te houden en updatet de property transform van de lagen op basis van de scrollpositie.
<script>
if (!CSS.supports('(animation-timeline: view()) and (animation-range: entry)')) {
const observer = new IntersectionObserver(
(entries) => {
for (const entry of entries) {
// This matches the effect as defined in the CSS example above.
// Customize this further if needed.
entry.target.style.scale = 0.5 + entry.intersectionRatio * 0.5;
}
},
{
threshold: Array.from({ length: 101 }, (_, i) => i / 100),
}
);
document.querySelectorAll('.scroller > *').forEach((el) => {
observer.observe(el);
});
}
</script>