CSS Transitions & Animations
Using pure CSS for smooth transitions and keyframe animations in React
CSS transitions and animations are the foundation of web animations. They're performant, well-supported, and perfect for simple to moderately complex animations. In React, you can control these animations by toggling classes or inline styles based on component state.
When to use CSS Transitions & Animations:
- •Hover effects and micro-interactions
- •Simple state transitions (show/hide, expand/collapse)
- •Loading spinners and progress indicators
- •Keyframe-based animations that don't need JavaScript control
Advantages:
- ✓Zero JavaScript overhead during animation
- ✓Browser-optimized performance
- ✓Works even if JavaScript fails
- ✓Smaller bundle size
Implementation Example
1// CSS Transitions in React2import { useState } from 'react';3import './styles.css';45const CSSTransitionExample = () => {6 const [isExpanded, setIsExpanded] = useState(false);7 const [isVisible, setIsVisible] = useState(true);8 const [activeTab, setActiveTab] = useState(0);910 return (11 <div className="animation-demo">12 {/* Simple toggle transition */}13 <button14 className="toggle-button"15 onClick={() => setIsExpanded(!isExpanded)}16 >17 Toggle Expand18 </button>1920 <div className={`expandable-content ${isExpanded ? 'expanded' : ''}`}>21 <p>This content expands and collapses smoothly</p>22 </div>2324 {/* Fade in/out */}25 <button onClick={() => setIsVisible(!isVisible)}>26 Toggle Visibility27 </button>2829 <div className={`fade-box ${isVisible ? 'visible' : ''}`}>30 Fade In/Out Box31 </div>3233 {/* Sliding tabs */}34 <div className="tabs-container">35 <div className="tab-buttons">36 {['Tab 1', 'Tab 2', 'Tab 3'].map((tab, index) => (37 <button38 key={index}39 className={`tab-button ${activeTab === index ? 'active' : ''}`}40 onClick={() => setActiveTab(index)}41 >42 {tab}43 </button>44 ))}45 </div>4647 <div className="tab-indicator"48 style={{ transform: `translateX(${activeTab * 100}%)` }}49 />5051 <div className="tab-content">52 <div53 className="tab-panels"54 style={{ transform: `translateX(-${activeTab * 100}%)` }}55 >56 <div className="tab-panel">Content 1</div>57 <div className="tab-panel">Content 2</div>58 <div className="tab-panel">Content 3</div>59 </div>60 </div>61 </div>62 </div>63 );64};
CSS Styles
1/* CSS for smooth transitions */2.toggle-button {3 background: #3b82f6;4 color: white;5 padding: 0.5rem 1rem;6 border: none;7 border-radius: 0.25rem;8 cursor: pointer;9 transition: all 0.3s ease;10}1112.toggle-button:hover {13 background: #2563eb;14 transform: translateY(-2px);15 box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);16}1718.expandable-content {19 max-height: 0;20 overflow: hidden;21 opacity: 0;22 transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);23}2425.expandable-content.expanded {26 max-height: 200px;27 opacity: 1;28 padding: 1rem;29}3031.fade-box {32 width: 200px;33 height: 100px;34 background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);35 border-radius: 0.5rem;36 opacity: 0;37 transform: scale(0.8);38 transition: all 0.4s ease;39 pointer-events: none;40}4142.fade-box.visible {43 opacity: 1;44 transform: scale(1);45 pointer-events: auto;46}4748/* Sliding tabs */49.tabs-container {50 position: relative;51 width: 100%;52 background: #f3f4f6;53 border-radius: 0.5rem;54 overflow: hidden;55}5657.tab-buttons {58 display: flex;59 position: relative;60 z-index: 1;61}6263.tab-button {64 flex: 1;65 padding: 1rem;66 background: transparent;67 border: none;68 cursor: pointer;69 transition: color 0.3s ease;70}7172.tab-button.active {73 color: #3b82f6;74}7576.tab-indicator {77 position: absolute;78 top: 0;79 left: 0;80 width: 33.333%;81 height: 3px;82 background: #3b82f6;83 transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);84}8586.tab-content {87 position: relative;88 overflow: hidden;89 height: 200px;90}9192.tab-panels {93 display: flex;94 transition: transform 0.3s ease;95}9697.tab-panel {98 width: 100%;99 flex-shrink: 0;100 padding: 2rem;101}102103/* Keyframe animations */104@keyframes slideIn {105 from {106 transform: translateX(-100%);107 opacity: 0;108 }109 to {110 transform: translateX(0);111 opacity: 1;112 }113}114115@keyframes bounce {116 0%, 100% {117 transform: translateY(0);118 }119 50% {120 transform: translateY(-20px);121 }122}123124@keyframes pulse {125 0% {126 transform: scale(1);127 opacity: 1;128 }129 50% {130 transform: scale(1.05);131 opacity: 0.8;132 }133 100% {134 transform: scale(1);135 opacity: 1;136 }137}138139.animate-slide-in {140 animation: slideIn 0.5s ease forwards;141}142143.animate-bounce {144 animation: bounce 1s ease infinite;145}146147.animate-pulse {148 animation: pulse 2s ease infinite;149}
Best Practices
- ✓Use transform and opacity for best performance
- ✓Prefer cubic-bezier for natural motion
- ✓Avoid animating layout properties (width, height)
- ✓Use will-change sparingly for optimization
- ✓Test animations on lower-end devices