Unlike SASS variables, CSS Custom Properties can be modified in class selectors, allowing you to create abstractions and reduce the size of your CSS.

Let me show you an example!

In the CodyHouse Framework, we use the .grid-gap-{size} utility classes to set the spacing among grid items:

.grid {
  display: flex;
  flex-wrap: wrap;

  > * {
    flex-basis: 100%;
  }
}

.grid-gap-xxxs {
  margin-bottom: calc(-1 * var(--space-xxxs));
  margin-left: calc(-1 * var(--space-xxxs));

  > * {
    margin-bottom: var(--space-xxxs);
    margin-left: calc(var(--space-xxxs));
  }
}

.grid-gap-xxs {
  margin-bottom: calc(-1 * var(--space-xxs));
  margin-left: calc(-1 * var(--space-xxs));

  > * {
    margin-bottom: var(--space-xxs);
    margin-left: calc(var(--space-xxs));
  }
}

.grid-gap-xs {
  margin-bottom: calc(-1 * var(--space-xs));
  margin-left: calc(-1 * var(--space-xs));

  > * {
    margin-bottom: var(--space-xs);
    margin-left: calc(var(--space-xs));
  }
}

.grid-gap-sm {
  margin-bottom: calc(-1 * var(--space-sm));
  margin-left: calc(-1 * var(--space-sm));

  > * {
    margin-bottom: var(--space-sm);
    margin-left: calc(var(--space-sm));
  }
}

.grid-gap-md {
  margin-bottom: calc(-1 * var(--space-md));
  margin-left: calc(-1 * var(--space-md));

  > * {
    margin-bottom: var(--space-md);
    margin-left: calc(var(--space-md));
  }
}

.grid-gap-lg {
  margin-bottom: calc(-1 * var(--space-lg));
  margin-left: calc(-1 * var(--space-lg));

  > * {
    margin-bottom: var(--space-lg);
    margin-left: calc(var(--space-lg));
  }
}

.grid-gap-xl {
  margin-bottom: calc(-1 * var(--space-xl));
  margin-left: calc(-1 * var(--space-xl));

  > * {
    margin-bottom: var(--space-xl);
    margin-left: calc(var(--space-xl));
  }
}

.grid-gap-xxl {
  margin-bottom: calc(-1 * var(--space-xxl));
  margin-left: calc(-1 * var(--space-xxl));

  > * {
    margin-bottom: var(--space-xxl);
    margin-left: calc(var(--space-xxl));
  }
}

.grid-gap-xxxl {
  margin-bottom: calc(-1 * var(--space-xxxl));
  margin-left: calc(-1 * var(--space-xxxl));

  > * {
    margin-bottom: var(--space-xxxl);
    margin-left: calc(var(--space-xxxl));
  }
}

Because there’s a lot of repetition, a few weeks ago, we’ve decided to use CSS custom properties to simplify these classes.

The first step was creating an abstraction that contains the code we repeat for each utility class:

[class*="grid-gap"] {
  margin-bottom: calc(-1 * var(--grid-gap, 1em));
  margin-left: calc(-1 * var(--grid-gap, 1em));

  > * { 
    margin-bottom: var(--grid-gap, 1em); 
    margin-left: var(--grid-gap, 1em);
  }
}

This attribute selector looks for classes that contain the “grid-gap” string (all the grid-gap utility classes). Note that we’ve replaced the --space-unit variables with a new --grid-gap variable.

In our .grid class, we set the --grid-gap variable equal to 0 (default value).

.grid {
  --grid-gap: 0px;
  display: flex;
  flex-wrap: wrap;

  > * {
    flex-basis: 100%;
  }
}

Now we can modify, for example, the .grid-gap-xxxxs class as the following:

.grid-gap-xxxxs { --grid-gap: var(--space-xxxxs); }

We no longer need all the chunk of code about margins; we can just modify the value of the --grid-gap variable.

If we do the same for all the utility classes, we end up with the following:

.grid {
  --grid-gap: 0px;
  display: flex;
  flex-wrap: wrap;

  > * {
    flex-basis: 100%;
  }
}

[class*="grid-gap"] {
  margin-bottom: calc(-1 * var(--grid-gap, 1em));
  margin-left: calc(-1 * var(--grid-gap, 1em));

  > * { 
    margin-bottom: var(--grid-gap, 1em); 
    margin-left: var(--grid-gap, 1em);
  }
}

.grid-gap-xxxxs { --grid-gap: var(--space-xxxxs); }
.grid-gap-xxxs  { --grid-gap: var(--space-xxxs); }
.grid-gap-xxs   { --grid-gap: var(--space-xxs); }
.grid-gap-xs    { --grid-gap: var(--space-xs); }
.grid-gap-sm    { --grid-gap: var(--space-sm); }
.grid-gap-md    { --grid-gap: var(--space-md); }
.grid-gap-lg    { --grid-gap: var(--space-lg); }
.grid-gap-xl    { --grid-gap: var(--space-xl); }
.grid-gap-xxl   { --grid-gap: var(--space-xxl); }
.grid-gap-xxxl  { --grid-gap: var(--space-xxxl); }
.grid-gap-xxxxl { --grid-gap: var(--space-xxxxl); }

This optimization reduces the CSS size of this example by more than half! Obviously, you can apply this technique only when it’s possible to abstract some rules (I’m not suggesting that CSS custom properties will reduce by half the size of your CSS). But still, this tutorial is just an example of code optimization made possible by using CSS variables.

ps: CSS Variables are supported in all modern browsers.

If you’re interested in learning more about our grid system, download our framework or check the Grid and Layout page of the docs.

Be the first to know when we ship something cool!

Leave a Reply

Your email address will not be published.