DEV Community

Cover image for 🎩 JavaScript Enhanced Scss mixins! 🎩 concepts explained
Adam Crockett πŸŒ€
Adam Crockett πŸŒ€

Posted on • Edited on

🎩 JavaScript Enhanced Scss mixins! 🎩 concepts explained

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.

Top comments (11)

Collapse
 
andrejmikulicka profile image
Andrej Mikulička

I have absolutely no idea what have I just read but can't wait for Jess.

Collapse
 
adam_cyclones profile image
Adam Crockett πŸŒ€ • Edited

Thanks for the feedback, this has to be the best comment I have ever read!
I find it hard to express myself and yet I have captured yours and others interest which is absolutely fascinating, perhaps I am not barking up the wrong tree.

I will try to write a cleaner step by step edit - or even a new post that is more like a tutorial, documenting the principles in practice, reading code is easier to digest sometimes. What I really want to see is what other people have made with this approach and what problems or positives they have found, how did they improve it, this will us to write a next-gen tooling for everyone. I think a tutorial will help alot.

Pictures speak a thousand words, so here is the next in the series preview.

A bloody event listener registered in scss, Magic!
This perfectly illustrates what I have talked about, this is 100% pure styling logic where its meant to be, in a stylesheet.

Business logic would be clearly separated into JavaScript. A form submission for example would then just handle where data goes, not also what animations happen and how the UI updates, I think it is possible to make this work with Angular, React and Vue as well, so that is another post in this series.

Whats amazing is that this is achievable with existing tools today, this is thanks in part to css variables. Its about to get a lot more powerful, css mixins are coming! Google "@apply css rule".

What makes me smile from ear to ear is that this scss actually registers a JavaScript event listener, but thats a story for another time, keep your eyes pealed. πŸ˜„

Collapse
 
andrejmikulicka profile image
Andrej Mikulička

Wow, this looks AWESOME! Thanks for the info! Also, yes, sometimes it's better to see the code, because this comment explained more than the whole series to me.

Collapse
 
webia1 profile image
Webia1

How awesome is that? :)

Collapse
 
adam_cyclones profile image
Adam Crockett πŸŒ€ • Edited

I have a little announcement, due to the positive reception of this idea. I have decided to name the idea Jess JavaScript enhanced Stylesheets, and maybe Tess Typescript enhanced Stylesheets eventually.

I am going to develop Webpack tooling initially to make this workflow more seamless, there will likely be a frontend js adapter to assist this, the endgame is to write Jess, and Tess, indipendent (Rust or V or LuaJit or c++ anything fast that could potentially run in WASM and node or wasi) powered the compiler, similar to svelt and syntactically like sass but with a modern JavaScript inspiration, I will likely fork the rsass implementation and hack it into something new, it's not going to be just another preprocessor, this is more like a frontend framework for CSS, I believe we do CSS in js because there is not a viable alternative. Very excited to start πŸ§™β€β™‚οΈ, I would be very grateful to work with contributors and get a roadmap sorted and technical designs.

Collapse
 
adam_cyclones profile image
Adam Crockett πŸŒ€

Let's elaborate, there will be no Webpack tooling, Jess is under active development. In its current form it is a compiler for a subset of JavaScript, es5.5 if you will, some modern syntax will be available. You will be able to pick up Jess in a short amount of time because the syntax is something that is very similar to things you already know. Jess will eventually run in your browser, have a test framework and much more.

Jess is written in Typescript and Rust on Wasm and is at this point lexing input. I will be keeping a regular posting of development and if you are interested in this just follow me.

Collapse
 
josephborg profile image
Joseph A Borg

Why not use unique-id() instead of the random(9*9*9*9)?

Collapse
 
adam_cyclones profile image
Adam Crockett πŸŒ€

Because I didn't know about that! Good one! I will add this in right away 😍

Collapse
 
adam_cyclones profile image
Adam Crockett πŸŒ€

Oh just to say the implementation details are being refined anyway, suggestions like this are greatly appreciated!

Collapse
 
joshuajarman profile image
Joshua Jarman

We've been writing a lot of reactive css using zeit/styled-jsx for react, you might be interested in checking that project out and see the approach they've taken.

Collapse
 
adam_cyclones profile image
Adam Crockett πŸŒ€

So this post exploded for the 3rd time, I would like to write Jess to compete with tailwind and I already have half a parser, if you want to colab and know rust I'd love to hear from you. πŸ¦“