🎩 JavaScript Enhanced Scss mixins! 🎩 concepts explained

Adam Crockett 🌀 - Jul 26 '19 - - Dev Community

In the next post we are going to explore CSS @apply to supercharge what we talk about here. deprecated proposal :(

Traditional Web development flow

Traditionally we use css to style webpages, then add more styling after the fact with JavaScript, this usually works by adding arbitrary classes as an intermediary.

We also created business logic and a bunch of other things within JavaScript aside from styling. Seperation of concerns kind of glosses over the fact that JavaScript does indeed style applications, the job would originally have been intended for css and css alone.

css sure does have some crazy powers that can be as good as JavaScript to a point (a preprocessor is required for really clever stuff) but usually JavaScript has more powerful APIs based on that of css, I'm talking about Houdini, Web Animations API, Match media - aka media queries for JavaScript and so many more.

So the traditional model looks a bit like this.

CSS talks to the dom, JavaScript talks to the dom, JavaScript adds more classes or styles, CSS is prepared to handle state changes because it's authored to handle future tense, but all that really happens is that JS changes the dom, it's a bit inefficient if you think about it, all that potential state in your CSS, that might never be interacted with by the user.

JavaScript Enhanced Sass

So this technique hasn't got a name I'm calling it (Jess, JavaScript enhanced stylesheet), In truth it's a pattern and not really tied to sass but it could be done in any preprocessor, maybe even a new tool should be written, this is a paradigm shift, that's why I'm excited.

CSS variables/ custom properties are already pretty outstanding, I used to think, I use sass, I don't need CSS variables, but they are very different things, get that out of your head if you think that. CSS variables are live, as in change them in your devtools and see them update your hole UI. In effect you are no longer styling elements and classes in but just one variable. But can we take that one step further?

The answer of course is yes, we can actually get and set CSS variables directly inside JavaScript, this means a few things, firstly CSS is no longer handling future tense state changes, it is realtime, Triggered by JavaScript events, a CSS value could be updated to scroll position for example. Awesome! Now JavaScript has total power over CSS and the Dom. But what if there was a pattern that could enhance CSS with JavaScript powers instead? What if CSS controlled the styling logic of JavaScript so transparently that you could see a clear separation of concerns?

I am talking about reversing the flow so that CSS could call JavaScript and stylistically effect the dom (or do anything in JavaScript including use the more powerful APIs I mentioned earlier)

button {
    // Allows only focus outline on keys
    @include fucus(no-click);
}
Enter fullscreen mode Exit fullscreen mode

The mixin then handsoff to JavaScript 🧙‍♂️

There is already possible conveniently through the power of simple scss mixins. The idea is simple. Create a mixin that captures the selector it was used upon, this selector is then fed to a generated CSS variable --#{key}: .my-selector;, where key is going to need to be unique as then we can store more variables at :root without overriding previously called mixins accidentally, aka we want to use the mixin more than once. A scss guid is generated using random(9*9*9*9)making a very large number with the odds of duplication very very low. So we have this random guid now on :root with the value contained, the selector of the mixin caller. Next we scrape the root for CSS variables with a guid and hey presto we can now loop through and change the elements using this selector.

If you want to see this working, check out the rest of this series, dive into the code and see the difference.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .