AD JB Toolbox 01 EN

CSS Tutorial / CSS Transforms and Transitions

Transforms move, rotate, or scale a box's rendered appearance without reflowing surrounding content. Transitions animate a change between property values, so select the properties and timing deliberately and provide a reduced-motion alternative.

Understand transforms and normal flow

Document flow refers to the relationship between where an element is originally placed and surrounding elements. Even if you move the button up to translateY(-.5rem), the paragraph below does not move up according to the space where the button was moved. Transformed elements may overlap surrounding content or go off-screen, so leaving enough room in their original placement is a priority rather than increasing the movement distance.

function yes Results to Observe
translate() translate(1rem, -.5rem) Move 1rem to the right, .5rem up
rotate() rotate(15deg) Rotate around a reference point
scale() scale(1.05) Displayed at 1.05 times the original size

Just because the size appears larger does not mean that the space occupied by the box before conversion will be larger. Review the Grid or Width properties to change the actual column width of the card, or Transform to create a slightly larger visual effect when pressed. Inline boxes that are not replaced, such as plain text span , are not converted, so specify display: inline-block if necessary. Definitions of transformation targets and coordinate processing can be found in the MDN transform document.

Compare transform order and origin

When you list transformation functions, each function affects the coordinate system used by the next function. Therefore, translation/rotation and rotation/translation are generally not the same result. In the example below, A's rotated box is visible where it has been moved to the right, and B's box has moved in the direction affected by the rotation and is visible further down. Don't just look at the function name and assume that the two results are the same; compare their actual locations.

The center of rotation and expansion is set to transform-origin. If you use left top instead of the default center, it will rotate about the upper left corner. This is useful when you want to fix a specific point, such as when a menu opens, but the overlap with surrounding content can change just by changing the reference point.

