On CSS Architectures, Frameworks and Tooling

At LinkedIn, Chris has been working on a CSS Framework and Optimiser. In this presentation he’ll give some insights and thoughts about how and why styling components has led us to CSS-in-JS, which has invariably led to JS-in-CSS. He’ll address the ergonomics of this direction developers have taken, and while undertanding the resaons for these, why he has concluded this isn’t an ideal direction for performance. Finally, drawing on his team’s experience of developing these solutions, how tooling can bridge the divide between what’s best for the developer and what’s best for the browser.

The cascade is dead! Long live style sheets!

…well you have to start with something controversial. There are a lot of strong opinions about this; and presentations about doing CSS at scale are about managing the cascade.

Why do people like CSS-in-JS? Common themes are…

  • not needing to worry about naming
  • not having to deal with the cascade
  • having all your code in one place

At LinkedIn they had some problems with CSS – heavy amounts of bloat (an SPA that had 3.2meg of CSS), specificity was out of control, designs didn’t meet the design system.

They also had a lot of constraints – dozens of apps across lots of platforms (old systems need pure CSS deliverables), needed to put the priority on performance, needed to support Ember apps (which has no CSS-in-JS solution; “..I mean I guess we could make one..”).

They set a lot of goals – including server-side rendering, enabling designers, making a great dev experience…

Concerns with CSS-in-JS (Chris Has Opinions!)

  • less approachable to designers
  • CSS-in-JS (theoretically) worse for performance
  • Atomic CSS and other declaration-oriented systems create high-perf garbage (the styles are too terse to read, you can’t easily extend or abstract)
  • BEM is awful

The plan

  • component-oriented selectors
  • build a better BEM
  • optimise shared declarations into shared rules
  • use build-time code transforms for optimisation
  • generate code split styles
  • uglify CSS idents for maximum gzip efficiency

GZIP efficiency is impacted a surprising amount by the identifiers we use. CSS-in-JS hashes are particularly bad for this as they defeat compression.

The problem with optimising CSS by mergine rules is that it messes with the cascade, by reordering declarations. The problem then is you need to know what the components are doing before some optimisation decisions can be made.

So they made CSS Blocks and an optimiser called OptiCSS (that reads the HTML and CSS and optimises it accordingly).

Seems too good to be true? Does it handle dynamic changes, what’s the overhead, is it hard to use, etc?

So what’s a block? A collection of related design elements and their various modes and interaction states. This is the same as the B in BEM.

Every block is in its own stylesheet; classes and states are differentiated as nouns/adjectives respectively. There is a block root (root element), block state, class (child element) and class state.

(demos – these had very high detail that was too much to reproduce, see slides)