Day 13: Transitions & Transforms
✅ Today you will learn
- transition: property, duration, timing function, delay
- Which properties to animate (and which not to)
- transform: translate, scale, rotate, skew; transform-origin
- Hover effects: lift cards, zoom images, slide underlines
- 3D flip card with perspective and backface-visibility
🏢 In the real world
Clients often say “make it feel premium” without knowing what that means. Most of the time it means micro-interactions: a button that responds, a card that lifts slightly, a photo that zooms gently. Done right they take 0.2 seconds and 3 lines of CSS; done wrong they make the site feel slow and janky.
transition: from A to B smoothly
<style>
.btn { background: #264de4; color: #fff; border: 0; padding: 10px 18px; border-radius: 8px; font-size: 1rem; margin: 4px; cursor: pointer; }
.no-anim:hover { background: #0f766e; }
.anim {
transition: background-color .25s ease, transform .25s ease, box-shadow .25s ease;
}
.anim:hover {
background: #0f766e;
transform: translateY(-3px);
box-shadow: 0 10px 20px rgb(0 0 0 / 15%);
}
.anim:active { transform: translateY(0); }
</style>
<button class="btn no-anim">No transition</button>
<button class="btn anim">With transition</button>| Part | Example | Meaning |
|---|---|---|
| property | transform | What to animate (avoid “all”) |
| duration | .25s / 250ms | UI feedback: 150–300ms; bigger moves: 300–500ms |
| timing-function | ease, ease-out, linear, cubic-bezier() | Speed curve; ease-out feels natural for things entering |
| delay | .1s | Wait before starting – good for staggering |
<style>
.track { background: #f1f5f9; border-radius: 8px; margin: 6px 0; padding: 4px; }
.dot { width: 34px; height: 34px; border-radius: 50%; background: #264de4; transition: transform 1.2s; }
.track:hover .dot { transform: translateX(260px); }
.linear { transition-timing-function: linear; }
.ease { transition-timing-function: ease; }
.easeout { transition-timing-function: ease-out; }
.bounce { transition-timing-function: cubic-bezier(.68,-0.55,.27,1.55); background: #f59e0b; }
</style>
<p style="font:13px system-ui">Hover the grey area – compare the speed curves</p>
<div class="track"><div class="dot linear"></div></div>
<div class="track"><div class="dot ease"></div></div>
<div class="track"><div class="dot easeout"></div></div>
<div class="track"><div class="dot bounce"></div></div>transform: move, scale, rotate, skew
<style>
.t { display: inline-grid; place-items: center; width: 90px; height: 90px; margin: 18px; background: #264de4; color: #fff; border-radius: 10px; font: 600 12px system-ui; }
.t1 { transform: translate(20px, -10px); }
.t2 { transform: scale(1.2); }
.t3 { transform: rotate(15deg); }
.t4 { transform: skewX(-12deg); }
.t5 { transform: rotate(45deg); transform-origin: top left; background: #c2410c; }
</style>
<div class="t t1">translate</div><div class="t t2">scale 1.2</div><div class="t t3">rotate 15°</div><div class="t t4">skewX</div><div class="t t5">origin: top left</div>Changing width, height, top, left or margin forces the browser to recalculate layout on every frame – janky on cheap phones. transform and opacity are handled by the GPU and stay at 60fps.
Real hover effects
<style>
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 14px; }
.card { background: #fff; border-radius: 14px; overflow: hidden; box-shadow: 0 2px 8px rgb(0 0 0 / 8%); transition: transform .25s ease, box-shadow .25s ease; }
.card:hover { transform: translateY(-6px); box-shadow: 0 16px 30px rgb(0 0 0 / 14%); }
.card .img { overflow: hidden; }
.card img { display: block; width: 100%; transition: transform .5s ease; }
.card:hover img { transform: scale(1.08); }
.card p { margin: 0; padding: 10px 12px; font-weight: 600; }
.link { position: relative; color: #264de4; text-decoration: none; font-weight: 600; }
.link::after { content: ""; position: absolute; left: 0; bottom: -3px; height: 2px; width: 100%; background: currentColor; transform: scaleX(0); transform-origin: left; transition: transform .3s ease; }
.link:hover::after { transform: scaleX(1); }
</style>
<div class="grid">
<div class="card"><div class="img"><img src="images/kaju-katli-400.webp" alt="Kaju katli"></div><p>Kaju Katli</p></div>
<div class="card"><div class="img"><img src="images/ghewar-400.webp" alt="Ghewar"></div><p>Ghewar</p></div>
<div class="card"><div class="img"><img src="images/rasmalai-400.webp" alt="Rasmalai"></div><p>Rasmalai</p></div>
</div>
<p style="margin-top:16px">Read our <a class="link" href="#">ghewar recipe story</a> – hover me.</p>3D flip card
<style>
.flip { width: 220px; height: 150px; perspective: 800px; display: inline-block; margin: 6px; }
.inner { position: relative; width: 100%; height: 100%; transition: transform .6s; transform-style: preserve-3d; }
.flip:hover .inner, .flip:focus-within .inner { transform: rotateY(180deg); }
.face { position: absolute; inset: 0; border-radius: 14px; display: grid; place-items: center; text-align: center; padding: 12px; backface-visibility: hidden; font: 600 15px system-ui; }
.front { background: linear-gradient(135deg, #264de4, #06b6d4); color: #fff; }
.back { background: #fff7ed; border: 2px solid #f59e0b; transform: rotateY(180deg); }
</style>
<div class="flip" tabindex="0"><div class="inner">
<div class="face front">Q: Which two properties animate smoothest?</div>
<div class="face back">transform and opacity ✅</div>
</div></div>
<div class="flip" tabindex="0"><div class="inner">
<div class="face front">Rasmalai 🍮</div>
<div class="face back">Paneer discs in kesar milk · ₹700/kg</div>
</div></div>| 3D property | Role |
|---|---|
| perspective (on parent) | Distance of the viewer – smaller = stronger 3D |
| transform-style: preserve-3d | Children keep their 3D position |
| backface-visibility: hidden | Hide the back of each face while rotated |
| rotateY(180deg) | Turn around the vertical axis |
Never hide important information behind hover only. Add :focus-within (keyboard) and make the effect decorative, or wrap hover styles in @media (hover: hover).
🏅 Job skills unlocked today
Practice tasks
🏋️ Practice – do it yourself
Show solution
Quick quiz
🧠 Quick Quiz – test yourself
Interview corner
💼 Interview Corner
Why is animating transform faster than animating left/top?
left/top change layout, so the browser must recalculate layout and repaint every frame. transform (and opacity) can be applied on the compositor/GPU layer without layout or paint, giving smooth 60fps animations.
Transition vs animation?
A transition interpolates between two states when a property changes (e.g. on hover). A keyframe animation runs a defined sequence of steps on its own, can loop, and does not need a state change.
Summary
- transition: property duration easing delay on the base state.
- Animate transform and opacity for smooth 60fps.
- translate / scale / rotate / skew + transform-origin.
- Hover effects must also work with focus and never hide key info.
Day 14: @keyframes animations – loaders, attention pulses, scroll reveals and reduced-motion support.
