Very very custom properties
Published: 2020-11-04 15:49:48

---
title: Very very custom properties
published: true
description: A collection of hacks with CSS custom properties (recap of Gaël Poupard's talk at ParisWeb 2020)
tags: 
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/mcich2p3mq15zodm1f1k.jpg
---

At the latest ParisWeb conference, [Gaël Poupard](https://www.paris-web.fr/orateurs/gael-poupard.php) gave a very interesting talk about CSS Custom properties. His talk was in french, but you’ll find here a recap in english of most of the clever uses of CSS properties he shared with us.

CSS custom properties are CSS properties that live in user-land; they are not part of any official specification and you can create as many as you want, with any silly name you’d like and put anything as their value. The only constraint is that they must start with a double dash (like `--myLittlePony: pink`). They work like any other CSS properties: they are inherited from parent elements, and can be manipulated from JavaScript.

They are often called CSS Variables, but this is not their official name. Technically they are only variables when they are read through the `var()` method. `var(--myLittlePony)` will evaluate to `pink`, so you can do `background-color: var(--myLittlePony)`. `var()` also accepts an optional second argument as a fallback value so `var(--myLittlePony, ‘black’)` will evaluate to `black` if you didn’t define `--myLittlePony`.

## Live variables

Conceptually, they are pretty similar to variables you might have in your SCSS/LESS preprocessor, but even more powerful they are part of the official spec and you can access and modify them live in the browser.

If you define `--myLittlePony` on your `<body>`, all your elements will be able to reference it. Your buttons can use `background-color: var(--myLittlePony)`, your links can have `color: var(--myLittlePony)`, etc. Actually, all your color palette could be defined as CSS custom properties instead of SCSS variables. And because they are live, you could access them with your dev tools or plain JavaScript, change their values, and have all your elements change colors instantly.

## Using them as arguments

Arithmetic operations can also be applied using calc(). `font-size: calc(12px * var(--fontScale))` for example will allow you to scale your font based on the `--fontScale` custom property. Set it to `1` for the default one, and to `0.8` or `1.2` to implement some kind of zooming/dezooming function. You could also chose to implement a different default `--fontScale` when based on the viewport size. 

The same logic could be applied to margins, paddings or even colors through the use of the `hsl()` function and some custom `--hue` or `--light` properties. Applications are virtually limitless here.

## Using them as feature switches

A specific application of the above principle is to use pseudo-boolean values (`0` and `1`) to switch some features on or off. For example, if we have `animation: bounce calc(var(--enableAnimation) * 1s) infinite` and `--enableAnimation` set to `1`, it will play normally. But if we set `--enableAnimation: 0` then the whole duration is evaluated to `0`, disabling it.

This simple feature switch principle can be applied to disable shadows on low-end devices or animation in our screenshot testing pipeline.

## Embedded fallback mechanism

The fallback value of the `var()` method can actually accept another call to `var()`, creating a deep nested system of fallback values. 

![image-20201001104429306](https://dev-to-uploads.s3.amazonaws.com/i/f7j4wzakr6un9l3xin0d.png)

Styles for input elements and form buttons are notoriously difficult to write and maintain as they have to deal with a plethora of conflicting states: hover, disabled, focus, valid, invalid, pending, clicked, primary, secondary, etc. Some of them are mutually exclusive while others can be stacked on top of each other.
Instead of writing more and more specific selectors to handle all the cases and overwriting rules, the nested fallback mechanism of the `var()` method can be used instead and might offer an easier alternative.

## Bonus side effect

One last interesting thing to note is that Shadow DOM nodes inherits CSS custom properties from their parents. This means that you can pass CSS custom properties to a Shadow DOM node, and it can then use them to style its content. This would act as some sort of API between the Shadow DOM node and the outside world.

![image-20201001110156020](https://dev-to-uploads.s3.amazonaws.com/i/71bzmmdrka5j5b1rixnb.png)