Scope In CSS With and Without JavaScript

A presentation at Florida Drupalcamp 2020 in February 2020 in Orlando, FL, USA by Brian Perry

Slide 1

Slide 1

CSS has global scope.

Slide 2

Slide 2

Proprietary & Confidential 2

Slide 3

Slide 3

Proprietary & Confidential 3

Slide 4

Slide 4

BRIAN PERRY • Lead Front End Dev at Bounteous • Rocking the Chicago ‘burbs • Lover of all things components… …and Nintendo d.o: brianperry twitter: bricomedy github: backlineint nintendo: wabrian brianperryinteractive.com 4

Slide 5

Slide 5

5

Slide 6

Slide 6

CSS has global scope.

Slide 7

Slide 7

CSS has global scope. That’s great when you want rules to apply globally…

Slide 8

Slide 8

… and not so great when you don’t.

Slide 9

Slide 9

Many CSS in JavaScript solutions provide component scope.

Slide 10

Slide 10

CSS: global scope CSS-in-JS: component scope People disagree about these approaches… because… internet.

Slide 11

Slide 11

I think we should take advantage of both.

Slide 12

Slide 12

Thank You! Brian Perry Lead Front End Developer Email: brian.perry@bounteous.com

Slide 13

Slide 13

CSS has global scope.

Slide 14

Slide 14

CSS has global scope.

Slide 15

Slide 15

Codepen: https://codepen.io/brianperry/pen/rNNQpyK 15

Slide 16

Slide 16

THE CASCADE (THE C IN CSS) Stylesheets can have three different origins Image: https://www.miriamsuzanne.com/2019/10/03/css-is-weird/ 16

Slide 17

Slide 17

The way all rules are combined is very easy to understand and remember. Image: https://css-tricks.com/the-c-in-css-the-cascade/#article-header-id-11 17

Slide 18

Slide 18

CASCADING ORDER (ACCORDING TO W3C SPEC) • Find all declarations that apply to the element and property for the target media type. • Sort according to importance and origin (ascending order) • User agent declarations • User normal declarations • Author normal declarations • Author !important declarations • User !important declarations • Sort rules with same origin and importance by specificity • If all else fails, sort by order specified Source: https://www.w3.org/TR/CSS2/cascade.html#cascade 18

Slide 19

Slide 19

SPECIFICITY (Note: The universal selector and inherited selectors have a specificity of 0, 0, 0, 0) Source: https://stuffandnonsense.co.uk/archives/css_specificity_wars.html 19

Slide 20

Slide 20

20

Slide 21

Slide 21

CSS-in-JS can provide component scope …and other advantages.

Slide 22

Slide 22

WHY CSS-IN-JS? • Component scope – styles can’t ‘leak out’ • Co-locate styles with components • Positive developer experience • An advantage for distributed and composable components • Dead code elimination – bundler knows if css is being used • Worry free naming – don’t have to worry about conflicts or enforcing a naming convention • Respond to props rather than juggling class names • And yes, probably fear / lack of knowledge in some cases 22

Slide 23

Slide 23

AND WHY NOT? • You still need to know how CSS works (even the hard stuff) • Can come with a bundle size / performance cost • Potential barrier of entry for CSS experts who aren’t JS experts • Additional layers of abstraction • Some approaches use less css more object-like syntax • Potential syntax highlighting issues • Risk of inconsistency / one offs 23

Slide 24

Slide 24

So which approach is right?

Slide 25

Slide 25

Slide 26

Slide 26

Thank You! Brian Perry Lead Front End Developer Email: brian.perry@bounteous.com

Slide 27

Slide 27

CSS has global scope.

Slide 28

Slide 28

CSS has global scope.

Slide 29

Slide 29

HEY, REMEMBER CSS? Cascade Proprietary & Confidential Specificity Inheritance 29

Slide 30

Slide 30

Some of this is tricky. We should get our act together…

Slide 31

Slide 31

CSS METHODOLOGIES • Popular Methodologies • Object-Oriented CSS (OOCSS) • Block, Element, Modifier (BEM) • Scalable and Modular Architecture for CSS (SMACSS) • File organization • Naming conventions • Can create something that ‘feels’ like component scope. 31

Slide 32

Slide 32

BEM Concept: https://medium.com/@davehouse_80809/bem-for-everyone-else-89ccc8ad66f2 Codepen: https://codepen.io/brianperry/pen/BaaMYMJ 32 30

Slide 33

Slide 33

