Free tutorials & notes in Hindi & English · Clean code examples 🧰 Free PDF & Image Tools →
✨ Days 13–18 – Motion, UI & Professional CSS  ·  Day 14

Day 14: Keyframe Animations

⏱ 90 min📶 Intermediate🎯 100% self-study
Day 14 / 20

✅ Today you will learn

  • @keyframes with from/to and percentages
  • animation-name, duration, timing, delay, iteration-count, direction, fill-mode
  • Loaders: spinner, dots and skeleton screens
  • Attention effects: pulse, shake, marquee offer strip
  • Staggered entrances and respecting prefers-reduced-motion

🏢 In the real world

On slow 4G connections, users stare at a blank screen while data loads and think the app is broken. Apps like Swiggy and Flipkart show grey “skeleton” boxes and spinners instead – it feels faster even though it is not. Today you build those loaders plus the festive effects marketing teams always ask for.

@keyframes + animation

HTML + CSS
<style>
@keyframes slide-in {
  from { transform: translateX(-100%); opacity: 0; }
  to   { transform: translateX(0);     opacity: 1; }
}
@keyframes glow {
  0%, 100% { box-shadow: 0 0 0 0 rgb(245 158 11 / 60%); }
  50%      { box-shadow: 0 0 0 14px rgb(245 158 11 / 0%); }
}
.banner { background: #264de4; color: #fff; padding: 12px 16px; border-radius: 10px;
  animation: slide-in .7s ease-out both; }
.offer { display: inline-block; margin-top: 16px; background: #f59e0b; padding: 8px 14px; border-radius: 99px; font-weight: 700;
  animation: glow 1.8s ease-in-out infinite; }
</style>

<div class="banner">Welcome to Sharma Sweets 🍬</div>
<span class="offer">🪔 Diwali offer – 10% off</span>
<p><button onclick="var b=document.querySelector('.banner'); b.style.animation='none'; b.offsetWidth; b.style.animation='';">Replay</button></p>
▶  A one-time slide-in and an infinite glow
PropertyExampleMeaning
animation-nameslide-inWhich @keyframes
animation-duration.7sOne cycle
animation-timing-functionease-out, steps(4)Speed curve
animation-delay.2sStart later
animation-iteration-count1, 3, infiniteHow many times
animation-directionalternatePlay forward then backward
animation-fill-modeboth / forwardsKeep the first/last frame before/after
animation-play-statepausedPause, e.g. on hover

Loaders and skeleton screens

HTML + CSS
<style>
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes bounce { 0%, 80%, 100% { transform: scale(0); } 40% { transform: scale(1); } }
@keyframes shimmer { to { background-position: -200% 0; } }

