New CSS Rule to Prevent FOUC
Using CSS to animate elements on first load has always been a little tricky. You could easily animate an element from blue to red, but animating an element as it first appears in the DOM usually requires some Javascript workarounds or animation libraries.
The New @starting-style Rule
The new @starting-style rule is a game-changer that allows you to define the initial state of an element before its first style update, making entry animations smoother and easier than ever.
Traditionally, when an element is added to the page (or its display changes from none to block), browsers apply the new styles instantly, which causes yucky FOUC. Even if you have a transition: opacity set, the browser doesn't have a "before" state to transition from. It just jumps from non-existent to fully visible.
The @starting-style at-rule provides that missing "before" state. It tells the browser: the moment this element starts existing, pretend it has these styles so you can transition to its actual styles.
Here's the basic rule syntax:
Why is this better?
- No Javascript Needed: You no longer need to use requestAnimationFrame or setTimeout to trigger an entry animation.
- Performance: CSS transitions are generally more performant than JS-driven animations as they can be offloaded to the compositor thread.
- Cleaner Code: Your animation logic stays in your stylesheet, keeping your scripts focused on functionality.
Animating display: none
Until now you couldn't really transition the display property. If you changed a class from display: none to display: block, the transition would fail because display is not a property that can be animated.
By combining @starting-style with the new transition-behavior: allow-discrete property, we can now animate elements like this.
Property/Rule Descriptions:
- @starting-style: Sets the "zero-frame" values (e.g., opacity: 0) for the transition to start from.
- transition-behavior: Allows discrete properties (like display) to wait for the transition to finish.
- @keyframes (Alternative): Still great for loops, but @starting-style is better for simple state entries.
Here's an example with popover (also new!) and modals:
As of 2024, @starting-style is working in Firefox, Chrome, Edge, and Safari. It is part of a new wave of CSS features (like the Popover API and Anchor Positioning) designed to handle UI states that used to require Javascript. Pretty neat.
