I'm bullish on CSS mixins
As a component library developer, @mixin from the Functions and Mixins Module has
quickly become one of my favorite parts of CSS. Even though I have to polyfill it, mixins solve
so many of the problems with classes+variables:
- Classes make a non-Tailwind project feel like Tailwind. Mixins go with the rest of your styles, upholding separation of concerns.
- Classes can't be toggled from CSS. I literally can't do "shrink the label when the input is
active" - I have to either copy the class's contents in (and hope I remember to update it) or
use something arbitrary like CSS Modules that doesn't work well with Svelte. Mixins can be
@applyd at any time! - You can't customize with pure classes because their styles are sometimes inlined, so you have to
do something ugly and space consuming like:
With mixins, the user can just define their own:root { --m3-font: Roboto, system-ui; --m3-font-label: var(--m3-font); --m3-font-label-large-size: 0.875rem; --m3-font-label-large-height: 1.429; --m3-font-label-large-tracking: 0.006rem; --m3-font-label-large-weight: 500; } .m3-font-label-large, .m3-font-label-medium, .m3-font-label-small { font-family: var(--m3-font-label); } .m3-font-label-large { font-size: var(--m3-font-label-large-size); line-height: var(--m3-font-label-large-height); letter-spacing: var(--m3-font-label-large-tracking); font-weight: var(--m3-font-label-large-weight); }@mixin --m3-label-large!
Mixins could kill or reform CSS Modules
| CSS Modules | Pure CSS |
|---|---|
@value | CSS variables |
| Composition | @apply |
from | @import |
| Defining a class | Defining a mixin |
However: my polyfill can't transform dynamic access like size="--m3-button-large" color="--m3-primary", and even once mixins are widely supported, the ecosystem won't be able to tree shake dynamic
access. We need a .mixin.css or something that you can import just what you need from,
so unused mixins can be eliminated - or more generically, we need support for granular imports from
a CSS file.
We would also need syntax. For example, Svelte would need something like style|apply={[size, color]}.