CSS Transitions Properties, Timing, is an important CSS topic because it shows up in real projects, debugging sessions, and interviews. Learn the meaning first, then connect it to a small working example so the rule does not stay abstract.
Focus on what problem CSS Transitions Properties, Timing, solves, where developers usually make mistakes, and how to verify the result with output, behavior, or a small test.
A strong understanding of CSS Transitions Properties, Timing, should include syntax, behavior, one realistic use case, one failure case, and one quick way to check your work.
CSS Transitions Properties Duration Timing and Delay should be studied as a practical CSS lesson, not as a label. Start by naming the input, the rule that changes the input, and the result a learner should be able to predict after reading the page.
In the css > transitions page, the notes should connect the definition with a working scenario, a mistake that beginners actually make, and the exact check that proves the fix. That makes the topic useful for coding, debugging, and interview revision.
CSS transitions let you animate a style change from one state to another. They are commonly used for hover effects, focus states, buttons, cards, menus, form feedback, theme changes, and small interface interactions. Without a transition, a style change happens instantly. With a transition, the browser smoothly moves between the old value and the new value over time.
Transitions are best when an element has two clear states, such as normal and hover, closed and open, hidden and visible, or inactive and active. If you need a multi-step sequence that runs automatically, use CSS animations with @keyframes instead.
A transition needs at least a property and a duration. The shorthand syntax is the most common way to write it.
When the button enters the :hover state, background-color changes from blue to darker blue over 200ms. When hover ends, it transitions back.
.button {
background-color: #2563eb;
color: white;
padding: 10px 16px;
border: none;
border-radius: 6px;
transition: background-color 200ms ease;
}
.button:hover {
background-color: #1d4ed8;
}
| Property | Purpose | Example |
|---|---|---|
| transition-property | Which CSS property should animate. | opacity, transform, background-color |
| transition-duration | How long the transition takes. | 150ms, 0.3s |
| transition-timing-function | How the speed changes during the transition. | ease, linear, ease-out |
| transition-delay | How long to wait before starting. | 0ms, 100ms |
| transition | Shorthand for all transition settings. | opacity 200ms ease |
The longhand properties are useful for learning and debugging. The shorthand is cleaner for production CSS.
/* Longhand */
.box {
transition-property: opacity;
transition-duration: 250ms;
transition-timing-function: ease;
transition-delay: 0ms;
}
/* Equivalent shorthand */
.box {
transition: opacity 250ms ease 0ms;
}
You can transition multiple properties by separating each transition with a comma. This lets each property have its own duration, timing function, and delay.
.card {
opacity: 0.85;
transform: translateY(0);
box-shadow: 0 4px 12px rgba(15, 23, 42, 0.08);
transition:
opacity 180ms ease,
transform 220ms ease,
box-shadow 220ms ease;
}
.card:hover {
opacity: 1;
transform: translateY(-4px);
box-shadow: 0 14px 30px rgba(15, 23, 42, 0.16);
}
transition: all looks convenient, but it can animate properties you did not intend to animate. This can cause confusing bugs and performance problems. It is usually better to list the exact properties you want to transition.
/* Avoid in most production UI */
.panel {
transition: all 300ms ease;
}
/* Better */
.panel {
transition:
opacity 200ms ease,
transform 200ms ease;
}
The timing function controls the speed curve. Two transitions can have the same duration but feel very different because of their timing function.
| Timing function | Behavior | Best use |
|---|---|---|
| ease | Starts slow, speeds up, ends slow. | General UI transitions. |
| linear | Same speed from start to end. | Progress bars, continuous movement. |
| ease-in | Starts slow, ends faster. | Elements leaving the screen. |
| ease-out | Starts faster, ends slow. | Elements entering the screen. |
| ease-in-out | Smooth start and smooth end. | State changes and toggles. |
| cubic-bezier() | Custom speed curve. | Brand-specific or polished motion. |
.drawer {
transform: translateX(-100%);
transition: transform 280ms cubic-bezier(0.22, 1, 0.36, 1);
}
.drawer.is-open {
transform: translateX(0);
}
A delay waits before the transition starts. Delays can be useful for staged UI effects, but use them carefully. Too many delays make an interface feel slow.
.tooltip {
opacity: 0;
transform: translateY(4px);
transition:
opacity 150ms ease 300ms,
transform 150ms ease 300ms;
}
.button:hover .tooltip,
.button:focus-visible .tooltip {
opacity: 1;
transform: translateY(0);
}
For smooth UI motion, prefer properties that do not force the browser to recalculate layout on every frame. opacity and transform are usually the safest choices.
| Better choices | Use carefully |
|---|---|
| opacity | width, height |
| transform | top, left, right, bottom |
| background-color | large box-shadow changes |
| color | layout-heavy spacing changes |
Interactive controls should work for keyboard users too. Pair :hover with :focus-visible so the transition is not mouse-only.
.primary-button {
background: #2563eb;
color: #fff;
border: 0;
border-radius: 6px;
padding: 10px 16px;
transform: translateY(0);
transition:
background-color 160ms ease,
transform 160ms ease,
box-shadow 160ms ease;
}
.primary-button:hover,
.primary-button:focus-visible {
background: #1d4ed8;
transform: translateY(-2px);
box-shadow: 0 8px 18px rgba(37, 99, 235, 0.28);
}
.primary-button:active {
transform: translateY(0);
}
Cards often use subtle transitions to show that they are clickable. Keep the movement small so the layout does not feel jumpy.
.course-card {
border: 1px solid #e5e7eb;
border-radius: 8px;
padding: 18px;
background: #fff;
transform: translateY(0);
transition:
border-color 180ms ease,
box-shadow 180ms ease,
transform 180ms ease;
}
.course-card:hover {
border-color: #93c5fd;
box-shadow: 0 14px 34px rgba(15, 23, 42, 0.12);
transform: translateY(-3px);
}
A panel that appears and disappears can use opacity, transform, and visibility. This avoids animating display, which cannot transition between none and block.
.panel {
opacity: 0;
visibility: hidden;
transform: translateY(8px);
transition:
opacity 180ms ease,
transform 180ms ease,
visibility 0s linear 180ms;
}
.panel.is-open {
opacity: 1;
visibility: visible;
transform: translateY(0);
transition:
opacity 180ms ease,
transform 180ms ease,
visibility 0s;
}
Animating from height: 0 to height: auto does not work directly because auto is not an interpolable numeric value. A common CSS-only approach is to transition max-height with a known safe maximum.
For dynamic content with unknown height, JavaScript can measure the real height and set an exact pixel value. Pure CSS is simpler, but it needs a maximum height that fits the content.
.accordion-content {
max-height: 0;
overflow: hidden;
opacity: 0;
transition:
max-height 260ms ease,
opacity 180ms ease;
}
.accordion.is-open .accordion-content {
max-height: 320px;
opacity: 1;
}
Transitions can make theme changes feel smoother. Keep them restrained so large page-wide transitions do not feel distracting.
:root {
--page-bg: #ffffff;
--text-color: #111827;
}
.dark-theme {
--page-bg: #111827;
--text-color: #f9fafb;
}
body {
background: var(--page-bg);
color: var(--text-color);
transition:
background-color 220ms ease,
color 220ms ease;
}
JavaScript often toggles a class, while CSS handles the visual transition. This keeps behavior and styling cleanly separated.
<button class="menu-button">Menu</button>
<nav class="menu">
<a href="#">Home</a>
<a href="#">Courses</a>
<a href="#">Contact</a>
</nav>
.menu {
opacity: 0;
transform: translateY(-8px);
pointer-events: none;
transition: opacity 180ms ease, transform 180ms ease;
}
.menu.is-open {
opacity: 1;
transform: translateY(0);
pointer-events: auto;
}
const button = document.querySelector('.menu-button');
const menu = document.querySelector('.menu');
button.addEventListener('click', () => {
menu.classList.toggle('is-open');
});
JavaScript can listen for the transitionend event when you need to run code after a transition finishes. This is useful for cleanup tasks after a panel closes or a toast disappears.
A transition can fire one transitionend event for each transitioned property, so check event.propertyName when needed.
const toast = document.querySelector('.toast');
toast.addEventListener('transitionend', event => {
if (event.propertyName === 'opacity' && toast.classList.contains('is-hidden')) {
toast.remove();
}
});
Some users prefer less motion. Respect this with the prefers-reduced-motion media query. You can shorten or remove transitions while keeping the interface usable.
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
transition-duration: 1ms !important;
transition-delay: 0ms !important;
scroll-behavior: auto !important;
}
}
| Feature | Transitions | Animations |
|---|---|---|
| Trigger | Needs a state change such as hover, focus, or class toggle. | Can run automatically. |
| Steps | Moves between two style states. | Can define many keyframe steps. |
| Best for | Buttons, menus, cards, simple UI feedback. | Loaders, repeated motion, staged sequences. |
| CSS tool | transition | @keyframes and animation |
CSS transitions are ideal for smooth changes between two UI states. Use them for hover, focus, active, open, closed, visible, and hidden states. Choose specific properties, keep durations short, prefer opacity and transform, and respect reduced-motion preferences. For multi-step motion that runs independently, use CSS animations instead.
.lesson-box {
display: block;
max-width: 42rem;
padding: 1rem;
}
.lesson-box:empty::before {
content: "CSS Transitions Properties Duration Timing and Delay: add visible content";
}
Memorizing CSS Transitions Properties Duration Timing and Delay without the situation where it is useful.
Connect CSS Transitions Properties Duration Timing and Delay to a concrete CSS task.
Testing CSS Transitions Properties Duration Timing and Delay only with the perfect input.
Include empty, missing, duplicate, incompatible, or failed cases when relevant.
Changing code before reading the visible symptom or error message.
Inspect the output, state, configuration, or stack trace connected to CSS Transitions Properties Duration Timing and Delay.
Memorizing CSS Transitions Properties Duration Timing and Delay without the situation where it is useful.
Connect CSS Transitions Properties Duration Timing and Delay to a concrete CSS task.
A CSS transition smoothly animates a property from one value to another when an element changes state, such as hover, focus, active, or a class toggle.
No. <code>display</code> cannot smoothly transition between <code>none</code> and <code>block</code>. Use <code>opacity</code>, <code>visibility</code>, <code>transform</code>, or measured height techniques instead.
Most UI transitions feel good between <code>150ms</code> and <code>300ms</code>. Very small feedback can be faster, while larger panels may need slightly longer.
A transition responds to a style change between two states. An animation uses <code>@keyframes</code> and can run automatically through many steps.
Explore 500+ free tutorials across 20+ languages and frameworks.