transition-property
transition-property specifies which CSS properties trigger a transition animation when their values change. You can transition individual properties, multiple properties, or all properties. Understanding which properties to animate improves both performance and user experience.
Specifying which properties to animate
CSS
<!-- transition-property: which properties animate -->
.element {
background: blue;
color: white;
transition-property: background;
transition-duration: 0.3s;
}
.element:hover {
background: red; /* animates -->
color: yellow; /* changes instantly -->
}
<!-- Only background transitions, color changes instantly -->
/* Multiple properties: comma-separated -->
.element {
background: blue;
transform: scale(1);
opacity: 1;
transition-property: background, transform, opacity;
transition-duration: 0.3s;
}
.element:hover {
background: red;
transform: scale(1.2);
opacity: 0.8;
}
<!-- All three properties animate -->
/* all: transition everything that changes -->
.element {
background: blue;
color: white;
border-color: black;
transition-property: all;
transition-duration: 0.3s;
}
.element:hover {
background: red;
color: yellow;
border-color: green;
}
<!-- All properties that change will animate -->
/* none: no transitions -->
.element {
transition-property: none;
/* Changes happen instantly -->
}
<!-- Disables all transitions -->Which properties animate well
Property | Animates | Performance | Best Use |
|---|---|---|---|
background-color | Yes | Good | Color changes |
opacity | Yes | Excellent | Fade effects |
transform | Yes | Excellent | Movement/scale |
width/height | Yes | Poor | Avoid when possible |
color | Yes | Good | Text color changes |
border-color | Yes | Good | Border changes |
CSS
<!-- Good: animate performant properties -->
.button {
background: blue;
opacity: 1;
transform: scale(1);
transition-property: background, opacity, transform;
transition-duration: 0.3s;
}
.button:hover {
background: red; /* animates smoothly */
opacity: 0.9; /* animates smoothly -->
transform: scale(1.1); /* animates smoothly -->
}
<!-- All three animate performantly (60fps) -->
/* Avoid: layout-triggering properties -->
.element {
transition-property: width, height, padding;
/* Avoid! Triggers reflow/repaints -->
}
.element:hover {
width: 200px; /* causes reflow -->
height: 200px; /* causes reflow -->
padding: 20px; /* causes reflow -->
}
<!-- Poor performance: causes jank -->
/* Better: use transform instead -->
.element {
transition-property: transform;
width: 100px;
height: 100px;
transition-duration: 0.3s;
}
.element:hover {
transform: scale(2); /* no reflow, smooth 60fps -->
}
<!-- Same visual effect, much better performance -->
/* Selective property animation -->
.card {
background: white;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
border: 1px solid #ddd;
transition-property: background, box-shadow;
transition-duration: 0.3s;
}
.card:hover {
background: #f9f9f9; /* animates -->
box-shadow: 0 8px 16px rgba(0,0,0,0.2); /* animates -->
border: 1px solid #999; /* instant -->
}Transition-property with multiple durations
CSS
<!-- Different duration per property -->
.element {
background: blue;
transform: scale(1);
opacity: 1;
transition-property: background, transform, opacity;
transition-duration: 0.3s, 0.5s, 0.2s;
/* background: 0.3s -->
/* transform: 0.5s -->
/* opacity: 0.2s -->
}
.element:hover {
background: red;
transform: scale(1.2);
opacity: 0.5;
}
<!-- Each property animates at different speed -->
/* Different delays too -->
.element {
transition-property: background, transform, opacity;
transition-duration: 0.3s;
transition-delay: 0s, 0.1s, 0.2s;
/* background: starts at 0s -->
/* transform: starts at 0.1s -->
/* opacity: starts at 0.2s -->
}
<!-- Staggered animation sequence -->
/* Practical: sequential effects -->
.menu-item {
background: white;
color: gray;
transform: translateX(0);
transition-property: background, color, transform;
transition-duration: 0.2s, 0.2s, 0.3s;
transition-delay: 0s, 0s, 0.1s;
}
.menu-item:hover {
background: blue; /* quick change -->
color: white; /* quick change -->
transform: translateX(10px); /* slower, delayed slide -->
}Common transition patterns
CSS
<!-- Button hover: color + transform -->
.button {
background: blue;
color: white;
transform: scale(1);
transition-property: background, color, transform;
transition-duration: 0.2s;
}
.button:hover {
background: darkblue;
color: yellow;
transform: scale(1.05);
}
<!-- Multiple coordinated changes -->
/* Icon + text color change -->
.link {
color: blue;
transition-property: color;
transition-duration: 0.3s;
}
.link:hover {
color: darkblue;
}
.link::after {
content: '→';
opacity: 0;
transition-property: opacity;
transition-duration: 0.3s;
}
.link:hover::after {
opacity: 1;
}
<!-- Text color and icon appear together -->
/* Card elevation on hover -->
.card {
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
transform: translateY(0);
transition-property: box-shadow, transform;
transition-duration: 0.3s;
}
.card:hover {
box-shadow: 0 12px 24px rgba(0,0,0,0.15);
transform: translateY(-4px);
}
<!-- Shadow and lift together -->
/* Fade in/out -->
.element {
opacity: 0;
visibility: hidden;
transition-property: opacity, visibility;
transition-duration: 0.3s;
}
.element.visible {
opacity: 1;
visibility: visible;
}
<!-- Both opacity and visibility change -->Avoiding unnecessary transitions
CSS
<!-- Disable transitions where not needed -->
.element {
background: blue;
transition-property: all;
transition-duration: 0.3s;
}
/* This causes transitions on load and other unexpected changes */
/* Better: specify only what you want -->
.element {
background: blue;
transition-property: background, color; /* explicit -->
transition-duration: 0.3s;
}
<!-- Only specified properties animate -->
/* Disable on load: add class after render -->
.element {
transition-property: none; /* no transition on load -->
}
.element.interactive {
transition-property: background, color;
transition-duration: 0.3s;
}
<!-- Transitions only enabled when needed -->
/* Use JavaScript to add transition class -->
const element = document.querySelector('.element');
// After initial setup
element.classList.add('interactive');
// Now transitions are active
/* Avoid global "all" transitions on large properties -->
.container * {
transition-property: all; /* Don't do this! -->
}
/* Better: specific elements -->
button {
transition-property: background, color;
}
link {
transition-property: color;
}
<!-- More predictable and performant -->Note
`transition-property` specifies which CSS properties animate. Use specific properties (background, color, transform) rather than "all" for better performance. Animate GPU-accelerated properties (transform, opacity) instead of layout properties (width, height). Combine with different `transition-duration` and `transition-delay` values for coordinated effects.
Next
Transition timing and delay: [transition-duration & delay](/css/transition-duration).