Save the following code as transform-compare.html in UTF-8 and open it in your browser. No external files or libraries are required.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Transform order and origin</title>
  <style>
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; padding: 1rem; color: #183044; font-family: sans-serif; line-height: 1.6; }
main { max-width: 46rem; margin-inline: auto; }
h1 { font-size: 1.5rem; } h2 { font-size: 1.2rem; }
button, input { font: inherit; }
button { cursor: pointer; }
:focus-visible { outline: 3px solid #164f73; outline-offset: 3px; }
.comparisons { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr)); gap: 1rem; }
.slot { padding: 1rem; border: 1px solid #8a9ba7; }
.frame { height: 9rem; display: grid; place-items: center; background: #f0f2f4; }
.box { width: 4rem; height: 2rem; display: grid; place-items: center; background: #166b92; color: white; }
.first { transform: translateX(2rem) rotate(45deg); }
.second { transform: rotate(45deg) translateX(2rem); }
.center { transform: rotate(30deg); transform-origin: center; }
.corner { transform: rotate(30deg); transform-origin: left top; }
  </style>
</head>
<body>
<main>
<h1>The same value also varies depending on the order and reference point</h1>
<div class="comparisons">
  <section class="slot"><h2>Translate, then rotate</h2><div class="frame"><div class="box first">A</div></div></section>
  <section class="slot"><h2>Rotate, then translate</h2><div class="frame"><div class="box second">B</div></div></section>
  <section class="slot"><h2>Center origin</h2><div class="frame"><div class="box center">C</div></div></section>
  <section class="slot"><h2>Top-left origin</h2><div class="frame"><div class="box corner">D</div></div></section>
</div>
</main>
</body>
</html>
  1. Compare the positions of A and B. If you change the function order of .second to be the same as A, the relative positions of the two boxes will be the same. After confirmation, return it to the original order.
  2. C and D have the same rotation angle. Change only transform-origin from .corner to center, check the difference in reference points, and restore to left top.
  3. Compare the magnification by changing only the rotation of C to scale(1.2). The area outside the box will grow, but the surrounding area will not be relocated. After confirmation, restore it to rotate(30deg).

Choose transition properties and timing

transition does not change state by itself. The change starts only when the CSS value changes on hover, focus, or class change. Specifies the property name to effect, duration, progression curve, and startup delay; if delay is omitted, it defaults to 0 seconds.

transition: transform 180ms ease 0ms, background-color 180ms ease 0ms;

Here, 180ms is 0.18 seconds, and ease is a curve that smoothly connects the beginning and end rather than proceeding only at the same speed. linear changes at a constant rate. Use short times and no delays first, then adjust as needed. Adding a long delay to a seemingly unresponsive button can make it difficult to notice the results of your actions.

Putting transition on the base rule allows it to operate on both entry and return. A transition declared only on :hover disappears when hover ends and can produce a different return. Name the properties deliberately instead of using all. This example transitions transform and background-color; not every property interpolates in the same way. For further detail, see MDN transition document.

Test hover and keyboard focus

Save the code below as transition-state.html. When you hover over the button or use the Tab key, the button moves up and its background color changes. Focus points are individually outlined in dark blue. The button is for practice purposes only to observe changes in state, and no additional action is performed after pressing the button.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Transforms and state transitions exercise</title>
  <style>
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; padding: 1rem; color: #183044; font-family: sans-serif; line-height: 1.6; }
main { max-width: 46rem; margin-inline: auto; }
h1 { font-size: 1.5rem; } h2 { font-size: 1.2rem; }
button, input { font: inherit; }
button { cursor: pointer; }
:focus-visible { outline: 3px solid #164f73; outline-offset: 3px; }
.stage { padding: 2rem 1rem; border: 2px dashed #8a9ba7; }
.action { padding: .75rem 1.25rem; border: 1px solid #166b92; border-radius: .4rem;
  color: #183044; background: #eaf4fa; transform: translateY(0);
  transition: transform 180ms ease, background-color 180ms ease; }
.action:hover, .action:focus-visible { transform: translateY(-.5rem); background: #cfe8f4; }
.neighbor { margin-block: 1rem 0; padding: .75rem; background: #f0f2f4; }
@media (prefers-reduced-motion: reduce) {
  .action { transition: none; }
  .action:hover, .action:focus-visible { transform: none; }
}
  </style>
</head>
<body>
<main>
<h1>The paragraph stays in place as the button moves</h1>
<p>Hover over the button or press Tab to focus it.</p>
<div class="stage">
  <button class="action" type="button">Check state</button>
  <p class="neighbor">This paragraph stays in place when the button is transformed.</p>
</div>
</main>
</body>
</html>
  1. Remember the top position of the paragraph below and hover over the button. Only the buttons move and the paragraphs must remain in the same place.
  2. Change the duration in two places from 180ms to 800ms to observe entry and return, then return to the original value.
  3. Leave the time as is and change only the progress curve to linear for comparison. Then restore it to ease.
  4. We only add a 400ms delay to the end of the first transition. The background color and movement start point change. Eliminates delays after confirmation.
  5. Focus on the button with the Tab key and exit with Shift+Tab. Make sure the focus outline and background color describe the operating state.

Reduce motion and check side effects

If the user has set it to reduce movement, the prefers-reduced-motion: reduce condition will eliminate the movement, leaving behind background color and focus marks. If you just remove the transition, the change will occur immediately, but the final position you moved to will remain. In the example above, we decided that decorative movement itself was unnecessary, so even the hover and focus transforms were changed to none. Please refer to MDN motion reduction setting guide.

Compare the two states by changing your operating system settings or reproducing the media characteristics in the Rendering panel of your browser developer tools. In the reduced setting, the button should not move, only the color and focus indicator should change. When you're done with the lab, restore the emulation to its default state.

A non-none transform creates a stacking context and can establish the containing block for absolute and fixed descendants. If a popup or fixed element behaves unexpectedly, inspect transformed ancestors. Also check overlap, keyboard focus, and reduced motion; a smooth transition alone does not establish usable layout. See CSS position: relative, absolute, fixed, and sticky, CSS z-index and Stacking Contexts.

More in This Category
CSS Tutorial / Inspect CSS with DevTools: Styles and Computed

CSS Tutorial / Inspect CSS with DevTools: Styles and Computed

Use Styles, Computed, and the box model display to diagnose CSS, compare temporary edits, and transfer a confirmed change to the correct source file.

CSS Tutorial / CSS position: relative, absolute, fixed, and sticky

CSS Tutorial / CSS position: relative, absolute, fixed, and sticky

Compare positioning modes in a complete example, identify containing blocks, and troubleshoot sticky limits and overlapping content.

CSS Tutorial / CSS Tables: Borders, Sizing, and table-layout

CSS Tutorial / CSS Tables: Borders, Sizing, and table-layout

Style semantic tables, compare automatic and fixed layout with long content, and provide horizontal scrolling when a table needs more space.

CSS Tutorial / What CSS Does and How It Differs from HTML

CSS Tutorial / What CSS Does and How It Differs from HTML

Learn the roles of HTML and CSS through a complete page example, and see how styling changes presentation without replacing meaningful HTML.

CSS Tutorial / Responsive Images and Video: aspect-ratio and object-fit

CSS Tutorial / Responsive Images and Video: aspect-ratio and object-fit

Compare original image proportions, cover, contain, and object-position, then test responsive video sizing with a downloadable sample.

CSS Tutorial / CSS display: Block, Inline, inline-block, and Hiding

CSS Tutorial / CSS display: Block, Inline, inline-block, and Hiding

Compare block and inline sizing, replaced elements such as images, and the layout and interaction differences between common hiding techniques.

CSS Tutorial / CSS Transforms and Transitions

CSS Tutorial / CSS Transforms and Transitions

Compare transform order and origins, add hover and keyboard transitions, and test overflow and reduced-motion behavior.

CSS Tutorial / Flexbox Alignment, Wrapping, gap, grow, and shrink

CSS Tutorial / Flexbox Alignment, Wrapping, gap, grow, and shrink

Compare Flexbox alignment and wrapping, distribute space with flex values, and prevent long content from blocking item shrinkage.

CSS Tutorial / CSS Fonts, Font Sizes, and Line Height

CSS Tutorial / CSS Fonts, Font Sizes, and Line Height

Build a readable font stack, compare line-height inheritance, and use browser tools to identify the fonts actually rendering your text.

CSS Tutorial / CSS Combinators and Pseudo-Classes

CSS Tutorial / CSS Combinators and Pseudo-Classes

Compare descendant, child, and sibling selectors, then test hover, focus, and child-position conditions in a complete example.