What values can you put in a CSS Custom Property?

Will Boyd:

CSS custom properties can hold all sorts of things. Some of these things were not obvious to me, which is why I decided to write this.

In short: they can contain just about everything. It’s only until CSS Custom Properties are used in a certain context as a CSS Variable — using var() — that they are evaluated.

☝️ To understand the above you should know that CSS Custom Properties are not Variables

A CSS Custom Property allows you to define a property with a certain value, e.g. --width: 200;.

It’s only when it’s used with var() — e.g. var(--width) — that you are creating a CSS Variable to use.

That’s why you can use CSS Custom Properties to:

What Can You Put in a CSS Variable? →

CSS Custom Properties are not Variables

When mentioning CSS Custom Properties here on bram.us I do tend to name them like that — and not CSS Variables — as that’s their official name.

I always thought the terms could be used interchangeably — with CSS Variables simply being the unofficial name — but as detailed by Šime Vidas on Web Platform News that’s not the case:

The spec distinguishes the two terms: A custom property is not a variable, but it defines a variable. Any property can use variables with the var() function whose values are defined by their associated custom properties.


CSS custom properties are not variables →

Emoji Customizer created with CSS Variables

Fun pen by Jakob Eriksen in which he combines Emoji and CSS Custom Properties to create an Emoji Customizer.

The reason that this works is because of the fact that emoji can have modifiers. Skin Tone and Hair, as used in the demo above, are such modifiers. Using the ZWJ ("\u200d") you can glue all parts together so that they become an “Emoji ZWJ Sequence”, yielding a new Emoji.

🤓 My favorite Emoji ZWJ Sequence is the Rainbow Flag (🏳️‍🌈). It literally is the combination of a white flag (🏳) and a rainbow (🌈).

Pass Data from CSS to JavaScript with CSS Variables

What happens when you combine the fact that part after the : for CSS Custom Properties doesn’t need to be valid CSS with window.getComputedStyle()? You get a way of passing data – including Arrays, Objects, and even JSON – from CSS to JavaScript.

CodePen: JSON in CSS Vars →

Staggered Animations with CSS Custom Properties

Paul Hebert on the Paul Hebert blog:

Movement in nature doesn’t happen all at once. Imagine a flock of birds taking off, raindrops splashing on the ground, or trees bending in the wind. The magic of these moments comes from many small movements overlapping and converging. I wanted to bring this natural movement into my web animations.

Instead of setting an incremental transition-delay on each :nth-of-type() element to achieve this effect, a different approach was taken: the transition-delay was set once and CSS Custom Property is used as a multiplier to increase that delay per element.

<li class="Menu__item">
  <a href="#" class="Menu__link" style="--index: 0;">Babar</a>
<li class="Menu__item">
  <a href="#" class="Menu__link" style="--index: 1;">Dumbo</a>
<li class="Menu__item">
  <a href="#" class="Menu__link" style="--index: 2;">Echo</a>
