A Journey from
SASS to CSS-in-JS
Martin Jujou (jooj)
About me
@mjujou
Current Domain
Frontend Landscape
● ~ 288 Reusable / Themable React
components
● ~ 62 page level components
● 4 Single Page Apps (SPA) components
● Many node servers
Current Domain React
Landscape
fe-pa-xyz
Or
fe-spa-xyz
fe-co-ccc
fe-co-bbb
fe-co-aaa
fe-server-xxxx
Node server React
React
Let's start the (long) Journey ...
Why SASS
Rewind to June 2016… (When i started at Domain)
● SASS was used on a few components already
● Our common style library was written in SASS
(fe-brary)
● At the time it was more popular than most other
style frameworks / extensions
● Worked well enough alongside React
How we used SASS
At a very high level :)
<Select />
(scss, js, static files)
fe-build
(internal build tool)
fe-brary
(common sass,
mixins, variables,
placeholders etc)
Bundle Command Output:
*.css
*.js
Static assets
How we used SASS
<Select />
Why #no-sass
Fast-forward to Jan 2017 …
Why #no-sass
Why #no-sass
Why #no-sass
We needed to step back to think more about the WHY
● Multiple versions of the same component caused style clashes.
● BEM syntax was annoying (required too much developer brain power)
● Bloated css output, nested selector overload, unused css on a given
page
● Needed critical css
● Sass compilation was slow due to a few factors (theming, static assets
etc)
● node-sass binary was problematic on different platforms (eg:
windows)
<MyPageComponent />
<Select /> 1.0.4
<SearchFilters /> 1.0.0 <Select /> 2.0.0
Why #no-sass
Why we needed to be careful with our decision
● Need to keep components consistent
● Not easy to update many components
● Performance was critical
● We wanted a framework which was relatively future
proof
● We need a great developer experience
We needed to experiment
styled-components
styled-components
styled-components
Pros:
- Most popular CSS-in-JS framework
- Easier to delete unused css (tied to components)
- Good performance
Cons:
- Difficult for us to migrate to (code mod would be
impossible)
- Bundle size isn't great (at the time)
- JSX no longer semantic (relies on good naming)
- Architecting SC projects is a challenge
Glamorous
Glamorous
Glamorous
Pros:
- Easier to delete unused css
- Good performance + bundle size
- Extraction of css
Cons:
- Difficult for us to migrate to (code mod would be
impossible)
- Quickly became clear the author (Kent C Dodds) was
in favour of emotion (eventually deprecated) .. DOA
Styled jsx
Styled jsx
Pros:
● shadow dom-style encapsulation, closely resembles
web components
● Fast and small bundle
● Future-proof: Equivalent to server-renderable
"Shadow CSS"
Cons:
● Not very intuitive (having style block inside JSX
confused developers)
● Not very mature at the time of investigation + not very
popular outside of nextjs
Postcss + CSS Modules
● It's not CSS-in-JS !! This would be a staged approach
prior to making the full move to CSS-in-JS
● What if we could satisfy some of these pain points
quickly:
○ Keeping same scss syntax so no major changes
needed in each component
○ Getting rid of problematic node-sass binary
○ Removing the need to use BEM
Postcss + CSS Modules
Pros:
- Got a component working with minimal sass changes
- Extraction of css
Cons:
- Ended up being slower !! We needed lots of plugins
- Not all sass syntax could be supported (eg: @function,
@if )
- Some nasty side effects (eg: sass math evaluation was
different)
Postcss + CSS Modules
● postcss-scss (Parser)
● postcss-easy-import
● postcss-url
● postcss-advanced-variables
● postcss-hexrgba
● postcss-color-function
● postcss-functions
● postcss-flexbugs-fixes
● postcss-nested
● postcss-extend-rule
● postcss-at-rules-variables
● postcss-property-lookup
● postcss-calc
● postcss-automath
● postcss-current-selector
● postcss-at-warn
● postcss-warn-cleaner
Emotion
Emotion
Emotion
Emotion
Pros:
- Popular CSS-in-JS framework
- Excellent performance
- Don't need to clutter JSX with styled components
- Easiest migration path out of all CSS-in-JS frameworks
- Supports composition, nested selectors and global styles
- Supports server side rendering
- Plays nice with legacy sass components
Cons:
- Docs not as good as something like styled components (bit better
now)
Emotion
Finally agreed this was the path forward !
How?
Styled Components
● Agreed not to use import styled from '@emotion/styled' yet ...
○ Easier migration path to use css string styles (can automate some
bits)
○ Less brain power required, using styled approach would need a
re-architecture of the component being reworked (including JSX
changes)
○ Less semantic in JSX if using styled
○ Disabling with eslint rule
If this turns out to be too restrictive we can bring it back in the future - was a
heated topic
Styled Components
Server Side Rendering
Emotion 9 required mods to our internal
tooling at the time to ensure css was inlined
into HTML
Emotion 10 has SSR work out of the box !!
peerDep
Exporting style variables
with JS
Theming
Not ideal.. Need to
manually pass in theme for
each css
Theming
Style utility functions
Backwards compatibility
E2E Testing
Style linting
https://github.com/styled-components/stylelint-config-styled-components
Same style linter as styled components (works for emotion)
Co locating styles
CLI Migration Tool
SASS to Emotion: https://github.com/DomainGroupOSS/sass-to-emotion
Emotion workshops
Big wins
● No more style clashes if there is 2 majors in component tree (as
emotion classname hash is content based)
● No more node-sass !
● No need to worry about writing namespaced selectors
● Performance gains (faster bundling and faster runtime as there is
less css bloat !)
Common Questions
Class name labels
css-149rzh1
css-149rzh1-martin
Composing styles
Annoyances
Unit testing:
Annoyances
Passing custom class names to 3rd party components:
● Anti-pattern to doing this but sometimes it's necessary for 3rd party components
● Was ok to do in emotion 9, but cumbersome in 10
Emotion 9 Emotion 10
Annoyances
Critical CSS - ordering of style tags isn't necessary ideal for SSR critical css ?
Thanks
Software Engineers