BEM IS GREAT! • Understandable structure that unifies markup and styles • Specific and component focused classes But… • In practice often like component scope, but not truly scoped to component • Not enforced at the tooling level • (sass-lint can help a bit here) • Requires discipline across dev team • Naming is still hard 38

Slide 34

Slide 34

CSS-in-JS can provide component scope.

Slide 35

Slide 35

COMPONENT SCOPE - STYLED COMPONENTS Source: https://www.cssinjsplayground.com/ 40

Slide 36

Slide 36

VUE SINGLE FILE COMPONENTS Source: https://codesandbox.io/s/vue-sfc-css-scope-m3ndm 44

Slide 37

Slide 37

You probably know what slide is coming next…

Slide 38

Slide 38

Slide 39

Slide 39

Thank You! Brian Perry Lead Front End Developer Email: brian.perry@bounteous.com

Slide 40

Slide 40

CSS has global scope.

Slide 41

Slide 41

CSS has global scope.

Slide 42

Slide 42

HEY, REMEMBER CSS AND BEM? Cascade Proprietary & Confidential Specificity Inheritance BEM 53

Slide 43

Slide 43

But can ‘regular’ CSS have component scope?

Slide 44

Slide 44

But can ‘regular’ CSS have component scope? Not really, but…

Slide 45

Slide 45

ATOMIC (FUNCTIONAL) CSS IS A THING • Small single purpose classes named based on visual function • Immutable CSS • Classes don’t change • Visual control shifts from CSS to markup • Approaches: • Static – pre-existing set of utility classes • Programmatic – CSS generated based on markup 56

Slide 46

Slide 46

TAILWIND A utility-first framework for rapidly building custom designs 57

Slide 47

Slide 47

I’LL BE HONEST… Some people love it, but to me it feels more like not using CSS… 58

Slide 48

Slide 48

CSS-in-JS can provide component scope.

Slide 49

Slide 49

But could CSS-in-JS be more like ‘regular’ CSS?

Slide 50

Slide 50

CSS MODULES • Not a package • Handled by a build process (typically Webpack) • Scopes styles locally by default • Can play nice with Sass • Ships with Create React App and Gatsby • Has a super snarky logo 61

Slide 51

Slide 51

SCOPED CSS – PROJECT CARD 62

Slide 52

Slide 52

63

Slide 53

Slide 53

64

Slide 54

Slide 54

SCOPED CLASS NAMES 65

Slide 55

Slide 55

Slide 56

Slide 56

GLOBAL CSS 67

Slide 57

Slide 57

STYLES SHARED BY MULTIPLE TEMPLATING ENGINES Drupal • Twig • Unique styles and components Combined • Global styles that apply to both. • Few (if any) shared React • JSX • Unique styles and components components Proprietary & Confidential 68

Slide 58

Slide 58

STYLES SHARED BY MULTIPLE TEMPLATING ENGINES Drupal • Global CSS file combines design system partials and Drupal specific partials React • Projects consume partials as needed • Imported in JS • Mix of global and component scope • Also project specific CSS Proprietary & Confidential 69

Slide 59

Slide 59

We can have both!

Slide 60

Slide 60

SEPARATION OF CONCERNS IS IN THE EYE OF THE BEHOLDER Source: https://speakerdeck.com/didoo/let-there-be-peace-on-css?slide=62 71

Slide 61

Slide 61

But could we have component scope with less JS?

Slide 62

Slide 62

POPULAR EXTENSIONS BECOME OFFICIAL • CSS Preprocessors influence CSS • CSS Custom Properties • CSS Nesting • Popular Drupal contrib projects make their way into core (I said Drupal, aren’t you proud?) • JSON:API • Panels Ecosystem -> Layout Builder • Babel lets you develop with cutting edge JS today • Transpile today, browser native tomorrow. 73

Slide 63

Slide 63

COULD WE SEE THE SAME FOR CSS SCOPE? • HTML Scoped Attribute… kind of didn’t happen. •

<style scoped> 74

Slide 64

Slide 64

COULD WE SEE THE SAME FOR CSS SCOPE? • Web Components / Shadow DOM as a solution? • Shadow DOM styles scoped locally by default. • Approaches also exist to use or selectively override global styles. • Still requires writing a decent amount of JS. 75

Slide 65

Slide 65

76

Slide 66

Slide 66

THANKS TO THE MANY CONTRIBUTORS… … • … 77

Slide 67

Slide 67

Thank You! Brian Perry Lead Front End Developer Email: brian.perry@bounteous.com