Previously, we discussed how trigonometric functions are unfortunately considered the “Most Hated” CSS feature according to the State of CSS 2025 survey. This was surprising to me as a math enthusiast. I wrote an article highlighting the uses of the `cos()` and `sin()` functions. Today, let’s explore another function: the tangent function, `tan()`.
CSS Trigonometric Functions: The “Most Hated” CSS Feature
1. `sin()` and `cos()`
2. `tan()` (You are here!)
3. `asin()`, `acos()`, `atan()`, and `atan2()` (Coming soon)
Before diving into examples, what is `tan()`? The tangent of an angle is simply the sine divided by its cosine.
That definition doesn’t explain much about its use in CSS. Remember, `tan()` comes from dividing the angles of functions we examined in the first article. Unlike `cos()` and `sin()`, which were associated with circles, `tan()` is most useful with triangular shapes, especially right-angled triangles with a 90° angle.
If we choose the bottom-right angle, we have three sides: the adjacent side, the opposite side, and the hypotenuse. The `tan()` of an angle is the quotient of the opposite and adjacent sides. If the opposite side grows, `tan()` increases. If the adjacent side grows, `tan()` decreases. Adjust the triangle in the demo to see how `tan()` changes.
Now, let’s see how to use the `tan()` function in CSS. We can start by arranging triangles into another shape.
Sectioned lists
Imagine an unordered list arranged into a polygon, with each element as a triangular slice. Where does `tan()` come in? Let’s set up our list with HTML:
“`
- 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 - 8
 
“`
Note: This step will be easier when `sibling-index()` and `sibling-count()` gain support. For now, I’m hardcoding the indexes.
We have `–total: 8` items and an index `–i` for each. We’ll define a radius for the polygon, the height of each triangle:
“`
:root {
–radius: 35vmin;
}
“`
Add some styling to center the list items:
“`
ul {
display: grid;
place-items: center;
}
li {
position: absolute;
}
“`
Size the items: the container’s `width` is twice the `–radius`, and each element is `–radius` wide.
“`
ul {
display: grid;
place-items: center;
width: calc(var(–radius) * 2);
aspect-ratio: 1;
}
li {
position: absolute;
width: var(–radius);
}
“`
So far, we have a square container with stacked rectangular items. Let’s place them around the center. Rotate each item by dividing a full circle, `360deg`, by `–total: 8`, then multiply by `–i`.
“`
li {
–rotation: calc(360deg / var(–total) * var(–i));
transform: rotate(var(–rotation));
}
“`
The elements still overlap. Move their `transform-origin` to `left center` and translate them back to the center by half the `–radius` before rotating.
“`
li {
transform: translateX(calc(var(–radius) / 2)) rotate(var(–rotation));
transform-origin: left center;
}
“`
This creates a sunburst shape. Clip each element into a triangle using `clip-path`:
“`
li {
clip-path: polygon(100% 0, 0 50%, 100% 100%);
}
“`
Close the gaps by increasing the item height so their sides touch, forming a perfect polygon. Use `tan()` to calculate the perfect height.
For a simple square with four items, each triangle is a pair of right triangles. `tan()` is great for right angles. If we know the angle, we can find the triangle’s opposite side (height) using the adjacent side (width).
“`
li {
–theta: calc(360deg / 2 / var(–total));
height: calc(2 *
Discover more from WIREDGORILLA
Subscribe to get the latest posts sent to your email.


