Computing cos(25deg) in CSS

An answer to a headscratcher Tyler Gaw (and Chris Coyier) ran into: getting the result of cos(25deg) in CSS.

~

The Problem

On the CodePen blog, Chris Coyier dug into a blog post by Tyler Gaw – a blog post which I had missed before – in which Tyler wanted to know what the resulting number for cos(25deg) in CSS is.

Take cos(25deg) for example. I know that will return a number between -1 and 1. But what number?

One of the approaches Tyler tried, but then abandoned, was storing that value in a Custom Property and then reading its Computed Value. As Tyler found, this didn’t work:

… using a custom prop like --u: cos(25deg) doesn’t really work either because the custom prop value is stored as cos(25deg)

Checking the Computed Value of --u indeed yields the string cos(25deg) instead of the number you might expect:

#demo {
  --u: cos(25deg);
}
getComputedStyle($0).getPropertyValue("--u");
// -> "cos(25deg)"

~

The Cause

The reason why the CSS engine doesn’t fully parse cos(25deg) in Tyler’s demo because the parser doesn’t know what type --u is.

As stated in the Custom Properties specification, a Custom Property computes to:

[The] specified value with variables substituted, or the guaranteed-invalid value.

The further processing of cos(25deg) only happens when that value is used in a declaration that expects a <number>. For example, if you use cos(25deg) as the value for scale – or use var(--u) as the value for scale – getting the computed value for scale will return the resulting number:

#demo {
  scale: cos(25deg);
}
getComputedStyle($0).getPropertyValue("scale");
// -> 0.906308

This because the engine tries to parse scale as a its expected type of <number>.

~

The Solution

Winging back to Tyler’s custom property approach, the solution comes in the form of @property, which allows you to register a custom property to be of a certain type.

By telling the parser – using @property – that the custom property’s type is a <number>, the engine will try to parse it as such when getting its computed value.

As per CSS Properties and Values API Level 1 specification:

The computed value of a registered custom property is determined by the syntax of its registration.

💁‍♂️ Note that when this parsing fails, the value can become Invalid at Computed-Value Time (or IACVT for short).

In code, it becomes this:

@property --r {
  syntax: "<number>";
  inherits: false;
  initial-value: 0;
}

#demo {
  --r: cos(25deg);
}
getComputedStyle($0).getPropertyValue("--r");
// -> 0.906308

So there you have it, Tyler, you no longer need to resort to the JS workaround you came up with 🙂

~

All together

Here’s a demo that combines all code used in this post:

See the Pen Parsing CSS functions by Bramus (@bramus) on CodePen.

~

Published by Bramus!

Bramus is a frontend web developer from Belgium, working as a Chrome Developer Relations Engineer at Google. From the moment he discovered view-source at the age of 14 (way back in 1997), he fell in love with the web and has been tinkering with it ever since (more …)

Unless noted otherwise, the contents of this post are licensed under the Creative Commons Attribution 4.0 License and code samples are licensed under the MIT License

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.