Conditional CSS Values

CSS lacks a general purpose ternary operator or if/else statements.

However, in many situations there is a small trick that we can use to toggle values using invalid custom properties and fallback values. I learn't this trick from Devon Govett.

Let's say we want to switch visibility between visible and hidden when a custom property is set or unset.

body {
  --switch: on;
}

.widget {
  visibility: /* on ? visible : hidden */ ;
}

When --switch is on, the value for visibility should be visible, otherwise it should be hidden.

Since we know that visible is the default value for visibility, we can set visibility to an invalid value var(--switch) so that CSS skips the declaration and the element remains visible.

body {
  --switch: on;
}

.widget {
  /*
   "on" is an invalid value for visiblity
   therefore this declaration is skipped and
   the value for visibility is visible
  */
  visibility: var(--switch);
}

Now comes the interesting part. How do we switch to hidden?

The answer is with a fallback value that CSS will pick up when the --switch property is set to an invalid value!

body {
  /* initial is an invalid value! */
  --switch: initial;
}

.widget {
  /* CSS will fallback to hidden */
  --visibility: var(--switch, hidden);
  visibility: var(--visibility);
}

By setting --switch to initial (a guaranteed-invalid value), the --visibility property will compute to the fallback hidden.

We can therefore switch the value of --switch between on and initial to change visibility!