The atan() trigonometric function takes a number and returns its inverse for the tan() function. Specifically, it takes any number between -Infinity to Infinity and returns an angle between -90deg and 90deg (in radians) that, when passed to tan(), produces that number.
.element {
--atan: calc(atan(var(--i) / var(--count)));
/* atan() returns an angle, so to graph it, I used it as a number */
transform: translateY(calc(-1.5px * var(--int-atan)));
}
This is unlike acos() or asin(), whose input is limited between -1 and 1.
The atan() function is defined in the CSS Values and Units Module Level 4 specification.
Syntax
atan( <calc-sum> )
The atan() function takes in any calculation that must resolve to a number; otherwise, it makes the declaration invalid.
Arguments
/* it undoes tan() */
rotate: atan(1.73); /* ~60deg */
rotate: atan(1); /* 45deg */
rotate: atan(atan(30deg)); /* 30deg */
/* it can take any number between -Infinity and Infinity */
rotate: atan(Infinity); /* 90deg*/
rotate: atan(100000); /* ~90deg*/
rotate: atan(-Infinity); /* -90deg*/
/* we can do inner calculations */
rotate: atan(sqrt(3)); /* 60deg */
rotate: atan(sqrt(3) / 3); /* 30deg */
Basic usage
Before checking what atan() represents, I think it’s worth getting a little familiarized with it. As I mentioned at the beginning, atan() takes any number and returns a specific angle. If we want to target some notable angles (like 30° or 45°), then we’ll need to input the following numbers:
.square {
rotate: atan(-Infinity); /* -90deg */
rotate: atan(0); /* 0deg */
rotate: atan(2 - sqrt(3)); /* 15deg */
rotate: atan(sqrt(3) / 3); /* 30deg */
rotate: atan(1); /* 45deg */
rotate: atan(sqrt(3)); /* 60deg */
rotate: atan(2 + sqrt(3)); /* 75deg */
rotate: atan(Infinity); /* 90deg */
}
But where do these relationships between numbers and angles come from?
What’s atan()?
To understand atan(), we have to talk first about its original function, tan(), which takes an angle and returns its tangent as a number. And to define what exactly this tangent represents, we’ll have to look at one of its definitions through the right-angled triangle, which, as its name implies, is a triangle with a 90° angle.

If we pick one of the other two angles, we’d have three sides:
- Adjacent (the one touching the angle)
- Opposite (the one away from the angle)
- Hypotenuse (the longest side)
Then, given an angle, tan() returns the ratio between the opposite and adjacent sides.

What if we knew the length of the triangle’s sides and wanted the angle instead? Then, it’s as easy as using atan() to find it!

From here, we can explain some notable angles. For example, -Infinity and Infinity return -90deg and 90deg respectively, since for one of the angles to be 90deg, we would need an infinitely long side. Or if both sides are of equal length, their quotient would be 1, so they would have a 45deg angle.
Finding the perfect angle
All this theory is fine, but how can we use atan() in a practical way? Well, uses aren’t scarce at all: every time we want to find an angle given two sides of a (right) triangle, we’ll need to use atan()! And they appear in a lot of places.
Imagine we wanted to section a page diagonally, like the following layout:

…and we started with the following markup:
<main>
<h1>Meet Lorem, ipsum.</h1>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Minima quod architecto suscipit! Lorem, ipsum dolor sit
amet consectetur adipisicing elit.
</p>
<p>
Cupiditate ratione magni dicta qui natus reiciendis totam quidem ex. Accusantium nisi vero ratione ea doloremque
quis, consectetur aperiam eum!
</p>
</main>
…along with a little styling for the background-image:
body {
background-image: url("https://picsum.photos/id/32/1080/1080/");
background-size: cover;
background-position: bottom left;
}
So, right now, we only have our content behind a background image:
Gnarly, right? The first thing we would like to do is section the page diagonally into two halves. We can do this using a conic-gradient() placed at the bottom left corner of the page that crosses half the page:
main {
height: 100vh;
background: conic-gradient(at bottom left, oklch(0.2 0 0) 45deg, #0006 calc(var(--atan) + 2deg));
}
As you can see, we sectioned the page by a 45deg angle, but this will only work if the page is a perfect square. If we want to find the perfect angle, we’ll need to use atan(). To do so, we’ll think of the page as a big right triangle, where its height is the adjacent side and its width the opposite.

Then, replacing those values into the atan() formula, we’ll find our desired angle:
:root {
--angle: atan(100vw/100vh);
}
And we can just plug it into our conic-gradient()!
main {
height: 100vh;
background: conic-gradient(at bottom left, #161616 var(--angle), #0006 calc(var(--angle) + 2deg));
}
As you can see, the content overflows outside the upper section we just made. To fix this, we’ll need to create a safebox inside the triangle where we make sure the content is kept.

It’s simpler than we might expect since we already did half the work! Let’s say we want to make the safe box’s height one half of the page’s height. This means we would want its width to extend until it touches the triangle’s border. If we draw how this might look, we’ll notice another right triangle popping up.

We have all the necessary data to find the width! Substituting the values into tan()‘s formula, we can solve for it:

The only thing to note is, in order to create the safe box, we’ll use the element’s padding. So, we’ll subtract the value we just got for the width from 100dvw to get the correct padding:
/* In case you haven't set it */
* {
box-sizing: border-box;
}
main {
/* ... */
--sb-height: 50vh;
padding-bottom: calc(100vh - var(--sb-height));
padding-right: calc(100vw - ((100dvh - var(--sb-height)) * tan(var(--angle))));
}
What’s left is to add some padding on the other sides to give it a little breathing space:
main {
/* ... */
padding-top: 3rem;
padding-left: 3rem;
}
And we are done!
Specification
The atan() function is defined in the CSS Values and Units Module Level 4 specification, which is currently in Editor’s Draft.
Browser support
More information
- Trigonometric functions in CSS (Bramus)
- 081: Trigonometric Functions (CSS Podcast)
Related tricks!
Creating a Clock with the New CSS sin() and cos() Trigonometry Functions
The “Most Hated” CSS Feature: cos() and sin()
The “Most Hated” CSS Feature: tan()
The “Most Hated” CSS Feature: asin(), acos(), atan() and atan2()
Related
acos()
.element { rotate: acos(0.5) }
asin()
.element { rotate: asin(-0.5); }
atan2()
.element { rotate: atan2(200px, 200px); }
cos()
.element { transform: translateY(calc(cos(20deg * var(--i)) * 100px)); }
sin()
.element { transform: translateY(calc(sin(20deg * var(--i)) * 100px)); }
tan()
.element { transform: translateY(calc(tan(15deg * var(--i)) * 5dvh)); }