Toggle navigation
☰
HTML
CSS
Scripting
Database
<!doctype html> <title>Example</title> <style> body { margin: 0; font-family: sans-serif; background-color: #f0f0f0; min-height: 200vh; /* Make the page scrollable */ display: flex; flex-direction: column; align-items: center; } .spacer { height: 100vh; display: flex; justify-content: center; align-items: center; text-align: center; } .reveal-card { background-color: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); max-width: 400px; margin: 50px 20px; /* Starting state: hidden and pushed down */ opacity: 0; transform: translateY(50px); transition: opacity 0.8s ease-out, transform 0.8s ease-out; } /* Final state when the JS adds this class */ .reveal-card.is-visible { opacity: 1; transform: translateY(0); } @media (prefers-reduced-motion: reduce) { .reveal-card { transition: none; /* Instant appearance */ transform: none; /* Don't slide up, just fade or appear */ } } </style> <div class="spacer"> <h1>Scroll down slowly 👇</h1> </div> <div class="reveal-card reveal-element"> <h2>I magically appear!</h2> <p>This box faded in and slid up when it entered the viewport via the Intersection Observer API.</p> </div> <div class="reveal-card reveal-element" style="transition-delay: 0.2s;"> <h2>I'm slightly delayed!</h2> <p>You can stagger animations simply by adding a transition-delay on adjacent items.</p> </div> <div class="spacer"> <p>Keep scrolling...</p> </div> <div class="reveal-card reveal-element"> <h2>Here comes another!</h2> <p>The observer keeps watching and firing precisely when elements cross the threshold.</p> </div> <script> // Select all elements to be tracked const revealElements = document.querySelectorAll('.reveal-element'); // Set up the Intersection Observer const observer = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { // If the element is visible in the viewport if (entry.isIntersecting) { entry.target.classList.add('is-visible'); // Un-observe it if you only want the animation to happen once observer.unobserve(entry.target); } }); }, { root: null, // use the document's viewport rootMargin: '0px', threshold: 0.2 // trigger when 20% of the element is visible }); // Start observing each element revealElements.forEach(el => observer.observe(el)); </script>