.spinner { width: 40px; height: 40px; border: 4px solid #dbeafe; border-top-color: #264de4; border-radius: 50%; animation: spin .8s linear infinite; }
.dots span { display: inline-block; width: 12px; height: 12px; margin: 0 3px; background: #264de4; border-radius: 50%; animation: bounce 1.2s infinite ease-in-out both; }
.dots span:nth-child(1) { animation-delay: -.32s; }
.dots span:nth-child(2) { animation-delay: -.16s; }

.sk { background: linear-gradient(90deg, #e5e7eb 25%, #f3f4f6 50%, #e5e7eb 75%); background-size: 200% 100%; animation: shimmer 1.4s linear infinite; border-radius: 8px; }
.sk-card { display: flex; gap: 12px; align-items: center; margin-top: 16px; }
.sk-img { width: 70px; height: 70px; }
.sk-line { height: 12px; margin: 8px 0; }
.row { display: flex; gap: 40px; align-items: center; }
</style>

<div class="row">
  <div class="spinner" role="status" aria-label="Loading"></div>
  <div class="dots" aria-hidden="true"><span></span><span></span><span></span></div>
</div>
<div class="sk-card" aria-busy="true">
  <div class="sk sk-img"></div>
  <div style="flex:1"><div class="sk sk-line" style="width:70%"></div><div class="sk sk-line" style="width:45%"></div></div>
</div>
▶  Spinner, bouncing dots and a shimmering skeleton card
🧠 Accessible loaders

Give spinners role="status" and an aria-label (or visually hidden text “Loading…”), and set aria-busy="true" on the area being loaded so screen-reader users know something is happening.

Attention effects that sell

HTML + CSS
<style>
@keyframes shake { 10%, 90% { transform: translateX(-1px); } 20%, 80% { transform: translateX(2px); } 30%, 50%, 70% { transform: translateX(-4px); } 40%, 60% { transform: translateX(4px); } }
@keyframes marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes ring { 0%, 100% { transform: rotate(0); } 10%, 30% { transform: rotate(-15deg); } 20%, 40% { transform: rotate(15deg); } 50% { transform: rotate(0); } }

.error { border: 2px solid #dc2626; padding: 8px; border-radius: 8px; width: 220px; animation: shake .5s; }
.strip { overflow: hidden; background: #111827; color: #fde68a; border-radius: 8px; margin: 14px 0; }
.strip .track { display: flex; width: max-content; animation: marquee 12s linear infinite; }
.strip span { padding: 8px 24px; white-space: nowrap; }
.strip:hover .track { animation-play-state: paused; }
.bell { display: inline-block; font-size: 28px; animation: ring 2s ease-in-out infinite; transform-origin: top center; }
</style>

<input class="error" value="98290" aria-invalid="true"> <small style="color:#dc2626">Enter 10 digits</small>
<div class="strip"><div class="track">
  <span>🪔 Diwali gift boxes from ₹480</span><span>🚚 Free delivery above ₹1,500</span><span>🍬 Sugar-free kaju katli launched</span>
  <span aria-hidden="true">🪔 Diwali gift boxes from ₹480</span><span aria-hidden="true">🚚 Free delivery above ₹1,500</span><span aria-hidden="true">🍬 Sugar-free kaju katli launched</span>
</div></div>
<span class="bell" aria-hidden="true">🔔</span> 3 new orders
▶  Shake for errors, an offer marquee (pauses on hover) and a ringing bell

Staggered entrance

HTML + CSS
<style>
@keyframes rise { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: none; } }
.list li { list-style: none; background: #eef2ff; margin: 6px 0; padding: 10px 14px; border-radius: 8px;
  animation: rise .5s ease-out both;
  animation-delay: calc(var(--i) * 120ms); }   /* each item waits a bit longer */
</style>

<ul class="list" style="padding:0">
  <li style="--i:0">✔ Order received</li>
  <li style="--i:1">✔ Sweets packed</li>
  <li style="--i:2">✔ Out for delivery</li>
  <li style="--i:3">✔ Delivered</li>
</ul>
▶  CSS variables + calc() for a cascading entrance

Respect prefers-reduced-motion

CSS – include this in every project
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
⚠️ Why it matters

People with vestibular disorders can feel dizzy or nauseous from large moving elements. Phones and computers have a “reduce motion” setting; this snippet honours it. It is one of the rare good uses of !important.

🏅 Job skills unlocked today

✔ Write @keyframes and configure animations✔ Build spinners, dots and skeleton loaders✔ Create shake, marquee and stagger effects✔ Support users who prefer reduced motion

Practice tasks

🏋️ Practice – do it yourself

Task 1: Create a “typing” indicator (three dots fading in and out one after another) for a chat app.
Show solution
▶  Result
Task 2: Make a skeleton screen for a product grid of 4 cards (image, title line, price line).
Task 3: Animate a progress bar from 0% to 75% once on page load using forwards fill-mode.

Quick quiz

🧠 Quick Quiz – test yourself

1. Repeat an animation forever:
Or the infinite keyword in the shorthand.
2. Keep the last keyframe after the animation ends:
animation-fill-mode.
3. A skeleton screen’s purpose is…
Perceived performance.
4. Pause a marquee on hover:
Resumes on mouse leave.
5. Users who get dizzy from motion are protected by…
OS accessibility setting.

Interview corner

💼 Interview Corner

How do you make loading feel faster?

Show skeleton screens matching the final layout, use lightweight CSS spinners only for short waits, load content progressively, reserve space to avoid layout shifts, and give accessible status messages.

What is animation-fill-mode?

It decides which styles apply before the animation starts (backwards – first keyframe during the delay) and after it ends (forwards – last keyframe stays). both does both.

Summary

  • @keyframes defines steps; animation applies them.
  • infinite + linear for spinners; both/forwards to keep frames.
  • Skeletons and spinners improve perceived speed.
  • Always add the prefers-reduced-motion snippet.
➡️ Next

Day 15: styling forms and tables – inputs, custom checkboxes, validation states and responsive tables.

Frequently Asked Questions

CSS animation or JavaScript animation?
CSS for UI effects, loaders and entrances – simpler and fast. JavaScript (or libraries) for scroll-linked, physics or sequenced timelines that depend on user input.
Can I trigger an animation when an element scrolls into view?
Yes – add a class with JavaScript’s IntersectionObserver (JS course), or use the newer CSS animation-timeline: view() where supported.
← CSS (20 Days)
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

Next topicDay 15: Styling Forms & Tables Your progress: 14 / 20 (70%) · Lesson 15 / 20 Continue →

How was this lesson?

Your feedback helps us make the content better.

Write a review or suggestion (optional)

After approval, your name and city may appear publicly with your review. Please do not write your email or phone number.

▶ CodingEasily on YouTube

Learn with video lessons in easy Hindi

Featured video: RDBMS Part 3 – Class XI Commerce IT

▶ Subscribe – it’s free