Now that CSS Custom Properties are a Thing, All Value Parts Can Be Changed Individually

In CSS, some properties have shorthand. One property that takes separated values. Syntactic sugar, as they say, to make authoring easier. Take transition, which might look something like:

.element {   transition: border 0.2s ease-in-out; }

We could have written it like this:

.element {   transition-property: border;   transition-duration: 0.2s;   transition-timing-function: ease-in-out; }

Every “part” of the shorthand value has its own property it maps to. But that’s not true for everything. Take box-shadow:

.element {   box-shadow: 0 0 10px #333; }

That’s not shorthand for other properties. There is no box-shadow-color or box-shadow-offset.

That’s where Custom Properties come to save us!

We could set it up like this:

:root {   --box-shadow-offset-x: 10px;   --box-shadow-offset-y: 2px;   --box-shadow-blur: 5px;   --box-shadow-spread: 0;   --box-shadow-color: #333; }  .element {   box-shadow:     var(--box-shadow-offset-x)     var(--box-shadow-offset-y)     var(--box-shadow-blur)     var(--box-shadow-spread)     var(--box-shadow-color); }

A bit verbose, perhaps, but gets the job done.

Now that we’ve done that, remember we get some uniquely cool things:

  1. We can change individual values with JavaScript. Like:

    document.documentElement.style.setProperty("--box-shadow-color", "green");
  2. Use the cascade, if we need to. If we set --box-shadow-color: blue on any selector more specific than the :root, we’ll override that color.

Fallbacks are possible too, in case the variable isn’t set at all:

.element {   box-shadow:     var(--box-shadow-offset-x, 0)     var(--box-shadow-offset-y, 0)     var(--box-shadow-blur, 5px)     var(--box-shadow-spread, 0)     var(--box-shadow-color, black); }

How about transforms? They are fun because they take a space-separated list of values, so each of them could be a custom property:

:root {   --transform_1: scale(2);   --transform_2: rotate(10deg); }  .element{   transform: var(--transform_1) var(--transform_2); }

What about elements that do have individual properties for their shorthand, but also offer comma-separated multiple values? Another great use-case:

:root {   --bgImage: url(basic_map.svg);   --image_1_position: 50px 20px;   --image_2_position: bottom right; }  .element {   background:      var(--bgImage) no-repeat var(--image_1_position),     var(--bgImage) no-repeat var(--image_2_position); }

Or transitions?

:root {   --transition_1_property: border;   --transition_1_duration: 0.2s;   --transition_1_timing_function: ease;      --transition_1_property: background;   --transition_1_duration: 1s;   --transition_1_timing_function: ease-in-out; }  .element {   transition:      var(--transition_1_property)      var(--transition_1_duration)      var(--transition_1_timing_function),     var(--transition_2_property)      var(--transition_2_duration)      var(--transition_2_timing_function), }

Dan Wilson recently used this kind of thing with animations to show how it’s possible to pause individual animations!


Here’s browser support:

Green indicates full support at the version listed (and above). Yellow indicates partial support. Red indicates no support. See Caniuse for full browser support details.

Desktop

Chrome Opera Firefox IE Edge Safari
49 36 31 No 15 9.1

Mobile / Tablet

iOS Safari Opera Mobile Opera Mini Android Android Chrome Android Firefox
9.3 37 No 56 57 52

Now that CSS Custom Properties are a Thing, All Value Parts Can Be Changed Individually is a post from CSS-Tricks

CSS-Tricks

Add a Comment

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

21