<!-- etc. -->
.Menu__link {
  --index: 0;
  transition-delay: calc(0.025s * var(--index));

Here’s a pen with the final result:


Staggered Animations with CSS Custom Properties →

💡 You can also use CSS Custom Properties as binary conditions for your styles. Combine it with a media query such as prefers-reduced-motion and you can disable animations that way.

💁‍♂️ Did you know the part after the : for CSS Custom Properties doesn’t need to be valid CSS? It’s only until it is used that it’ll be evaluated. This fact opens up the way for currying in CSS.

:root {
  --f-2: ((2 / 16 - var(--f-foot)) * var(--f-hill));

body {
  font-size: calc(var(--f-2) * 16);

Displaying the (Numeric) Value of CSS Custom Properties (CSS Variables) inside Generated Content

Nice hack by Cassie: she uses counter-reset as a temporary storage space so that the value of a CSS Variable it can be used inside generated content (e.g. with the content property).

⚠️ Do note that this only works with numbers, as counter-reset only accepts numbers.

Jeremy has also written down a few lines on a some of the limitations when using CSS Custom Properties

Displaying numeric CSS vars in generated content Demo (CodePen) →

💁‍♂️ On a personal note: Personally I’d consider data-* objects instead of CSS Custom Properties to inject the unread count. Like so:

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

I think it’s better place to store this kind of information (it is data, after all) and above that you’re not limited to using numbers.

Remains that this is a nice find by Cassie … I thought the time of clever CSS hacks was mostly over, turns out it’s not 🙂

Using @supports to detect if a browser supports CSS Variables

As tweeted by Ire Aderinokun:

@supports (color: var(--)) { 
   /* has support */

Not too surprising if you’ve used Feature Queries before, but what does surprise me is that you can make it work by only passing the prefix of CSS Custom Properties (e.g. --) into the var() function.

See the Pen Supports CSS Variables by Ire Aderinokun (@ire) on CodePen.

Did this help you out? Like what you see?
Consider donating.

I don’t run ads on my blog nor do I do this for profit. A donation however would always put a smile on my face though. Thanks!

☕️ Buy me a Coffee ($3)

Ordering tabular data with only CSS thanks to CSS Variables

Neat experiment by Roman Komarov in which he orders tabular data using just HTML/CSS, thanks to the use of CSS Custom Properties (CSS Variables):

Each cell of each row is given a specific value to sort on.

    --order-by-published: 161221;
    --order-by-views: 2431;
  <th class="table-cell">
    <a href="http://kizu.ru/en/fun/controlling-the-specificity/">Controlling the Specificity</a>
  <td class="table-cell">2016-12-21</td>
  <td class="table-cell">2 431</td>

When selecting a specific column, that value is aliased to the --order CSS Variable

#sort-by-published:checked ~ .table > .table-body > .table-row {
  --order: var(--order-by-published);

#sort-by-views:checked ~ .table > .table-body > .table-row {
  --order: var(--order-by-views);

And that --orderorder of each row:

.table-row {
  order: var(--order);

Add in an extra condition to use in the calculation and you can achieve a reverse sorting:

.table-row {
  order: calc(var(--order) * var(--sort-order, -1));

Very nice!

As Roman notes though, this isn’t great when it comes to a11y:

This so­lu­tion is not re­ally a so­lu­tion, but an ex­per­i­ment, and can be bad for ac­ces­si­bil­ity — right now its not pos­si­ble to re­order stuff in a way it would be ac­ces­si­ble with key­board (with­out con­fus­ing tele­port­ing fo­cus) or screen read­ers.

Roman Komarov: Variable Order →

CSS Variables and Reduced Motion

Great usage of CSS Custom Properties in combination with calc() by Steve Gardner to cater for users who have prefers-reduced-motion set to reduce:

By setting --duration to 0 it basically behaves like a binary condition for a CSS calculation. Simple and effective 🙂

(Personally I’d set it to either 0 or 1 – and not 0.5. That way the math is kept easy and it becomes a true binary toggle)

⁉️ Not sure what prefers-reduced-motion is? Check out CSS-Tricks’ Introduction to the Reduced Motion Media Query to get up to speed.

Theming with CSS Custom Properties (CSS Variables)

Stephanie Liu has replicated the native Slack theming capabilities in the browser using CSS Variables CSS Custom Properties. The essence of the demo is actually quite simple: define the variables on the :root level, and use ‘m where needed.

:root {
  --column-bg: #ae0001;
  --menu-bg-hover: #680001;
  --active-item: #D3A625;
  --active-item-text: #680001;
  --hover-item: #BE0002;
  --text-color: #FFFFFF;
  --active-presence: #00FFBA;
  --mention-badge: #DE4C0D;
.sidebar {
  background: var(--column-bg, #ae0001);

Here’s a full working demo:

See the Pen Slack Theming with CSS Custom Properties by Stephanie (@ramenhog) on CodePen.

💁‍♂️ You can also use this with Responsive Web Design / Media Queries: simply change the values of CSS Custom Properties in your Media Queries, et voila.

Theming with CSS Custom Properties →
Slack Theming with CSS Custom Properties →