The “Most Disliked” CSS Feature: tan()

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.

Similar Posts