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.