Custom Functions are coming to CSS
CSS Custom Functions are going to be a real game changer. And will be landing in your browser in the future. So let's dive in!
A few days ago, I saw a video on YouTube about a new function that will become part of the CSS standard in the near future. Recently, a first prototype of @functions has landed in Chrome Canary behind a flag. They are following the Editor’s Draft of the CSS Functions and Mixins Module on the website csswg.org. When other browsers adopt this CSS module, it will be a real game changer. CSS is growing by the day into a real programming language. Yeah, I know that CSS isn't a programming language, but in the last few years, it has been getting a lot smarter and more complex.
Code examples of Custom CSS Functions
Let's start with a simple example of a Custom CSS Function. Let's say you want to transform a value into the negative. This can be done by writing a method --negative(value)
and outputting the value using the key result
.
@function --negate(--value) {
result: calc(-1 * var(--value));
}
:root {
padding: --negate(5px); /* -5px */
padding: --negate(10px); /* -10px */
}
For a second code example, we can take a look at the --light-dark function. The current light-dark() method in CSS only works with colors, which, most of the time, is all you need. But let's say you need to change the font weight of your text to improve readability. Using @function, you can do this. Until today, we had to write a @media query to detect if the prefers-color-scheme is dark. This results in a lot of extra lines of code.
h1 {
@media (prefers-color-scheme: light) {
font-weight: 400;
color: black;
}
@media (prefers-color-scheme: dark) {
font-weight: 500;
color: whitesmoke;
}
}
Using the upcoming Custom CSS Function, we can update the code above as follows. You might think that it will take the same amount or even more lines of code, but that really isn't the case, as you can reuse the @function throughout your project. This way, your code will be a lot cleaner in the end.
@function --light-dark(--light, --dark) {
result: var(--light);
@media (prefers-color-scheme: dark) {
result: var(--dark);
}
}
h1 {
font-weight: --light-dark(400, 500);
color: --light-dark(black, whitesmoke);
}
Custom CSS Functions Work Differently Than Other Languages
One important thing to note, especially if you are working with programming languages like PHP, JavaScript, or .NET. Functions in CSS don't have a return state. Just like any line of CSS, the last value is rendered in the browser. In terms of functions, this might be confusing, but since CSS has its own way of processing styling, it makes sense. Let's look at an example:
@function --dangerColor() {
result: red;
result: green;
}
h1 {
color: --dangerColor();
}
As a programmer, you would expect that the outputted color would be 'red' since this is the value linked with the result state. However, because CSS has no return state, this won't be the case. As mentioned before, CSS always uses the last value. So, the color of the h1 will be 'green'. Just think in the CSS way, not the PHP, JavaScript, or .NET way.
Using CSS variable and scoping
We can also use CSS variables within and around @functions. Since CSS is weighted by specificity and scoped, you might see some (un)expected results depending on your perspective.
@function --add-a-b-c(--b, --c) {
--c: 300;
result: calc(var(--a) + var(--b) + var(--c));
/* uses the --a from the call site's custom property,
the --b from the function parameter,
and the --c from the local variable */
}
div {
--a: 1;
--b: 2;
--c: 3;
z-index: --add-a-b-c(20, 30); /* 321 */
}
In the code example above, you can see how CSS variables are handled. --a will be set to 1 and won’t be overwritten. The CSS variables --b and --c are overwritten by values set in the function call for z-index. Their values will be set to 20 and 30, respectively. However, --c will be overwritten again in the scope of the @function with the value 300. So, the output will be 321.
Browser support of Custom CSS Functions
At this point, there is no real browser support at all. It has just landed as a first prototype in Chrome Canary behind the Experimental Web Platform Features flag. So, don't expect this new CSS function to roll out anytime soon.
My personal thoughts
I think this will be a great addition for us website developers, as it gives us more power and control over the front end of the websites we build. Will I start using Custom CSS Functions when they land? For sure—if browser support is decent, as this will help simplify the code and build more reusable components.