CSS transitions allow property changes to occur smoothly over a specified duration, rather than instantaneously. When an element's property value changes — whether triggered by a class toggle, :hover pseudo-class, or JavaScript DOM manipulation — the transition interpolates between the old and new values.
Transitions are the simplest form of CSS animation: they define a starting state, an ending state, and how the interpolation between them should behave. For multi-step sequences, use CSS Animations with @keyframes instead.
transitions-intro.css
CSS
1
.button {
2
background: #1A1A2E;
3
color: #A0A0A0;
4
transition: background 0.3s ease, color 0.3s ease;
5
}
6
7
.button:hover {
8
background: #00FF41;
9
color: #0D0D0D;
10
}
preview
transition-property
The transition-property specifies which CSS properties should be transitioned when their values change. You can list multiple properties separated by commas, or use the all keyword to transition every animatable property.
/* Best practice: be explicit about what to transition */
13
.explicit {
14
transition-property: transform, opacity;
15
/* Only these two properties will animate */
16
}
⚠
warning
Using transition-property: all is convenient but can cause performance issues and unexpected animations. Be explicit about which properties you want to transition — it is more maintainable and performant.
transition-duration
transition-duration defines how long the transition takes to complete. Values are specified in seconds (s) or milliseconds (ms). When multiple properties are being transitioned, you can specify different durations for each.
The timing function (easing curve) controls the rate of change during the transition. It determines whether the animation starts fast and slows down, starts slow and speeds up, or moves at a constant pace.
timing-function.css
CSS
1
.element {
2
/* Keyword timing functions */
3
transition-timing-function: ease; /* slow start, fast middle, slow end (default) */
transition-delay specifies how long to wait before the transition begins. A positive value delays the start; a negative value starts the transition mid-way through its duration (as if it had already been running).
transition-delay.css
CSS
1
.element {
2
/* Start after 0.2s delay */
3
transition-delay: 0.2s;
4
5
/* Negative delay — starts mid-transition */
6
transition-delay: -0.5s;
7
/* If duration is 1s, starts at 50% progress */
8
}
9
10
/* Staggered delays for lists */
11
.item:nth-child(1) { transition-delay: 0s; }
12
.item:nth-child(2) { transition-delay: 0.1s; }
13
.item:nth-child(3) { transition-delay: 0.2s; }
14
.item:nth-child(4) { transition-delay: 0.3s; }
15
.item:nth-child(5) { transition-delay: 0.4s; }
preview
transition Shorthand
The transition shorthand combines all four transition sub-properties into a single declaration. The order is: property | duration | timing-function | delay.
Not all CSS properties can be transitioned. Animatable properties are those that accept numeric values, colors, or discrete enumerated values. Below are the key categories of animatable properties.
transition: color 0.2s ease, background-color 0.2s ease;
9
}
10
11
.bad {
12
/* Triggers layout — avoid for animation */
13
transition: width 0.3s ease, height 0.3s ease;
14
}
15
16
/* Instead of animating width/height, use transforms */
17
.better {
18
transition: transform 0.3s ease;
19
/* transform: scaleX(1.5) instead of width: 150% */
20
}
Triggering Transitions
Transitions are triggered whenever a property value changes. The most common triggers are pseudo-classes like :hover and :focus, but any value change — including JavaScript-driven class toggles and inline style manipulation — will trigger a transition.
Terminal-themed interfaces benefit from subtle, responsive hover effects. These micro-interactions make the interface feel alive and responsive without being distracting.
terminal-hover.css
CSS
1
.terminal-link {
2
color: #00FF41;
3
text-decoration: none;
4
position: relative;
5
transition: color 0.2s ease;
6
}
7
8
.terminal-link::after {
9
content: '';
10
position: absolute;
11
bottom: -2px;
12
left: 0;
13
width: 0;
14
height: 1px;
15
background: #00FF41;
16
transition: width 0.3s ease;
17
}
18
19
.terminal-link:hover {
20
color: #00FF41;
21
}
22
23
.terminal-link:hover::after{
24
width: 100%;
25
}
26
27
/* Terminal button glow */
28
.terminal-btn {
29
background: #1A1A2E;
30
border: 1px solid #222222;
31
color: #E0E0E0;
32
padding: 8px 16px;
33
border-radius: 4px;
34
font-family: monospace;
35
transition:
36
border-color 0.2s ease,
37
box-shadow 0.2s ease,
38
color 0.2s ease;
39
}
40
41
.terminal-btn:hover {
42
border-color: #00FF41;
43
box-shadow: 0 0 12px rgba(0, 255, 65, 0.15);
44
color: #00FF41;
45
}
46
47
/* Scanline accent pulse */
48
.scanline-accent {
49
transition: opacity 0.3s ease;
50
}
51
52
.scanline-accent:hover {
53
animation: scanPulse 0.5s ease;
54
}
55
56
@keyframes scanPulse {
57
0%, 100% { opacity: 1; }
58
50% { opacity: 0.7; }
59
}
preview
Best Practices
◆Only transition transform and opacity for 60fps performance
◆Be explicit about transition-property — avoid 'all' for performance and predictability
◆Use ease-out for enter transitions, ease-in for exit transitions
◆Keep transition durations short: 150-300ms for micro-interactions
◆Use cubic-bezier spring curves (0.34, 1.56, 0.64, 1) for playful interactions
◆Set a shorter reverse transition (out) than forward (in) for responsive feel
◆Use transition-delay for staggered sequencing in lists and groups
◆Always test transitions on low-powered devices — what's smooth on desktop may jank on mobile
◆Respect prefers-reduced-motion by wrapping transitions in no-preference media queries