Animating a transition to and from ‘display: none’ has historically required JavaScript. CSS couldn’t handle transitions for elements that didn’t exist on the page.
Two new features added to Chrome and most of the other browsers now enable us to animate to and from ‘display: none’.
The issue
Setting an element to ‘display: none’ makes it disappear. It leaves nothing for a transition to work with. CSS could not animate transitions to and from a non-existent state.
Solution
The introduction of two new CSS features:
- transition-behavior: allow-discrete
- @starting-style
transition-behavior: allow-discrete
You can use the CSS property ‘allow-discrete’ to enable transitions on discrete properties.
Discrete properties do not have values between states. For example, display and visibility. It’s either one or the other. Traditionally, CSS transitions only work on properties with continuous values. These include opacity, transform, and width.
‘Allow-discrete’ lets you create a transition effect when a discrete property changes. It doesn’t interpolate the discrete property itself (you can’t have a ‘halfway’ display). But it allows the transition before the discrete property switches states.
#navigation {
display: none;
max-height: 0;
transition-property: display, opacity, max-height;
transition-duration: 1.25s;
transition-timing-function: ease-in-out;
transition-behavior: allow-discrete;
}
@starting-style
@starting-style sets the initial CSS styles on an element. This is before any other CSS rules. It provides a reliable starting point for transitions and animations.
#navigation.open {
display: block;
max-height: 1000px;
opacity: 1;
@starting-style {
max-height: 0;
opacity: 0;
}
}
Examples
To bring this concept to life, I’ve crafted a Codepen. It showcases a way to animate a burger menu.
For a more in-depth understanding, delve into this informative blog post from Google about entry and exit animations. Additionally, Kevin Powell’s video offers a wealth of practical advice!
Browser compatibility and testing
Check browser compatibility before implementing:
Note: one issue at the time of writing. There isn’t an option to inspect @starting-style in Chrome DevTools. However you can see it in Firefox DevTools (but allow-discrete doesn’t work in Firefox).
Summary
Implementing ‘@starting-style’ and ‘transition-behavior: allow-discrete’ serves as a nice progressive enhancement. Your site will work fine without these features. However, they add a finesse to animations. This can improve the user experience on compatible browsers.
