The CSS translate() function shifts an element from its default position on a two-dimensional plane. This way, we can reposition an element horizontally, vertically, or both.
.parent:hover .box {
transform: translate(50px, 50%);
}
Along with other transform functions, it is used inside the transform property. The translate() function is defined in the CSS Transforms Module Level 1 draft.
Syntax
The translate() function’s syntax looks like this:
<translate()> = translate( <length-percentage>, <length-percentage>? )
This means we can move (translate) an element by one or two lengths or percentages.
Arguments
/* Single argument */
translate(100px) /* moves 100px to the right */
translate(-100%) /* moves 100% of the element's width to the left */
/* Double argument */
translate(50px, 100px) /* moves 50px to the right, then 100px downward */
translate(50%, 100%) /* moves 50% of the element's width to the right, then 100% of its height downward */
The translate() function takes two <length-percentage> arguments (tx, ty, as in “translate horizontally” and “translate vertically”). These tell the browser how much to move the element and in which direction (whether it’s positive or negative).
tx: Specifies the displacement on the horizontal axis. If it’s positive, the element goes right. If it’s negative, the element shifts to the left.ty(optional): Specifies the displacement on the vertical axis. If it’s positive, the element goes downward; if it’s negative, the element moves upward.
If only one argument is passed, it’s assumed to be tx. When both arguments are passed, the second argument is ty. Together, they shift the element diagonally.
You can use either <length> or <percentage> values. A <length> value is absolute, while a <percentage> value is relative to the element’s width (for tx) or height (for ty).
Basic usage
While there are many ways to center an element in CSS, for most of its history, the translate() function was the best approach for centering an absolutely positioned element.
The process works as follows: given an absolute element, shift it to the center using top: 50% and left: 50%. However, these alone only fix the top-left corner of the element in the center, not the element itself. To fix this, use transform: translate(-50%, -50%) to shift the element back by half of its own width and height.
.modal-center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(0.9);
}
More recently, this can be done using the justify-self and align-self properties. Alternatively, the semantic <dialog> element is centered by default.
Diagonal movements
The translateX() function moves elements horizontally, while translateY() handles the vertical axis. For diagonal movement, you can combine both or use the shorter translate() function.
A common use case is animating an element into the page from any corner. For example, with a Toast component that slides in from the bottom-right, you can position it with bottom and right properties and then offset it off the page with translate().
.toast {
position: fixed;
bottom: 30px;
right: 30px;
transform: translate(40px, 40px);
transition: transform 0.28s ease;
}
Then, when a .show class is triggered, the translate() values are reset, causing the element to slide in diagonally:
.toast.show {
opacity: 1;
transform: translate(0, 0);
}
It doesn’t affect other elements
The translate() function, like other transform functions, does not affect the document flow. It visually displaces the translated element to a new position without pushing surrounding elements or elements at the new position. The space the element originally occupied remains reserved in the layout as if it hadn’t moved at all.
/* Translated element */
.translated {
position: absolute;
top: 0;
left: 0;
transform: translate(80px, 40px);
}
Unlike margin, which can trigger reflows or shift neighboring elements, translate() only changes where the element is visually rendered.
Issues with pointer pseudo-classes
Using translate() directly on a pointer pseudo-class like :hover can sometimes cause bad interactions. If the element is translated far enough from the cursor, the :hover state ends, causing the element to snap back immediately to its original position — where the cursor still lingers, triggering the translation again and resulting in a continuous flickering loop.
A simple solution is to place the element to be translated inside a parent container, apply the pseudo-class (:hover) to the parent, and let the child element receive the translate function.
/* Problem case */
.bad:hover {
transform: translateX(160px);
}
/* Solution */
.parent:hover .good {
transform: translateX(160px);
}
Specification
The CSS translate() function is defined in the CSS Transforms Module Level 1, which is currently in Editor’s Draft status.
Browser support
The translate() function has baseline support across all modern browsers.