CSS Transitions in React
CSS Transitions in React
The most performant transitions are pure CSS. React’s job is simply to toggle class names; the browser’s compositor thread handles the animation. Properties that can be animated on the compositor thread (without involving the main thread) are: opacity, transform. Prefer these over animating width, height, or color.
4.1 Basic CSS Transition: Fade Toggle
FadeToggle.js
import { useState } from 'react'; import './FadeToggle.css'; export default function FadeToggle() { const [visible, setVisible] = useState(true); return ( <div className="wrapper"> <div className={`box ${visible ? 'visible' : 'hidden'}`}> Hello, I fade in and out! </div> <button onClick={() => setVisible(v => !v)}> Toggle </button> </div> ); }
FadeToggle.cs
.box { transition: opacity 300ms ease, transform 300ms ease; } .box.visible { opacity: 1; transform: translateY(0); } .box.hidden { opacity: 0; transform: translateY(-8px); } /* Respect user preference for reduced motion */ @media (prefers-reduced-motion: reduce) { .box { transition: none; } }
Tip: CSS transitions only interpolate between two states. For enter/exit on mount/unmount (when the element leaves the DOM entirely), you need
react-transition-group or Framer Motion, CSS alone cannot animate an element before it is removed from the DOM.4.2 CSS Keyframe Animation: Entrance
SlideIn.css
@keyframes slideInUp { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: translateY(0); } } .card-enter { animation: slideInUp 400ms cubic-bezier(0.22, 1, 0.36, 1) both; } /* Stagger children with animation-delay */ .card-enter:nth-child(1) { animation-delay: 0ms; } .card-enter:nth-child(2) { animation-delay: 80ms; } .card-enter:nth-child(3) { animation-delay: 160ms; }
4.3 Inline Style Transitions
For dynamic values (e.g. a progress bar driven by state), use inline styles with a CSS transition on the element:
ProgressBar.jsx
function ProgressBar({ value }) { // value: 0 – 100 return ( <div style={{ background: '#1f2840', borderRadius: 99, height: 8 }}> <div style={{ width: `${value}%`, height: '100%', background: '#61dafb', borderRadius: 'inherit', transition: 'width 500ms cubic-bezier(0.4, 0, 0.2, 1)', }} /> </div> ); } References: React Community Intro to React
