Scroll Reveal Animation (CSS)
April 2024
Easily create scroll reveal animations with CSS's animation-timeline property. This showcase uses avatars from my last 20 GitHub followers to demonstrate the effect. Note: not all browsers support this yet. For more details, check the MDN documentation..
import React, { useEffect, useRef, useState } from "react";import { StarFilledIcon } from "@radix-ui/react-icons";export default function ScrollRevealAnimationCSS() {const containerRef = useRef(null);const [githubFollower, setGithubFollower] = useState<{id: number;name: string;avatar: string;randomStar: number;}[]>([]);useEffect(() => {const fetchLast20GithubFollowers = async () => {try {const response = await fetch("https://api.github.com/users/ibelick/followers");const data = await response.json();const newGithubFollowers = data.map((follower: any) => {return {id: follower.id,name: follower.login,avatar: follower.avatar_url,randomStar: Math.floor(Math.random() * 90) + 10,};}).slice(0, 20);setGithubFollower(newGithubFollowers);} catch (error) {console.error(error);}};fetchLast20GithubFollowers();}, []);console.log("githubFollower", githubFollower);return (<><divclassName="h-[500px] w-full overflow-y-scroll p-4"ref={containerRef}><ul className="flex w-full flex-col space-y-2 pb-[10%]">{githubFollower?.map((item) => {return (<likey={item.id}className="items flex items-center justify-between rounded-xl bg-mauve-light-5 bg-opacity-50 px-2 py-2 backdrop-blur-xl dark:bg-mauve-dark-5"><div className="flex items-center"><imgsrc={item.avatar}alt="Avatar"className="h-8 w-8 rounded-full"/><span className="ml-2 text-sm text-mauve-light-12 dark:text-mauve-dark-12">{item.name}</span></div><div className="flex items-end"><StarFilledIcon className="h-4 w-4 text-mauve-light-9 dark:text-mauve-dark-9" /><span className="ml-1 text-xs text-mauve-light-11 dark:text-mauve-dark-11">{item.randomStar}</span></div></li>);})}</ul></div><style jsx>{`@keyframes appear {from {filter: blur(2px);scale: 0.95;}to {opacity: 1;filter: blur(0);scale: 1;}}.items {animation: appear linear both;animation-timeline: view();animation-range: entry cover 20%;}`}</style></>);}