In this article · 8 sections
Small animations make a website feel polished: buttons that respond to hover, sections that fade in, loaders that show progress. This CSS animation tutorial covers transitions and keyframes with practical examples, plus the rules that keep animations smooth on budget phones.
1. Transitions: animate between two states
.btn {
background: #F5C400;
transform: translateY(0);
box-shadow: 0 4px 12px rgba(0,0,0,.12);
transition: transform .2s ease, box-shadow .2s ease, background .2s ease;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 10px 24px rgba(0,0,0,.18);
background: #ffd83a;
}
Tip: list specific properties instead of transition: all.
2. Keyframes: multi-step animations
@keyframes pulse {
0% { box-shadow: 0 0 0 0 rgba(27,111,216,.5); }
100% { box-shadow: 0 0 0 12px rgba(27,111,216,0); }
}
.live-dot { animation: pulse 1.6s infinite; }
Loader spinner
@keyframes spin { to { transform: rotate(360deg); } }
.spinner {
width: 28px; height: 28px; border-radius: 50%;
border: 3px solid #e3e8f4; border-top-color: #1B6FD8;
animation: spin .8s linear infinite;
}
3. Fade-in on scroll
CSS sets the start and end states; a few lines of JavaScript add a class when the element appears:
.reveal { opacity: 0; transform: translateY(24px); transition: opacity .6s ease, transform .6s ease; }
.reveal.in { opacity: 1; transform: none; }
const io = new IntersectionObserver(es => es.forEach(e => {
if (e.isIntersecting) { e.target.classList.add('in'); io.unobserve(e.target); }
}), { threshold: 0.1 });
document.querySelectorAll('.reveal').forEach(el => io.observe(el));
Make sure content above the fold isn't hidden at load, or it will hurt LCP.
4. Performance rules
- Animate
transformandopacity. They're cheap for the browser - Avoid animating
width,height,top,left,margin; they cause layout recalculation - Keep durations short: 150–300 ms for UI feedback, 400–700 ms for reveals
- Use
will-changesparingly, only on elements about to animate - Test on a mid-range Android phone
5. Respect reduced motion
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after { animation: none !important; transition: none !important; }
.reveal { opacity: 1; transform: none; }
}
6. Easing
ease-outfeels natural for elements enteringease-infor elements leaving- Custom curves:
cubic-bezier(.2,.8,.2,1)gives a smooth, modern feel
When not to animate
- Text people are trying to read
- Everything on the page at once
- Auto-playing sliders that hide messages
See micro-interactions: when they help and hurt.
FAQs
Should I use an animation library?
For simple effects, plain CSS is lighter. Libraries help for complex timelines and interactive animation.
Do animations affect SEO?
Not directly, but heavy animations can hurt speed and Core Web Vitals.
Joboo Web adds smooth, lightweight animations that keep sites fast. See our work.