Embrace the Cascade: CSS-in-JS

Libraries & Tradeoffs

Disclaimer

This presentation is not a dig at your preferred workflow*. If you find something that works for you, use it.

 

If you're looking for something new to solve a problem,

this talk will help you navigate the lingo.

* unless your workflow is based on styled-components

Why This talk?

Why This talk?

Why This talk?

But first,

why CSS-in-JS?

Dead code elimination

Make sure the CSS you need is there

Leverage the TS ecosystem

Type-checking, bundling, compilers*

Act I    My perfect library

Act II   BoomerCSS

act III  One more thing

Things to consider:

  • Performance
  • Utility vs Class
  • Rendering patterns supported
  • Is this for a page, or for a design-system?
    • Handling of variance
    • How are other devs gonna extend what you have?
  • Escape hatches
  • Community and Ecosystem
  • Tooling required for good DX
  • Tooling required for good UX
  • Compatibility with vanilla JS, react, solid, vue, etc
  • Bundle size
  • Styling pattern: JS object vs CSS string

 

Runtime

Build time

Styled-components

Vanilla-extract

CSSOM, dynamic styles

"dumb" .css file

When does the code runs?

run-time

but once

Stitches

Performance

Very JS

Just CSS

Styled-components

Tailwind

How much

"it's just CSS"

Theme provider

CSS vars

CSR only

Everything

Styled-components *

CSS-modules

Rendering patterns supported
CSR, SSR, SSG, RSC

* this one is a little bit unfair but I'm sticking with it

Utility-first or atomic

Class-based
Semantic

<button class="text-base font-medium rounded-lg p-3 bg-sky-500 text-white"> 
    Accept 
 </button
<button class="btn-primary"> 
    Accept 
 </button
.btn-primary {
  border-radius: .5rem;
  background-color: rgb(14 165 233);
  padding: .75rem;
  font-size: 1rem;
  line-height: 1.5rem;
  font-weight: 500;
  color: rgb(255 255 255);
}

Utility-first promise

  • Scale with large teams
  • no cascade to deal with
  • no specificity to deal with
  • no CSS stuff to deal with*
  • tiny .css file (great for caching)
  • WYSIWYG
  • safer changes
  • copy paste is fine

Client bundle load

Performance

features / components

added bytes to load

Utility-first

Semantic

And yet...

I want a class based
CSS-in-JS library

Variant-first

Styling coloration

No tooling required

Just typescript
and you're good

Statically extracted

doesn't mean no runtime

Ongoing maintenance cost

Specificity is not an issue anymore*

introducing @layer

Ready for boomers

Act II   Boomer CSS

- Class based

- Statically extracted

- barely any runtime

- variants

- just CSS

Not ready for use

An experiment for now


Let me know
if you're interested

Roadmap

  • Theme overwrites
  • Dynamic variables
  • Better CSS-extraction pattern
  • Better handling of styles/css generation
  • add lightningCSS compiler

Act III   One more thing

Better CSS-extraction?

Ways to extract CSS

  • Compiler approach *
  • Build against a meta-framework
  • Provide plugin(s) for bundler(s)
  • Use macros **

* what BoomerCSS uses

** what BoomerCSS kinda uses

Javascript Macros

  • Kind of comptime in Zig
  • stage 3-ish TC39
  • implemented in Bun / Parcel
  • Not limited to CSS or asset generation
  • generate assets + remove runtime exec cost

deck

By pookmook

deck

  • 30