You Might Not Need SCSS

A presentation at SydCSS in February 2019 in Sydney NSW, Australia by Ben Buchanan (200ok)

Slide 1

Slide 1

You might not need SCSS Ben Buchanan weblog.200ok.com.au Presented at SydCSS, 2019.02.07

Slide 2

Slide 2

SCSS is awesome! Appeared in 2006 Popular Works everywhere* * that you care about

Slide 3

Slide 3

SCSS is the jQuery of CSS youmightnotneedjquery.com appeared in 2014 Are we even asking the question about SCSS?

Slide 4

Slide 4

Slide 5

Slide 5

Slide 6

Slide 6

Qbit private API HTML CSS ES6 Qbit Public API Templates (Angular, React) SCSS variables JSON design tokens

Slide 7

Slide 7

Qbit private API HTML CSS ES6 Qbit Public API Templates (Angular, React) SCSS variables CSS custom props JSON design tokens

Slide 8

Slide 8

The place SCSS has in our stack

Slide 9

Slide 9

SCSS is awesome at compile time Variables Calculations Mixins Style APIs via !default Bundling Minification Prefix management

Slide 10

Slide 10

Detailed list of SCSS runtime features

Slide 11

Slide 11

SCSS as style API Provides error handling :) Precompiled modifications only :-/ Imposes dependencies & stack choice on consumer :(

Slide 12

Slide 12

SCSS for themes

Slide 13

Slide 13

Slide 14

Slide 14

I wanted a better way Lighter payload Native portability Runtime features

Slide 15

Slide 15

CSS Custom Properties & Calc()

Slide 16

Slide 16

Custom properties they’re really not variables affected by inheritance and the cascade

Slide 17

Slide 17

Custom prop basics :root { —colour-brand: #f00; } button { background: var(—colour-brand); }

Slide 18

Slide 18

Get/Set with JS // DOM elements const $el = document.getElementById(‘target’); const $root = document.documentElement; // Get window.getComputedStyle($el).getPropertyValue(“—color”); // Set $el.style.setProperty(‘—color’, ‘black’);

Slide 19

Slide 19

Themes / Colour Schemes

Slide 20

Slide 20

Theme by resource theme-red.css :root { —colour-brand: #f00; } theme-blue.css :root { —colour-brand: #00f; } base.css button { background: var(—colour-brand); }

Slide 21

Slide 21

Theme by selector .theme1 { —colour-brand: #f00; } .theme2 { —colour-brand: #00f; }

<body class=”theme1”> <button>Red</button> </body> <button class=”theme1”> Red </button> <button class=”theme2”> Blue </button>

Slide 22

Slide 22

SCSS component vars /* core var / $colour-brand: #f00 !default; / component var */ $colour-button: $colour-brand !default; button { background: $colour-button; }

Slide 23

Slide 23

CSS component props /* set a default / :root { —colour-button: var(—colour-brand); } / component var needs a boost. */ .theme1, .theme2 { —colour-button: var(—colour-brand); }

Slide 24

Slide 24

But you don’t need it! .my-custom-theme { —colour-brand: #0f0; } .my-custom-theme button { —colour-brand: #00f; }

Slide 25

Slide 25

Remember SCSS payloads?

Slide 26

Slide 26

Slide 27

Slide 27

CSS variable payload

Slide 28

Slide 28

CSS variable payload SCSS variable payloads

Slide 29

Slide 29

calc() :root { —header-height: calc(var(—grid-unit) * 12); }

Slide 30

Slide 30

calc() voodoo header { height: 50px; } main { height: calc(100% - 50px); } Mixed units.

Slide 31

Slide 31

Tip: negative values calc(valueYouNeedToBeNegative * -1)

Slide 32

Slide 32

Gotcha: dang browsers Some calculations fall foul of browser variation. SCSS is at least normalised calculation.

Slide 33

Slide 33

90% of the effort is in the last 10%

Slide 34

Slide 34

Think of the childrenIE11 childrenIE11 Calc: supported but buggy Custom Props: no support

Slide 35

Slide 35

PostCSS to the rescue! postcss([ postCSSCustomProperties({ importFrom: ‘./dist/css-variables.css’ }), postCSSCalc() ])) .selector { margin-top: 40px; margin-top: calc(var(—space-l) * 1.25); }

Slide 36

Slide 36

A choice

  1. Put up with IE11 bloat in your CSS 2. Serve IE11 its own CSS

Slide 37

Slide 37

Heresy alert! var ua = navigator.userAgent; var uamatch = ua.match(/(msie|trident(?=/))/?\s*([\d.]+)/i) || []; if(/trident/i.test(uamatch[1]) && parseInt(/\brv[ :]+(\d+)/g.exec(ua)[1], 10) === 11) { document.querySelector(‘head’).innerHTML += ‘<link rel=”stylesheet” href=”ie11.css” type }  Available at https://bitbucket.org/snippets/200ok 

Slide 38

Slide 38

What I really missed… was errors Error: Undefined variable: “$button-border-widht”. on line 31 of path/to/button.scss from line 8 of path/to/qbit-all.scss >> -width: #{$button-border-widht}; ———————————————-^

Slide 39

Slide 39

What I really missed… was errors .selector { color: var(—colour-that-does-not-exist); } This was really hard to debug.

Slide 40

Slide 40

Stylelint to the rescue! gulpStylelint “plugins”: [ “stylelint-scss”, “stylelint-value-no-unknown-custom-properties” ]

Slide 41

Slide 41

Stylelint to the rescue! gulpStylelint path/to/component.css 85:18 ✖ Unexpected custom property “—colour-hoover” inside declaration “color”.

Slide 42

Slide 42

Do we still need SCSS?

Slide 43

Slide 43

CSS Variables Calculations Runtime power Many tools Bundling Concatenation Postprocessing Linting/errors SCSS Mixins Loops

Slide 44

Slide 44

Demand native specs! Mixins Loops CSS require

Slide 45

Slide 45

You might still use SCSS… …for massive projects …because it’s still right for you

Slide 46

Slide 46

You might not need SCSS… …in your API …for small projects

Slide 47

Slide 47

Thank you.