A CSS transition driven by state
React only changes the class and the inert attribute; the browser animates transform and opacity. inert keeps the hidden links out of the Tab order while the drawer is closed (an off-screen element is still focusable otherwise). The handler checks propertyName because transitionend fires once per animated property.
In React you animate by changing state and letting CSS transitions move between the old and new styles; exits need the element kept mounted until its animation ends, the View Transitions API animates whole DOM changes, the Motion library handles complex cases, and every animation must respect prefers-reduced-motion.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 5 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Write a useReducedMotion() hook that returns true when the user prefers reduced motion and updates when the setting changes.
Make a Collapse component that slides a panel open and closed with a CSS transition on grid-template-rows, with aria-expanded on its toggle button.
Explain it without notes
How do you animate a change driven by React state with CSS? What should you animate for smoothness?
Why are exit animations hard in React and how do you solve them?
How do you use the View Transitions API with React, and why is flushSync needed?
What is prefers-reduced-motion and how should a React app respect it?
Preview
Console
Nothing logged yet.Expected console output
closed: inert = true
open: inert = false | class = drawer drawer--open
transitionend: transform | open = true