CSS atan2() Function
The CSS atan2() function calculates an angle from two numeric values representing vertical and horizontal coordinates. Unlike atan(), it uses the signs of both values to determine the correct quadrant, making it useful for rotations, directional calculations, and geometric CSS layouts.
Syntax
atan2(y, x)
The atan2() function accepts two comma-separated mathematical expressions and returns an angle.
The first argument represents the vertical component (y), and the second represents the horizontal component (x).
For example:
transform: rotate(atan2(1, 1));
The expression atan2(1, 1) returns 45deg, so the element rotates 45 degrees.
Changing the horizontal component changes the calculated angle:
transform: rotate(atan2(1, -1));
This returns 135deg, placing the angle in the second quadrant.
The function can also accept mathematical expressions:
transform: rotate(atan2(3 * 2, 4 * 2));
The expressions evaluate to 6 and 8, producing an angle of approximately 36.87deg.
Parameters
The atan2() function requires exactly two arguments.
| Parameter | Description |
|---|---|
y |
The vertical coordinate or component. It may be a number, dimension, or percentage. |
x |
The horizontal coordinate or component. It may be a number, dimension, or percentage. |
Both arguments must have compatible CSS numeric types. Two numbers, two lengths, or two percentages are valid examples.
Valid expressions include:
atan2(1, 1)
atan2(1, -1)
atan2(-1, -1)
atan2(-1, 1)
atan2(3, 4)
atan2(50px, 100px)
atan2(25%, 50%)
atan2(1rem, 20px)
atan2(var(--y), var(--x))
Different length units can be combined because both arguments resolve to compatible dimensions.
However, a number and a length cannot be mixed directly:
atan2(50px, 2)
This is invalid because the arguments have incompatible types.
The order of the arguments matters. The vertical component always comes first.
How It Works
The atan2() function calculates the angle between the positive horizontal axis and the direction represented by the point (x, y).
For example:
atan2(3, 4) /* Approximately 36.87deg */
The point has a horizontal component of 4 and a vertical component of 3.
Because both components are positive, the result is an angle in the first quadrant.
Changing the signs moves the point into another quadrant:
atan2(3, -4) /* Approximately 143.13deg */
atan2(-3, -4) /* Approximately -143.13deg */
atan2(-3, 4) /* Approximately -36.87deg */
The function considers both arguments independently, so it can distinguish directions that have the same tangent ratio.
For example:
atan2(1, 1) /* 45deg */
atan2(-1, -1) /* -135deg */
Both coordinate pairs have a tangent ratio of 1, but they point in opposite directions.
The atan2() function preserves that directional information.
Return Values
The atan2() function returns an angle normalized to the range greater than -180deg and less than or equal to 180deg for ordinary finite, nonzero coordinate pairs.
| Expression | Result |
|---|---|
atan2(1, 1) |
45deg |
atan2(1, -1) |
135deg |
atan2(-1, -1) |
-135deg |
atan2(-1, 1) |
-45deg |
atan2(1, 0) |
90deg |
atan2(-1, 0) |
-90deg |
atan2(0, 1) |
0deg |
atan2(0, -1) |
180deg |
atan2(3, 4) |
Approximately 36.87deg |
atan2(4, 3) |
Approximately 53.13deg |
The result is an angle and can be represented in degrees, radians, turns, or gradians.
For example, atan2(1, 1) is equivalent to 45deg, 0.125turn, or approximately 0.7854rad.
CSS mathematical calculations also distinguish positive and negative zero. Certain special inputs involving signed zero or infinity can produce boundary results such as -180deg.
Coordinate Quadrants
The signs of the two arguments determine the quadrant of the calculated angle.
| Quadrant | Y Value | X Value | Example |
|---|---|---|---|
| First | Positive | Positive | atan2(1, 1) = 45deg |
| Second | Positive | Negative | atan2(1, -1) = 135deg |
| Third | Negative | Negative | atan2(-1, -1) = -135deg |
| Fourth | Negative | Positive | atan2(-1, 1) = -45deg |
In standard mathematical coordinates, positive angles are measured counterclockwise from the positive horizontal axis.
When the result is used with CSS rotate(), positive angles rotate clockwise in the usual left-to-right coordinate system.
For example:
.first {
transform: rotate(atan2(1, 1));
}
.second {
transform: rotate(atan2(1, -1));
}
.third {
transform: rotate(atan2(-1, -1));
}
.fourth {
transform: rotate(atan2(-1, 1));
}
The four elements rotate by 45deg, 135deg, -135deg, and -45deg, respectively.
Using Dimensions and Percentages
Unlike atan(), which requires a unitless number, atan2() can accept two compatible dimensions or percentages.
For example:
.example {
transform: rotate(atan2(75px, 100px));
}
The function calculates an angle of approximately 36.87deg.
Different compatible length units can also be used:
.example {
transform: rotate(atan2(1rem, 20px));
}
The browser converts the length values to compatible units before calculating the angle.
Percentage arguments are also supported:
.example {
transform: rotate(atan2(50%, 100%));
}
This produces an angle of approximately 26.57deg.
Both arguments must have compatible types. Mixing a percentage with a length directly is not valid:
transform: rotate(atan2(50%, 100px));
The function can also use expressions containing compatible units:
.example {
transform: rotate(atan2(25px + 25px, 100px));
}
The first argument evaluates to 50px, producing an angle of approximately 26.57deg.
Using Custom Properties
CSS custom properties can provide the coordinate values used by atan2().
For example:
:root {
--y: 3;
--x: 4;
}
.example {
transform: rotate(atan2(var(--y), var(--x)));
}
The result is approximately 36.87deg.
Changing either custom property changes the calculated angle:
:root {
--y: 3;
--x: -4;
}
The resulting angle becomes approximately 143.13deg.
Custom properties can also contain lengths:
:root {
--vertical-distance: 75px;
--horizontal-distance: 100px;
}
.example {
transform: rotate(atan2(var(--vertical-distance), var(--horizontal-distance)));
}
This produces an angle of approximately 36.87deg.
Both custom property values must resolve to compatible numeric types.
This technique is useful for components whose direction depends on changing measurements or values.
Example
The following example demonstrates how atan2() calculates rotation angles for four different coordinate pairs.
Each blue line uses the signs of its vertical and horizontal components to determine its direction.
HTML:
<div class="atan2-demo">
<div class="atan2-row">
<span>atan2(1, 1) = 45deg</span>
<div class="atan2-line atan2-one"></div>
</div>
<div class="atan2-row">
<span>atan2(1, -1) = 135deg</span>
<div class="atan2-line atan2-two"></div>
</div>
<div class="atan2-row">
<span>atan2(-1, -1) = -135deg</span>
<div class="atan2-line atan2-three"></div>
</div>
<div class="atan2-row">
<span>atan2(-1, 1) = -45deg</span>
<div class="atan2-line atan2-four"></div>
</div>
</div>
CSS:
.atan2-demo {
display: grid;
gap: 12px;
}
.atan2-row {
display: flex;
align-items: center;
gap: 20px;
min-height: 100px;
}
.atan2-row span {
width: 240px;
flex-shrink: 0;
}
.atan2-line {
width: 90px;
height: 8px;
background-color: #0066cc;
transform-origin: center;
}
.atan2-one {
transform: rotate(45deg);
transform: rotate(atan2(1, 1));
}
.atan2-two {
transform: rotate(135deg);
transform: rotate(atan2(1, -1));
}
.atan2-three {
transform: rotate(-135deg);
transform: rotate(atan2(-1, -1));
}
.atan2-four {
transform: rotate(-45deg);
transform: rotate(atan2(-1, 1));
}
The lines rotate by 45deg, 135deg, -135deg, and -45deg.
The example shows how atan2() distinguishes coordinate quadrants rather than relying on a single tangent ratio.
Fixed-angle fallback declarations are included for browsers that do not support atan2().
atan() vs. atan2()
The atan() and atan2() functions both calculate angles, but they differ in their arguments and directional capabilities.
| Feature | atan() | atan2() |
|---|---|---|
| Arguments | One | Two |
| Input | A unitless tangent ratio | Two compatible numeric components |
| Return range | -90deg to 90deg | Greater than -180deg through 180deg for ordinary inputs |
| Quadrant detection | Cannot distinguish all quadrants | Uses both argument signs |
| Dimensions | Requires a unitless number | Accepts compatible dimensions and percentages |
For example:
atan(1) /* 45deg */
atan2(1, 1) /* 45deg */
atan2(-1, -1) /* -135deg */
The two coordinate pairs used by atan2() have the same tangent ratio, but they point in opposite directions.
Dividing the coordinates before calling atan() loses this information:
atan(1 / 1) /* 45deg */
atan(-1 / -1) /* 45deg */
Use atan() when only a tangent ratio is needed. Use atan2() when the direction of the original coordinate pair matters.
Related Trigonometric Functions
CSS provides several trigonometric functions for converting between angles and numeric values.
| Function | Description |
|---|---|
atan2() |
Returns an angle from two coordinate components. |
atan() |
Returns an angle from a tangent ratio. |
tan() |
Returns the tangent of an angle. |
asin() |
Returns an angle from a sine value. |
acos() |
Returns an angle from a cosine value. |
sin() |
Returns the sine of an angle. |
cos() |
Returns the cosine of an angle. |
The atan2() function is particularly useful when a direction must be calculated from both horizontal and vertical components.
Common Uses
The atan2() function is useful for CSS calculations involving directions, rotations, and geometric relationships.
| Use | Description |
|---|---|
| Directional rotations | Calculate a rotation angle from horizontal and vertical values. |
| Geometric layouts | Determine the direction between coordinate values. |
| Dynamic transforms | Calculate rotations using CSS custom properties. |
| Angle calculations | Convert coordinate components into an angle. |
| CSS animations | Use calculated directions in animated transforms. |
For example:
.example {
transform: rotate(atan2(75, 100));
}
This rotates the element by approximately 36.87deg.
For a direction between two points, first calculate the differences between their coordinates:
:root {
--start-x: 20;
--start-y: 30;
--end-x: 120;
--end-y: 105;
}
.example {
transform: rotate(atan2(var(--end-y) - var(--start-y), var(--end-x) - var(--start-x)));
}
The vertical difference is 75, and the horizontal difference is 100, producing an angle of approximately 36.87deg.
Limitations
The atan2() function has several important limitations.
- It requires exactly two comma-separated arguments.
- Both arguments must have compatible numeric types.
- The order of the arguments matters: vertical first, horizontal second.
- It returns an angle rather than a number or length.
- Its result must be used in a CSS context that accepts angles.
- Special values involving signed zero and infinity require careful interpretation.
- Older browsers may not support the function.
For example:
transform: rotate(atan2(1, 1));
This is valid because rotate() accepts an angle.
However:
width: atan2(1, 1);
This is invalid because width does not accept an angle.
The following expression is also invalid:
transform: rotate(atan2(50px, 2));
The first argument is a length, while the second is a unitless number.
When using coordinate calculations, ensure that both arguments represent compatible measurements.
Browser Support
The atan2() function is Baseline Widely available and has been supported across major browser engines since March 2023.
Older browsers may not recognize CSS trigonometric functions. Fixed-angle fallback declarations can help maintain a usable appearance.
.example {
transform: rotate(45deg);
transform: rotate(atan2(1, 1));
}
Browsers that support atan2() use the calculated angle. Browsers that do not support it retain the earlier valid declaration.
You can also check support using @supports:
@supports (transform: rotate(atan2(1, 1))) {
.example {
transform: rotate(atan2(1, 1));
}
}
For current compatibility information, visit Can I Use? and search for CSS trigonometric functions.
Specifications
The atan2() function is defined in the CSS Values and Units Module Level 4 .
The specification defines atan2() as a trigonometric function that returns an angle from two compatible numeric values, accounting for the signs of both arguments.
Related functions include atan(), asin(), acos(), sin(), cos(), and tan().
