CSS Scoping Showdown

Story Time

You starting a web site and want to style this header

h1 {
    font-size: 1.5em;
    color: rebeccapurple;
}

<h1>My Title</h1>

But then you want to use an h1 somewhere else and it needs different styles.

So you give this one a class name.

.title {
    font-size: 1.5em;
    color: rebeccapurple;
}

<h1 class="title">My Title</h1>

Latter your system has grown and you want to add a title to some other component.

You forget about the first one and give the new one the class of title also.

.title {
    font-size: 1.5em;
    color: rebeccapurple;
    // more styles
}

<h1 class="title">My Title</h1>

// later you add this
.title {
    font-size: 1em;
    color: notpurple;
}

<h1 class="title" >Some Component Title</h1>

Node Tree

Body

Header

Main

Footer

Nav

Search

Login

Ordered  List
Unordered List
List Items

Form
Button

Form
Button

Content

Paragraph
Ordered List
Unordered List
List Items
Video
Form
Inputs
Img

Paragraph
Ordered List
Unordered List
List Items

How do styles cascade?

Body

Header

Main

Footer

Nav

Search

Login

Ordered  List
Unordered List
List Items

Form
Button

Form
Button

Content

Paragraph
Ordered List
Unordered List
List Items
Video
Form
Inputs
Img

Paragraph
Ordered List
Unordered List
List Items

.header {
    font-family: Arial;
}

Body

Header

Main

Footer

Nav

Search

Login

Ordered  List
Unordered List
List Items

Form
Button

Form
Button

Content

Paragraph
Ordered List
Unordered List
List Items
Video
Form
Inputs
Img

Paragraph
Ordered List
Unordered List
List Items

.header {
    font-family: Arial;
}

.login {
    font-family: Helvetica;
}

Body

Header

Main

Footer

Nav

Search

Login

Ordered  List
Unordered List
List Items

Form
Button

Form
Button

Content

Paragraph
Ordered List
Unordered List
List Items
Video
Form
Inputs
Img

Paragraph
Ordered List
Unordered List
List Items

body {
    font-family: Arial;
}

Global Styles

Body

Header

Main

Footer

Nav

Search

Login

Ordered  List
Unordered List
List Items

Form
Button

Form
Button

Content

Paragraph
Ordered List
Unordered List
List Items
Video
Form
Inputs
Img

Paragraph
Ordered List
Unordered List
List Items

p {
    font-family: Arial;
}

Global element selectors

Body

Header

Main

Footer

Nav

Search

Login

Ordered  List
Unordered List
List Items

Form
Button

Form
Button

Content

Paragraph
Ordered List
Unordered List
List Items
Video
Form
Inputs
Img

Paragraph
Ordered List
Unordered List
List Items

.title {
    // styles
}

Global class selectors

.title {
    // styles
}

Name collisions.

Pros

It's the place to normalize your styles

Cons

Styles applied here apply to everything.

Class Naming collision.

Global Styles

Normalization

  • Give sane defaults
  • Fix css bugs
  • Fix browser inconsistencies 

Put all normalizations in one place

And keep them minimal 

Gotchas

  • Its global, if you make a mistake it will propagate to the whole project.
  • Your's or other's assumptions might be wrong

How to scope your styles

  • Shadow DOM
  • BEM
  • CSS-Modules

Shadow DOM

A scoped container of JavaScript and CSS

Definition

How to

var shadow = someNode.createShadowRoot();
shadow.innerHTML = '<p>Here is some new text</p>';

Shadow DOM & CSS

Browser Support

Only in Chrome and Safari 10

Pros

Shadow DOM CSS can't affect global space

Cons

Can only style it externally through inheritance of the host 

Shadow DOM

BEM

(Block Element Modifier)

Class naming convention

block__element--modifier

  • Block: component of single piece of functionality
  • Element: an element of that component
  • Modifier: a modified instance of the block or element 

Pros

  • Great solution to the problem 

Cons

  • Really long class names
  • It's possible for there to be collisions if people aren't disciplined 

BEM

CSS-Modules

We scope our CSS to the components that use them. By hashing classes and class selectors when we bundle up the app.

// app.css

.title{
    //some style
}

1. Author your css strictly with class selectors

 

// app.js

import styles from "./app.css";

// will be a hash of the title class
styles.title 

2. Import those .css files into your .js files and compose them.

// app.css
.title_4hfkw{
    //some style
}

// app.js
import styles from "./app.css";

styles.title // title_4hfkw

3. CSS Modules Converts the class names in both places to unique hashes.

Pros

  • CSS is scoped to where you want it
  • Can blissfully author your class names 

Cons

  • Have to set up css-modules(webpack)
  • Dictates how you author your css

CSS-Modules

You get Webpack for free in the JS starter

npm i -g ldsjs --registry http://icsnpm.ldschurch.org

Note: CSS-Modules does hash animation names

References 

CSS Scoping Showdown

By Matthew Poulson

CSS Scoping Showdown

  • 632