CSS Transitions: Duration, Timing Functions, and Cubic Beziers
Master CSS transitions. Learn how to animate style changes smoothly using transition properties, delay settings, and timing curves.
Introduction
Static websites can feel cold and mechanical. When a user hovers over a button, select tab, or image link, and the color swaps instantly, it creates a jarring visual transition.
To improve user experience, modern websites use motion. In CSS, the simplest way to add motion is using CSS Transitions. Transitions allow you to change property values smoothly (from an old style to a new style) over a specified duration, rather than instantly. Configuring transitions with custom timing curves and delays is a key technique to create premium-feeling, interactive interfaces.
What You Will Learn
- How to initialize a transition using
transition-property. - Controlling transition speed using
transition-duration. - Using timing functions (
ease,linear,ease-in-out) to model velocity. - Designing custom acceleration curves using
cubic-bezier(). - Combining settings using the
transitionshorthand.
Prerequisites
Detailed Explanation: Transition Properties
A CSS transition requires two states: a start state and a target state (often triggered by hover states like :hover or focus states like :focus). You then declare how the browser should animate the shift between these states.
The Four Transition Properties
transition-property: Specifies the name of the CSS property you want to animate (e.g.background-color,transform,opacity). Avoid animatingallproperties for better performance.transition-duration: Specifies how long the transition takes to complete. Declared in seconds (s) or milliseconds (ms) (e.g.,0.3s,300ms).transition-delay: Specifies a waiting period before the transition starts (e.g.0.1s).transition-timing-function: Defines the speed curve of the transition, controlling how the velocity changes over time.
Understanding Timing Functions
The transition timing function determines whether the animation moves at a constant speed, starts slow, or accelerates near the end.
linear: Constant speed from start to end.ease: (Default) Starts slow, accelerates in the middle, then slows down at the end.ease-in: Starts slow, then accelerates until the end.ease-out: Starts fast, then decelerates to a slow stop at the end.ease-in-out: Starts slow, speeds up in the middle, then decelerates at the end.cubic-bezier(x1, y1, x2, y2): Defines a custom timing curve. By adjusting the coordinate control points, you can create bounce effects or custom physics-based accelerations.
.custom-ease-card {
/* custom cubic bezier curve */
transition-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1);
}
The Transition Shorthand
Combine all four properties into a single, clean declaration:
$$\text{transition: property | duration | timing-function | delay};$$
.button {
background-color: #3b82f6;
/* Shorthand declaration */
transition: background-color 0.3s ease-in-out 0.1s;
}
.button:hover {
background-color: #1d4ed8;
}
> [!NOTE] > When using shorthand, if you want to write a transition delay, you MUST write the duration first. The first time value is always parsed as the duration, and the second time value is parsed as the delay.
Visual Learning Diagram (Mermaid)
graph TD
subgraph Velocity Curves Compared
Linear[linear: Constant speed]
EaseIn[ease-in: Accelerates at end]
EaseOut[ease-out: Decelerates at end]
Cubic[cubic-bezier: Custom acceleration/deceleration]
end
Code Examples
Example 1: Premium Hover Active Button
Create a button with smooth background color and shadow transitions:
.btn-interactive {
background-color: #3b82f6;
color: white;
border: none;
padding: 12px 24px;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
cursor: pointer;
/* Animate background and shadow independently using comma separators */
transition: background-color 0.2s ease,
box-shadow 0.2s ease,
transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1); /* Bouncy scaling */
}
.btn-interactive:hover {
background-color: #2563eb;
box-shadow: 0 10px 15px rgba(37, 99, 235, 0.3);
transform: translateY(-2px); /* Lift button */
}
.btn-interactive:active {
transform: translateY(1px); /* Press button down */
}
Example 2: Interactive Accordion Content Reveal
Reveal hidden accordion panels using smooth height and opacity transitions:
.accordion-content {
max-height: 0;
opacity: 0;
overflow: hidden;
/* Smoothly reveal panel height and content opacity */
transition: max-height 0.4s cubic-bezier(0.4, 0, 0.2, 1),
opacity 0.3s ease-in;
}
.accordion-item.active .accordion-content {
max-height: 500px; /* Target height limit */
opacity: 1;
}
Best Practices & Performance Optimization
- Do Not Animate Everything (
transition: all): Declaringtransition: all 0.3s;forces the browser to check and recalculate every single layout property (like width, margins, borders, and position coordinates) during the animation. This can cause lag and frame drops on low-end mobile devices. Only animate properties that do not trigger layout recalculations, such asopacityandtransform. - Animate Transform instead of Offsets: Avoid animating position coordinates (like
left: 0pxtoleft: 10px). This forces layout repaints (reflows) on every frame. Instead, usetransform: translateX(10px)which is processed by the GPU, keeping animations smooth.
FAQs
Q: Can all CSS properties be transitioned?
A: No. Only properties that have intermediate numeric values (like colors, lengths, margins, opacities, and angles) can be transitioned. Properties with absolute states (like display: none to display: block or font-family) cannot be transitioned smoothly.
Q: How do I transition an element to height: auto?
A: CSS cannot calculate transitions to auto heights because it needs explicit numeric values. To animate collapsibles, transition max-height from 0 to a fixed value larger than the content (e.g. 500px), or use modern grid layouts: grid-template-rows: 0fr transitioning to 1fr.
Summary
CSS transitions animate property changes smoothly. Configured using transition-property, transition-duration, transition-delay, and velocity timing functions (such as ease-in-out or custom cubic-bezier curves), these transitions are declared concisely using the transition shorthand.
Related Articles
Next Tutorial
How do we move, rotate, scale, and skew elements on the screen? Let's check: CSS 2D & 3D Transforms.