A journey from sass to css in-js

  • 1.
    A Journey from SASSto CSS-in-JS Martin Jujou (jooj)
  • 2.
  • 3.
  • 4.
    Current Domain Frontend Landscape ●~ 288 Reusable / Themable React components ● ~ 62 page level components ● 4 Single Page Apps (SPA) components ● Many node servers
  • 5.
  • 6.
    Let's start the(long) Journey ...
  • 7.
    Why SASS Rewind toJune 2016… (When i started at Domain) ● SASS was used on a few components already ● Our common style library was written in SASS (fe-brary) ● At the time it was more popular than most other style frameworks / extensions ● Worked well enough alongside React
  • 8.
    How we usedSASS At a very high level :) <Select /> (scss, js, static files) fe-build (internal build tool) fe-brary (common sass, mixins, variables, placeholders etc) Bundle Command Output: *.css *.js Static assets
  • 9.
    How we usedSASS <Select />
  • 10.
  • 11.
  • 12.
  • 13.
    Why #no-sass We neededto step back to think more about the WHY ● Multiple versions of the same component caused style clashes. ● BEM syntax was annoying (required too much developer brain power) ● Bloated css output, nested selector overload, unused css on a given page ● Needed critical css ● Sass compilation was slow due to a few factors (theming, static assets etc) ● node-sass binary was problematic on different platforms (eg: windows) <MyPageComponent /> <Select /> 1.0.4 <SearchFilters /> 1.0.0 <Select /> 2.0.0
  • 14.
    Why #no-sass Why weneeded to be careful with our decision ● Need to keep components consistent ● Not easy to update many components ● Performance was critical ● We wanted a framework which was relatively future proof ● We need a great developer experience
  • 15.
    We needed toexperiment
  • 16.
  • 17.
  • 18.
    styled-components Pros: - Most popularCSS-in-JS framework - Easier to delete unused css (tied to components) - Good performance Cons: - Difficult for us to migrate to (code mod would be impossible) - Bundle size isn't great (at the time) - JSX no longer semantic (relies on good naming) - Architecting SC projects is a challenge
  • 19.
  • 20.
  • 21.
    Glamorous Pros: - Easier todelete unused css - Good performance + bundle size - Extraction of css Cons: - Difficult for us to migrate to (code mod would be impossible) - Quickly became clear the author (Kent C Dodds) was in favour of emotion (eventually deprecated) .. DOA
  • 22.
  • 23.
    Styled jsx Pros: ● shadowdom-style encapsulation, closely resembles web components ● Fast and small bundle ● Future-proof: Equivalent to server-renderable "Shadow CSS" Cons: ● Not very intuitive (having style block inside JSX confused developers) ● Not very mature at the time of investigation + not very popular outside of nextjs
  • 24.
    Postcss + CSSModules ● It's not CSS-in-JS !! This would be a staged approach prior to making the full move to CSS-in-JS ● What if we could satisfy some of these pain points quickly: ○ Keeping same scss syntax so no major changes needed in each component ○ Getting rid of problematic node-sass binary ○ Removing the need to use BEM
  • 25.
    Postcss + CSSModules Pros: - Got a component working with minimal sass changes - Extraction of css Cons: - Ended up being slower !! We needed lots of plugins - Not all sass syntax could be supported (eg: @function, @if ) - Some nasty side effects (eg: sass math evaluation was different)
  • 26.
    Postcss + CSSModules ● postcss-scss (Parser) ● postcss-easy-import ● postcss-url ● postcss-advanced-variables ● postcss-hexrgba ● postcss-color-function ● postcss-functions ● postcss-flexbugs-fixes ● postcss-nested ● postcss-extend-rule ● postcss-at-rules-variables ● postcss-property-lookup ● postcss-calc ● postcss-automath ● postcss-current-selector ● postcss-at-warn ● postcss-warn-cleaner
  • 27.
  • 28.
  • 29.
  • 30.
    Emotion Pros: - Popular CSS-in-JSframework - Excellent performance - Don't need to clutter JSX with styled components - Easiest migration path out of all CSS-in-JS frameworks - Supports composition, nested selectors and global styles - Supports server side rendering - Plays nice with legacy sass components Cons: - Docs not as good as something like styled components (bit better now)
  • 31.
    Emotion Finally agreed thiswas the path forward !
  • 32.
  • 33.
    Styled Components ● Agreednot to use import styled from '@emotion/styled' yet ... ○ Easier migration path to use css string styles (can automate some bits) ○ Less brain power required, using styled approach would need a re-architecture of the component being reworked (including JSX changes) ○ Less semantic in JSX if using styled ○ Disabling with eslint rule If this turns out to be too restrictive we can bring it back in the future - was a heated topic
  • 34.
  • 35.
    Server Side Rendering Emotion9 required mods to our internal tooling at the time to ensure css was inlined into HTML Emotion 10 has SSR work out of the box !!
  • 36.
  • 37.
  • 38.
    Theming Not ideal.. Needto manually pass in theme for each css
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
    CLI Migration Tool SASSto Emotion: https://github.com/DomainGroupOSS/sass-to-emotion
  • 46.
  • 47.
    Big wins ● Nomore style clashes if there is 2 majors in component tree (as emotion classname hash is content based) ● No more node-sass ! ● No need to worry about writing namespaced selectors ● Performance gains (faster bundling and faster runtime as there is less css bloat !)
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
    Annoyances Passing custom classnames to 3rd party components: ● Anti-pattern to doing this but sometimes it's necessary for 3rd party components ● Was ok to do in emotion 9, but cumbersome in 10 Emotion 9 Emotion 10
  • 53.
    Annoyances Critical CSS -ordering of style tags isn't necessary ideal for SSR critical css ?
  • 54.