Dev.to · 3 min read

Animate display: none in Pure CSS! Modern @starting-style & allow-discrete Explained

Animate display: none in Pure CSS! Modern @starting-style & allow-discrete Explained

For over 10 years, transitioning elements from display: none was considered impossible in pure CSS without JavaScript reflow workarounds like requestAnimationFrame or void element.offsetWidth. Those days are officially over! Modern CSS introduces two game-changing features (Baseline 2024 across Chrome, Safari, and Firefox): @starting-style: Defines the before-change style snapshot at frame 0 when an element transitions from display: none or mounts to the DOM. transition-behavior: allow-discrete: Delays flipping to display: none until your exit transitions finish completely. 💡 The Mental Model: The Broadway Stage Analogy To understand why this is necessary, think of a browser render engine like a Broadway theater: Without @starting-style: Toggling display: none to display: block is like an actor suddenly teleporting from backstage straight into a 100% bright spotlight. The browser cannot interpolate between "does not exist in the render tree" and "fully visible", so it abruptly snaps. With @starting-style: @starting-style places the actor on their backstage floor tape mark in the dark (opacity: 0, scale: 0.85) before the curtains open. Once the stage lights go up, they smoothly fade and scale into center stage. With allow-discrete: When closing, allow-discrete acts like a curtain timer. It lets the exit fade play out completely before turning off the lights and sending the element backstage. 🚀 3 Real-World Production Patterns Pattern 1: Dropdown Menus & Modals (display: none → flex) .modal { display: flex; opacity: 1; transform: translateY(0); transition: opacity 0.35s ease, transform 0.35s ease, display 0.35s allow-discrete; /* Frame 0 snapshot when switching from display: none */ @starting-style { opacity: 0; transform: translateY(-12px); } } .modal.is-closed { display: none; opacity: 0; transform: translateY(-12px); } Pattern 2: Native HTML5 and ::backdrop Transitions You can animate the native element and its top-layer ::backdrop with zero JavaScript wrapper elements: dialog { opacity: 1; transform: scale(1); transition: opacity 0.3s ease, transform 0.3s ease, overlay 0.3s allow-discrete, display 0.3s allow-discrete; &::backdrop { background-color: rgba(0, 0, 0, 0.65); transition: background-color 0.3s ease, display 0.3s allow-discrete; } } @starting-style { dialog[open] { opacity: 0; transform: scale(0.92); &::backdrop { background-color: transparent; } } } Pattern 3: Dynamic DOM Elements & Toast Notifications When appending elements dynamically with JavaScript (element.appendChild), modern CSS allows them to animate on first paint automatically: .toast { opacity: 1; transform: translateX(0); transition: opacity 0.4s ease, transform 0.4s ease; @starting-style { opacity: 0; transform: translateX(40px); } } 🌐 Browser Compatibility (Baseline 2024) Both @starting-style and transition-behavior: allow-discrete are part of Baseline 2024 Widely Available: Browser Supported Version Chrome / Edge 117+ ✅ Safari 17.5+ ✅ Firefox 129+ ✅ For older browser fallbacks, use @supports: @supports (transition-behavior: allow-discrete) { /* Enhanced modern transitions */ } 🎯 60-Second Viewer Coding Challenge How would you make a modal scale in from 90% (0.9 → 1.0) on open, but slide down 20px as it closes? Grab the spoiler-free starter HTML from our GitHub Code Vault. Write your pure CSS solution (zero JS reflow hacks!). Drop your solution in the YouTube video comments — the top 3 best solutions will be pinned and inducted into our Community Hall of Fame! 🏆 📦 Resources & Links 📺 Watch Full Explainer Video: YouTube Deep-Dive ⭐ GitHub Repository: muneebali500/cascadedev-code-vault 📄 High-Res Printable Cheat Sheet: Available inside the GitHub repo (cheat-sheet.png)

This is a summary aggregated from Dev.to. Read the complete article on the original site:

Read full article at Dev.to

More Programming & Dev News