We use cookies to enhance your experience on the site
CodeWorlds

CSS Transitions - smooth transitions between states

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!

What are Transitions?

Transitions allow for a smooth change of CSS properties from one value to another over a specified time.

Without transition:

  • The change is instant (0ms)
  • A "jump" effect

With transition:

  • The change is gradual
  • A smooth, professional effect
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.

Transition Syntax

Basic syntax

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}

Transition components:

  1. transition-property - which property to animate
  2. transition-duration - how long the animation lasts
  3. transition-timing-function - how the speed changes over time
  4. transition-delay - delay before starting

Transition-property - what to animate?

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:

  • Colors: color, background-color, border-color
  • Dimensions: width, height, padding, margin
  • Position: top, left, right, bottom
  • Transform: transform
  • Opacity: opacity
  • Box-shadow, border-radius, font-size, line-height
  • And many more...

Properties that CANNOT be animated:

  • display (no intermediate values)
  • position (static, relative, absolute)
  • font-family (no intermediate values)

Transition-duration - how long?

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:

  • 0.15s-0.2s - fast, responsive (hover on links)
  • 0.3s-0.4s - standard (buttons, cards)
  • 0.5s-0.8s - slower, more dramatic (large changes)
  • 1s+ - very slow (only for special effects)

Transition-timing-function - timing curve

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:

  • linear: ————————— (constant speed)
  • ease: _/‾‾‾_ (slow start and end)
  • ease-in: __/‾‾ (slow start)
  • ease-out: ‾‾__ (slow end)
  • ease-in-out: _/‾_ (most natural)

Online tool: https://cubic-bezier.com/

Transition-delay - delay

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}

Practical examples

1. Button hover effect

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}

2. Card hover - reveal

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}

3. Navigation link underline

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}

4. Modal fade-in

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}

5. Loading skeleton

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}

Transitions vs Animations

Use Transitions when:

  • You need a simple change between two states
  • The animation is triggered by user interaction (hover, focus, click)
  • You want to animate the return to the initial state
  • Simpler implementation

Use Animations (@keyframes) when:

  • You need more than 2 states (keyframes)
  • The animation should run automatically (without interaction)
  • You need loops (infinite)
  • You need precise timing control

Multiple Transitions

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.

Performance Transitions

Fast properties (GPU-accelerated):

  • transform
    (translate, scale, rotate)
  • opacity

Slow 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}

Summary

CSS Transitions:

  • Smooth transitions between two states
  • Triggered by CSS changes (hover, focus, class)
  • Syntax:
    transition: property duration timing-function delay
  • Most popular: opacity, transform
  • Recommended time: 0.2s-0.4s
  • Timing function: ease-in-out for naturalness

Best Practices:

  1. Animate transform and opacity for performance
  2. Use ease-in-out for naturalness
  3. 0.2s-0.4s for most interactions
  4. Test on mobile devices
  5. Add transitions to the base state, not :hover

Remember: Transitions are like the smooth movement of the sun over the Egyptian pyramids - no jumps, but gradual, natural transitions!

Go to CodeWorlds