Welcome to the Valley of the Kings of Animation! Just as Egyptian hieroglyphs could change from one form to another under the influence of sunlight, in CSS we can create smooth transitions - transitions between element states. This is the simplest and most commonly used way to add animation to a page!
Transitions allow for a smooth change of CSS properties from one value to another over a specified time.
Without transition:
With transition:
1/* Without transition */
2.button {
3 background: blue;
4}
5
6.button:hover {
7 background: red; /* Instant change */
8}
9
10/* With transition */
11.button {
12 background: blue;
13 transition: background 0.3s; /* Smooth change over 0.3s */
14}
15
16.button:hover {
17 background: red; /* Now the change is smooth! */
18}Egyptian analogy: It's like the smooth movement of the sun from sunrise to sunset over the pyramids - it doesn't jump instantly, but moves gradually.
1/* transition: property duration timing-function delay; */
2
3.element {
4 transition: background-color 0.3s ease 0s;
5}
6
7/* Or separately */
8.element {
9 transition-property: background-color;
10 transition-duration: 0.3s;
11 transition-timing-function: ease;
12 transition-delay: 0s;
13}1/* One property */
2.button {
3 transition-property: background-color;
4}
5
6/* Multiple properties */
7.button {
8 transition-property: background-color, color, transform;
9}
10
11/* All properties (use carefully!) */
12.button {
13 transition-property: all;
14}Properties that can be animated:
Properties that CANNOT be animated:
1/* In seconds */
2.element {
3 transition-duration: 0.3s; /* 300ms - standard value */
4}
5
6/* In milliseconds */
7.element {
8 transition-duration: 300ms;
9}
10
11/* Different times for different properties */
12.element {
13 transition-property: background-color, transform;
14 transition-duration: 0.3s, 0.5s;
15 /* background-color: 0.3s, transform: 0.5s */
16}Recommended times:
The timing function defines how the animation speed changes over time:
1.element {
2 /* Linear - constant speed */
3 transition-timing-function: linear;
4
5 /* Ease - slow start, fast, slow end (default) */
6 transition-timing-function: ease;
7
8 /* Ease-in - slow start, fast end */
9 transition-timing-function: ease-in;
10
11 /* Ease-out - fast start, slow end */
12 transition-timing-function: ease-out;
13
14 /* Ease-in-out - slow start and end */
15 transition-timing-function: ease-in-out;
16
17 /* Cubic-bezier - custom curve */
18 transition-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55);
19
20 /* Steps - stepped (not smooth) */
21 transition-timing-function: steps(4);
22}Timing function visualization:
Online tool: https://cubic-bezier.com/
1.element {
2 transition-delay: 0.2s; /* Start after 0.2s */
3}
4
5/* Different delays for different properties */
6.element {
7 transition-property: opacity, transform;
8 transition-duration: 0.3s, 0.3s;
9 transition-delay: 0s, 0.1s;
10 /* opacity immediately, transform after 0.1s */
11}1<button class="btn">Click me</button>1.btn {
2 background: #3498db;
3 color: white;
4 padding: 12px 24px;
5 border: none;
6 border-radius: 4px;
7 cursor: pointer;
8 font-size: 16px;
9
10 /* Transition on multiple properties */
11 transition: background-color 0.3s ease,
12 transform 0.2s ease,
13 box-shadow 0.3s ease;
14}
15
16.btn:hover {
17 background: #2980b9;
18 transform: translateY(-2px);
19 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
20}
21
22.btn:active {
23 transform: translateY(0);
24 box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
25}1<div class="card">
2 <img src="pyramid.jpg" alt="Pyramid">
3 <div class="card-overlay">
4 <h3>Great Pyramid</h3>
5 <p>One of the Seven Wonders of the World</p>
6 </div>
7</div>1.card {
2 position: relative;
3 width: 300px;
4 height: 400px;
5 overflow: hidden;
6 border-radius: 8px;
7}
8
9.card img {
10 width: 100%;
11 height: 100%;
12 object-fit: cover;
13 transition: transform 0.5s ease;
14}
15
16.card-overlay {
17 position: absolute;
18 bottom: 0;
19 left: 0;
20 right: 0;
21 background: linear-gradient(to top, rgba(0,0,0,0.8), transparent);
22 padding: 20px;
23 color: white;
24
25 /* Overlay starts below the card */
26 transform: translateY(100%);
27 transition: transform 0.4s ease;
28}
29
30.card:hover img {
31 transform: scale(1.1); /* Zoom on image */
32}
33
34.card:hover .card-overlay {
35 transform: translateY(0); /* Overlay slides in */
36}1<nav>
2 <a href="#" class="nav-link">Home</a>
3 <a href="#" class="nav-link">About</a>
4 <a href="#" class="nav-link">Contact</a>
5</nav>1.nav-link {
2 position: relative;
3 color: #2c3e50;
4 text-decoration: none;
5 padding: 10px 0;
6 display: inline-block;
7}
8
9/* Underline as ::after pseudo-element */
10.nav-link::after {
11 content: '';
12 position: absolute;
13 bottom: 0;
14 left: 0;
15 width: 0; /* Starts from 0 */
16 height: 2px;
17 background: goldenrod;
18
19 /* Animate width */
20 transition: width 0.3s ease;
21}
22
23.nav-link:hover::after {
24 width: 100%; /* Expand to full width */
25}1<div class="modal" id="myModal">
2 <div class="modal-content">
3 <h2>Modal Title</h2>
4 <p>Modal content...</p>
5 <button class="close">Close</button>
6 </div>
7</div>1.modal {
2 position: fixed;
3 top: 0;
4 left: 0;
5 width: 100%;
6 height: 100%;
7 background: rgba(0, 0, 0, 0.8);
8 display: flex;
9 align-items: center;
10 justify-content: center;
11
12 /* Starts invisible */
13 opacity: 0;
14 pointer-events: none;
15
16 /* Animate opacity and backdrop */
17 transition: opacity 0.3s ease;
18}
19
20.modal.active {
21 opacity: 1;
22 pointer-events: auto;
23}
24
25.modal-content {
26 background: white;
27 padding: 30px;
28 border-radius: 8px;
29 max-width: 500px;
30
31 /* Starts below */
32 transform: translateY(50px);
33 transition: transform 0.3s ease 0.1s; /* 0.1s delay */
34}
35
36.modal.active .modal-content {
37 transform: translateY(0);
38}1<div class="skeleton">
2 <div class="skeleton-line"></div>
3 <div class="skeleton-line"></div>
4 <div class="skeleton-line short"></div>
5</div>1.skeleton-line {
2 height: 16px;
3 background: linear-gradient(
4 90deg,
5 #f0f0f0 0%,
6 #e0e0e0 50%,
7 #f0f0f0 100%
8 );
9 background-size: 200% 100%;
10 border-radius: 4px;
11 margin-bottom: 10px;
12
13 /* Animate gradient position */
14 animation: skeleton-loading 1.5s ease-in-out infinite;
15}
16
17.skeleton-line.short {
18 width: 60%;
19}
20
21@keyframes skeleton-loading {
22 0% {
23 background-position: 200% 0;
24 }
25 100% {
26 background-position: -200% 0;
27 }
28}Use Transitions when:
Use Animations (@keyframes) when:
1/* Shorthand - all at once */
2.element {
3 transition: background 0.3s ease,
4 color 0.3s ease,
5 transform 0.5s ease-out 0.1s,
6 box-shadow 0.4s ease;
7}
8
9/* Or even shorter (for the same values) */
10.element {
11 transition: all 0.3s ease;
12}Warning with
all: It may animate unwanted properties and affect performance. It's better to list specific properties.Fast properties (GPU-accelerated):
transform (translate, scale, rotate)opacitySlow properties:
width, height (cause reflow)margin, padding (cause reflow)top, left (slower than transform)1/* Slow */
2.element {
3 transition: width 0.3s, left 0.3s;
4}
5
6.element:hover {
7 width: 200px;
8 left: 100px;
9}
10
11/* Fast */
12.element {
13 transition: transform 0.3s, opacity 0.3s;
14}
15
16.element:hover {
17 transform: translateX(100px) scaleX(2);
18 opacity: 0.8;
19}CSS Transitions:
transition: property duration timing-function delayBest Practices:
Remember: Transitions are like the smooth movement of the sun over the Egyptian pyramids - no jumps, but gradual, natural transitions!