Practice Here: Embedded HTML Editor
Copy any full example from this lesson and paste it into the editor below. Then run it and change values like duration, color, movement, rotation, and scale.
1. What is Animation?
Animation means changing something slowly over time so that the user sees movement.
Without animation
A button suddenly changes color. A box suddenly appears. A menu suddenly opens.
With animation
The color smoothly changes. The box fades in. The menu slides open.
Why use animation?
Animation helps users understand movement, attention, loading, success, error, and interaction.
Full Example: Your First Animation Page
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>My First Animation</title>
<style>
body {
min-height: 100vh;
display: grid;
place-items: center;
margin: 0;
background: #fff7ed;
font-family: Arial, sans-serif;
}
.box {
width: 120px;
height: 120px;
border-radius: 24px;
background: #ff8a00;
animation: moveBox 2s ease-in-out infinite alternate;
}
@keyframes moveBox {
from {
transform: translateX(-100px);
}
to {
transform: translateX(100px);
}
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>
2. CSS Transition: The First Smooth Change
A transition makes a change smooth. Move your mouse over the card below.
Full Example: Hover Transition Card
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>CSS Transition Card</title>
<style>
body {
min-height: 100vh;
margin: 0;
display: grid;
place-items: center;
background: #fff7ed;
font-family: Arial, sans-serif;
}
.card {
width: 220px;
height: 150px;
border-radius: 24px;
background: linear-gradient(135deg, #fb923c, #facc15);
color: white;
display: grid;
place-items: center;
font-size: 24px;
font-weight: bold;
transition:
transform 0.5s ease,
border-radius 0.5s ease,
background 0.5s ease,
box-shadow 0.5s ease;
}
.card:hover {
transform: translateY(-25px) rotate(4deg) scale(1.08);
border-radius: 45px;
background: linear-gradient(135deg, #7c3aed, #2563eb);
box-shadow: 0 18px 35px rgba(37, 99, 235, 0.35);
}
</style>
</head>
<body>
<div class="card">Hover me</div>
</body>
</html>
3. CSS Keyframes: Planned Motion
@keyframes lets us describe animation steps. Below, the ball moves from one vertical position to another.
Full Example: Bouncing Ball
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Bouncing Ball Animation</title>
<style>
body {
min-height: 100vh;
margin: 0;
display: grid;
place-items: center;
background: #fff7ed;
font-family: Arial, sans-serif;
}
.stage {
width: 320px;
height: 260px;
border: 3px dashed #fb923c;
border-radius: 24px;
display: grid;
place-items: center;
background: #ffedd5;
overflow: hidden;
}
.ball {
width: 80px;
height: 80px;
border-radius: 50%;
background: radial-gradient(circle at 30% 30%, white, #fb923c, #c2410c);
animation: bounce 1s ease-in-out infinite alternate;
}
@keyframes bounce {
from {
transform: translateY(70px);
}
to {
transform: translateY(-70px);
}
}
</style>
</head>
<body>
<div class="stage">
<div class="ball"></div>
</div>
</body>
</html>
4. Transform: Move, Rotate, Scale
Most modern animations use transform. It is fast and smooth.
Full Example: Spin and Grow
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Transform Animation</title>
<style>
body {
min-height: 100vh;
margin: 0;
display: grid;
place-items: center;
background: #eff6ff;
font-family: Arial, sans-serif;
}
.shape {
width: 100px;
height: 100px;
background: linear-gradient(135deg, #2563eb, #7c3aed);
border-radius: 22px;
animation: spinAndGrow 2.2s linear infinite;
box-shadow: 0 12px 24px rgba(37, 99, 235, 0.25);
}
@keyframes spinAndGrow {
0% {
transform: rotate(0deg) scale(0.7);
}
50% {
transform: rotate(180deg) scale(1.25);
border-radius: 50%;
}
100% {
transform: rotate(360deg) scale(0.7);
}
}
</style>
</head>
<body>
<div class="shape"></div>
</body>
</html>
5. Timing Functions: The Feeling of Motion
Animation is not only about movement. It is also about speed.
Full Example: Timing Function Demo
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Timing Function Demo</title>
<style>
body {
margin: 0;
min-height: 100vh;
display: grid;
place-items: center;
background: #fff7ed;
font-family: Arial, sans-serif;
}
.panel {
width: min(90vw, 600px);
background: white;
border: 2px solid #fed7aa;
border-radius: 24px;
padding: 24px;
}
.track {
height: 160px;
border: 3px dashed #fb923c;
border-radius: 20px;
display: flex;
align-items: center;
padding: 20px;
overflow: hidden;
background: #ffedd5;
}
.ball {
width: 70px;
height: 70px;
border-radius: 50%;
background: #ff8a00;
display: grid;
place-items: center;
color: white;
font-weight: bold;
}
select,
button {
margin-top: 14px;
padding: 10px 14px;
border-radius: 999px;
font-size: 16px;
}
button {
border: none;
background: #ff8a00;
color: white;
font-weight: bold;
cursor: pointer;
}
</style>
</head>
<body>
<div class="panel">
<h1>Timing Function Demo</h1>
<div class="track">
<div class="ball" id="ball">Go</div>
</div>
<select id="timing">
<option value="linear">linear</option>
<option value="ease">ease</option>
<option value="ease-in">ease-in</option>
<option value="ease-out">ease-out</option>
<option value="ease-in-out">ease-in-out</option>
<option value="cubic-bezier(.68,-0.55,.27,1.55)">bounce-like</option>
</select>
<button onclick="runDemo()">Run</button>
<button onclick="resetDemo()">Reset</button>
</div>
<script>
const ball = document.getElementById("ball");
const timing = document.getElementById("timing");
function runDemo() {
ball.style.transition = "transform 1s " + timing.value;
ball.style.transform = "translateX(380px) rotate(360deg)";
}
function resetDemo() {
ball.style.transition = "transform 0.3s ease";
ball.style.transform = "translateX(0) rotate(0)";
}
</script>
</body>
</html>
6. Interactive Animation Playground
Change the sliders and see how transform changes the object.
Live CSS
transform: translateX(0px) rotate(0deg) scale(1);
border-radius: 24px;
Full Example: Slider Controlled Animation
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Interactive Animation Playground</title>
<style>
body {
margin: 0;
min-height: 100vh;
background: #fff7ed;
font-family: Arial, sans-serif;
display: grid;
place-items: center;
}
.panel {
width: min(92vw, 700px);
background: white;
border: 2px solid #fed7aa;
border-radius: 24px;
padding: 24px;
box-shadow: 0 14px 30px rgba(124, 45, 18, 0.14);
}
.stage {
height: 230px;
border: 3px dashed #fb923c;
border-radius: 20px;
display: grid;
place-items: center;
background: #ffedd5;
overflow: hidden;
margin-bottom: 20px;
}
.object {
width: 90px;
height: 90px;
border-radius: 24px;
background: linear-gradient(135deg, #ff8a00, #dc2626);
transition: transform 0.25s ease, border-radius 0.25s ease;
}
label {
display: block;
font-weight: bold;
margin-top: 12px;
}
input {
width: 100%;
}
pre {
background: #111827;
color: #e5e7eb;
padding: 16px;
border-radius: 14px;
overflow-x: auto;
}
</style>
</head>
<body>
<div class="panel">
<h1>Animation Playground</h1>
<div class="stage">
<div class="object" id="object"></div>
</div>
<label>Move X: <span id="moveText">0</span>px</label>
<input id="move" type="range" min="-220" max="220" value="0" />
<label>Rotate: <span id="rotateText">0</span>deg</label>
<input id="rotate" type="range" min="0" max="360" value="0" />
<label>Scale: <span id="scaleText">1</span></label>
<input id="scale" type="range" min="0.5" max="2" value="1" step="0.1" />
<label>Border Radius: <span id="radiusText">24</span>px</label>
<input id="radius" type="range" min="0" max="50" value="24" />
<h2>Live CSS</h2>
<pre id="output"></pre>
</div>
<script>
const object = document.getElementById("object");
const move = document.getElementById("move");
const rotate = document.getElementById("rotate");
const scale = document.getElementById("scale");
const radius = document.getElementById("radius");
const moveText = document.getElementById("moveText");
const rotateText = document.getElementById("rotateText");
const scaleText = document.getElementById("scaleText");
const radiusText = document.getElementById("radiusText");
const output = document.getElementById("output");
function updateAnimation() {
const x = move.value;
const r = rotate.value;
const s = scale.value;
const br = radius.value;
object.style.transform =
"translateX(" + x + "px) rotate(" + r + "deg) scale(" + s + ")";
object.style.borderRadius = br + "px";
moveText.textContent = x;
rotateText.textContent = r;
scaleText.textContent = s;
radiusText.textContent = br;
output.textContent =
"transform: translateX(" + x + "px) rotate(" + r + "deg) scale(" + s + ");\\n" +
"border-radius: " + br + "px;";
}
move.addEventListener("input", updateAnimation);
rotate.addEventListener("input", updateAnimation);
scale.addEventListener("input", updateAnimation);
radius.addEventListener("input", updateAnimation);
updateAnimation();
</script>
</body>
</html>
7. Animated Scene: Car, Cloud, Sun
A scene is many small animations working together.
Full Example: Animated Car Scene
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Animated Scene</title>
<style>
body {
margin: 0;
min-height: 100vh;
display: grid;
place-items: center;
background: #fff7ed;
font-family: Arial, sans-serif;
}
.scene {
width: min(92vw, 800px);
height: 300px;
position: relative;
background: linear-gradient(#bfdbfe, #dbeafe 62%, #86efac 62%, #22c55e);
border-radius: 24px;
overflow: hidden;
border: 3px solid #93c5fd;
}
.sun {
position: absolute;
top: 30px;
right: 55px;
width: 70px;
height: 70px;
background: #facc15;
border-radius: 50%;
box-shadow: 0 0 35px #facc15;
animation: pulseSun 2s ease-in-out infinite alternate;
}
@keyframes pulseSun {
from {
transform: scale(1);
}
to {
transform: scale(1.18);
}
}
.cloud {
position: absolute;
top: 70px;
left: -130px;
width: 130px;
height: 45px;
background: white;
border-radius: 999px;
animation: moveCloud 8s linear infinite;
}
.cloud::before,
.cloud::after {
content: "";
position: absolute;
background: white;
border-radius: 50%;
}
.cloud::before {
width: 55px;
height: 55px;
top: -22px;
left: 20px;
}
.cloud::after {
width: 70px;
height: 70px;
top: -35px;
left: 55px;
}
@keyframes moveCloud {
from {
transform: translateX(0);
}
to {
transform: translateX(950px);
}
}
.car {
position: absolute;
bottom: 80px;
left: 20px;
width: 140px;
height: 55px;
background: #ef4444;
border-radius: 28px 36px 12px 12px;
animation: driveCar 5s ease-in-out infinite alternate;
}
.car::before {
content: "";
position: absolute;
width: 62px;
height: 35px;
background: #bfdbfe;
top: -24px;
left: 36px;
border-radius: 20px 20px 0 0;
}
.wheel {
position: absolute;
bottom: -15px;
width: 32px;
height: 32px;
background: #111827;
border-radius: 50%;
border: 5px solid #e5e7eb;
animation: wheelSpin 0.7s linear infinite;
}
.wheel.one {
left: 22px;
}
.wheel.two {
right: 22px;
}
@keyframes driveCar {
from {
transform: translateX(0);
}
to {
transform: translateX(600px);
}
}
@keyframes wheelSpin {
to {
transform: rotate(360deg);
}
}
</style>
</head>
<body>
<div class="scene">
<div class="sun"></div>
<div class="cloud"></div>
<div class="car">
<div class="wheel one"></div>
<div class="wheel two"></div>
</div>
</div>
</body>
</html>
8. Useful Animation Patterns
Loader
Progress Bar
Typewriter
Full Example: Loader, Progress Bar, Typewriter
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Useful Animation Patterns</title>
<style>
body {
margin: 0;
min-height: 100vh;
display: grid;
place-items: center;
background: #fff7ed;
font-family: Arial, sans-serif;
}
.grid {
width: min(92vw, 900px);
display: grid;
grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
gap: 20px;
}
.card {
background: white;
border: 2px solid #fed7aa;
border-radius: 24px;
padding: 24px;
text-align: center;
}
.loader {
width: 82px;
height: 82px;
border: 10px solid #ffedd5;
border-top-color: #ff8a00;
border-radius: 50%;
margin: 20px auto;
animation: loaderSpin 1s linear infinite;
}
@keyframes loaderSpin {
to {
transform: rotate(360deg);
}
}
.progress-track {
height: 20px;
background: #ffedd5;
border-radius: 999px;
overflow: hidden;
margin-top: 38px;
}
.progress-fill {
width: 0%;
height: 100%;
background: linear-gradient(90deg, #16a34a, #facc15, #ff8a00);
animation: loadingBar 3s ease-in-out infinite;
}
@keyframes loadingBar {
0% {
width: 0%;
}
50% {
width: 82%;
}
100% {
width: 100%;
}
}
.typewriter {
max-width: max-content;
overflow: hidden;
border-right: 4px solid #c2410c;
white-space: nowrap;
animation:
typing 4s steps(34, end) infinite alternate,
blink 0.65s step-end infinite;
font-weight: bold;
color: #9a3412;
margin: 42px auto;
}
@keyframes typing {
from {
width: 0;
}
to {
width: 34ch;
}
}
@keyframes blink {
50% {
border-color: transparent;
}
}
</style>
</head>
<body>
<div class="grid">
<div class="card">
<h2>Loader</h2>
<div class="loader"></div>
</div>
<div class="card">
<h2>Progress Bar</h2>
<div class="progress-track">
<div class="progress-fill"></div>
</div>
</div>
<div class="card">
<h2>Typewriter</h2>
<div class="typewriter">Animation makes websites alive.</div>
</div>
</div>
</body>
</html>
9. Scroll Animation
Scroll animation means an element appears when it enters the screen.
Step 1
The element starts hidden using opacity 0.
Step 2
JavaScript observes when the element enters the screen.
Step 3
A class is added. The element fades and moves into place.
Full Example: Scroll Reveal Animation
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Scroll Reveal Animation</title>
<style>
body {
margin: 0;
background: #fff7ed;
font-family: Arial, sans-serif;
line-height: 1.7;
}
header {
min-height: 80vh;
display: grid;
place-items: center;
text-align: center;
background: linear-gradient(135deg, #ff8a00, #facc15);
color: white;
padding: 30px;
}
main {
max-width: 900px;
margin: auto;
padding: 40px 16px;
}
.card {
background: white;
border: 2px solid #fed7aa;
border-radius: 24px;
padding: 24px;
margin: 30px 0;
box-shadow: 0 14px 30px rgba(124, 45, 18, 0.14);
opacity: 0;
transform: translateY(45px);
transition: opacity 0.8s ease, transform 0.8s ease;
}
.card.visible {
opacity: 1;
transform: translateY(0);
}
</style>
</head>
<body>
<header>
<div>
<h1>Scroll Down</h1>
<p>Cards will appear when they enter the screen.</p>
</div>
</header>
<main>
<div class="card">
<h2>Card 1</h2>
<p>This card fades in and moves upward.</p>
</div>
<div class="card">
<h2>Card 2</h2>
<p>The browser observes when it becomes visible.</p>
</div>
<div class="card">
<h2>Card 3</h2>
<p>Then JavaScript adds the visible class.</p>
</div>
</main>
<script>
const observer = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
entry.target.classList.add("visible");
}
});
}, {
threshold: 0.25
});
document.querySelectorAll(".card").forEach(function(card) {
observer.observe(card);
});
</script>
</body>
</html>
10. Mini Quiz
Question: Which two CSS properties are usually best for smooth animation?
11. Practice Tasks
Level 1
Create a button that becomes bigger on hover.
Level 2
Create a ball that bounces forever.
Level 3
Create a loading spinner using border and rotate.
Level 4
Create a card that fades in when the page scrolls.
Level 5
Create sliders to control move, rotate, and scale.
Infinity Level
Create a small animated story: sun rises, bird flies, car moves, title appears.
12. Full Mini Project: Animated Landing Page
This final example combines title animation, button hover, floating cards, and repeated motion.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Animated Landing Page</title>
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
min-height: 100vh;
font-family: Arial, sans-serif;
background:
radial-gradient(circle at top left, rgba(255, 138, 0, 0.25), transparent 30%),
radial-gradient(circle at bottom right, rgba(37, 99, 235, 0.18), transparent 30%),
#fff7ed;
color: #1f2937;
overflow-x: hidden;
}
.hero {
min-height: 100vh;
display: grid;
place-items: center;
padding: 30px;
text-align: center;
position: relative;
}
.hero-content {
max-width: 760px;
background: rgba(255, 255, 255, 0.86);
border: 2px solid #fed7aa;
border-radius: 30px;
padding: 40px;
box-shadow: 0 20px 45px rgba(124, 45, 18, 0.14);
animation: fadeUp 1s ease both;
}
h1 {
font-size: clamp(2.2rem, 7vw, 5rem);
margin: 0;
color: #9a3412;
animation: titlePop 1.2s ease both;
}
p {
font-size: 1.2rem;
line-height: 1.7;
}
button {
border: none;
border-radius: 999px;
background: #ff8a00;
color: white;
padding: 16px 26px;
font-size: 18px;
font-weight: bold;
cursor: pointer;
transition: transform 0.3s ease, box-shadow 0.3s ease;
animation: softPulse 1.6s ease-in-out infinite alternate;
}
button:hover {
transform: translateY(-5px) scale(1.08);
box-shadow: 0 18px 32px rgba(249, 115, 22, 0.35);
}
.floating-card {
position: absolute;
width: 110px;
height: 110px;
border-radius: 24px;
display: grid;
place-items: center;
color: white;
font-weight: bold;
box-shadow: 0 16px 30px rgba(15, 23, 42, 0.18);
}
.card-one {
top: 12%;
left: 8%;
background: #2563eb;
animation: floatOne 3s ease-in-out infinite alternate;
}
.card-two {
right: 8%;
bottom: 14%;
background: #7c3aed;
animation: floatTwo 3.4s ease-in-out infinite alternate;
}
.card-three {
right: 12%;
top: 14%;
background: #16a34a;
animation: spinSlow 5s linear infinite;
}
@keyframes fadeUp {
from {
opacity: 0;
transform: translateY(40px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes titlePop {
0% {
opacity: 0;
transform: scale(0.75);
}
70% {
transform: scale(1.08);
}
100% {
opacity: 1;
transform: scale(1);
}
}
@keyframes softPulse {
from {
box-shadow: 0 0 0 rgba(249, 115, 22, 0.2);
}
to {
box-shadow: 0 0 35px rgba(249, 115, 22, 0.65);
}
}
@keyframes floatOne {
from {
transform: translateY(0) rotate(-5deg);
}
to {
transform: translateY(35px) rotate(8deg);
}
}
@keyframes floatTwo {
from {
transform: translateY(0) rotate(5deg);
}
to {
transform: translateY(-35px) rotate(-8deg);
}
}
@keyframes spinSlow {
to {
transform: rotate(360deg);
}
}
@media (max-width: 700px) {
.floating-card {
display: none;
}
.hero-content {
padding: 28px;
}
}
</style>
</head>
<body>
<main class="hero">
<div class="floating-card card-one">HTML</div>
<div class="floating-card card-two">CSS</div>
<div class="floating-card card-three">JS</div>
<section class="hero-content">
<h1>Animation</h1>
<p>
Animation makes a web page feel alive.
Start with transitions, then learn keyframes,
then control motion with JavaScript.
</p>
<button>Start Learning</button>
</section>
</main>
</body>
</html>
13. Final Understanding
Transition
For smooth change between two states.
Keyframes
For planned motion with steps.
Transform
For fast movement, rotation, and scaling.
JavaScript
For user-controlled animation.