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 ascos(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.
~
🔥 Like what you see? Want to stay in the loop? Here's how: