slides.oddbird.net/rws/smashing/cascade/

Cascading & Inheritance

slides.oddbird.net/rws/smashing/cascade/

@ Smashing Online

CSS is a System For Applying Styles
to Elements

The proposed scheme provides a simple mapping between HTML elements and presentation hints.

– Håkon Lie

Inline with HTML

<button style=
background: rebeccapurple;
color: white;
font: inherit;
padding: 0 1em;
>
</button>
<button style=“background: rebeccapurple;  ></button>
<button style=“background: rebeccapurple; ></button>
<button style=“background: rebeccapurple; ></button>
<button style=“background: rebeccapurple; ></button>
<button style=“background: rebeccapurple; ></button>
<button style=“background: rebeccapurple; ></button>

Selector “Hooks”

button {
background: rebeccapurple;
}
<button></button>

Selectors come in Four Basic Categories

Universal *

* {}
<form>
<button></button>
</form>

Element Types

button {}
<button></button>

Classes & Attributes

.action {}
[type=“submit”] {}
<button class=“action” type=“submit”></button>

Unique IDs

#send {}
<button id=“send”></button>

We Can Combine Them

#send > button.action[type=“submit”] {}
<form id=“send”>
<button class=“action” type=“submit”></button>
</form>

We Can Stack Them

button {}
.action {
[type=“submit”]
{}
#send {}
<button id=“send” class=“action” type=“submit”></button>

These Are Powerful Features!

combine & layer selectors to convey meaning & intent

It’s also why We Need a 🌊 Cascade

button          { background: gray; }
.action { background: darkblue; }
[type=“submit”] { background: darkgreen;
background: var(--submit); }
#send { background: maroon; }
<button    style=“background: darkviolet;”
id=“send” class=“action” type=“submit”>
</button>
[type=“submit”] { background: darkgreen;
background: var(--submit); }
<button></button>

💥 OMG Mutliple background
On The Same <button>

For Browsers… Every Property
of Every Element
Must Have a Single Value

A <button> Needs One Background-Color
& One Text Color
& One Padding-Left
& One Margin-Bottom
&

The 🌊 Cascade Resolves 💥 Value Conflicts

  1. filtering -> declared values?
  2. cascading -> cascaded value?
  3. defaulting -> specified value
  4. resolving -> computed value
  5. formatting -> used value?
  6. constraining -> actual value?

For Each Element in the DOM

e.g. button or paragraph

And Each Available CSS Property

e.g. background-color or margin-left

1. Filtering… Are Values Explicitly Defined?

2. Cascading (if multiple)… Which Has the Most Weight?

3. Defaulting (if none)… Find a Fallback Value!

Either inheritance, or the property default

4–6 Calculate Final Values… Based on Context & Layout

How many px is 50% in this case?

We Often Talk About Selectors & 🎯 Specificity

Where We Have Control

button          { background: gray; }
.action { background: darkblue; }
[type=“submit”] { background: darkgreen;
background: var(--submit); }
#send { background: maroon; }

Each Selector has a Weight Based on How Specific It Is

Inline styles are explicit The Highest 🎯 Specificity

  1. Inline styles
  2. Unique IDs
  3. Reusable classes & attributes
  1. Inline styles
  2. Unique IDs
  3. Reusable classes & attributes
  4. Element types
  1. Inline styles
  2. Unique IDs
  3. Reusable classes & attributes
  4. Element types
  5. Universal *

Often Represented by Numbers Using Factors of 10

(but I don’t recommend it)

  • 1000 – Inline styles
  • 100 – Unique IDs
  • 10 – Reusable classes & attributes
  • 1 – Element types
  • 0 – Universal *
/* 1  +  10  +     10      + 0  == 21 */
button.action[type=“submit”] * {}

By That Logic

/* 10 +  10 +  10 +  10 +  10 +
10 + 10 + 10 + 10 + 10 = 100 */

.class.class.class.class.class
.class.class.class.class.class
{}

/* 100 = 100 */
#id {}

👎 Don’t Bother

small numbers are easier

More Like Versioning v3.9.5

More Like Versioning v3.10.5

More Like Versioning v3.11.5

Only the First Number Matters 2.5.1 or 1.12.2 or 1.3.42

Only the First Number Matters 2.5.1 or 1.12.2 or 1.3.42

From… Broad Patterns
to Specific Overrides

Different Intents

  • universal/type » Reset / Normalizer
  • type/attr » Initial Defaults
  • attrs » Common Patterns
  • attrs » Page Layouts
  • attr > attr » Components
  • ID » Overrides

👎 Too Few Layers

Use combinations!

👎 Only Classes & Attributes Are Customized AND Reusable

👎 Selector Double-Duty

As hooks & weights

👍 It’s Super Clever 👎 But It’s Way Too Clever

Anyway… 🌊 Cascade >>> 🎯 Specificity

Style sheets can be cascaded; the user/browser specifies initial preferences and hands the remaining influence over…

– Håkon Lie

… It provides author and reader with the same notation…

– Håkon Lie

The 🌊 Cascade starts with A List of Stylesheets

applied to the same document…

Potentially From Different 🗺 Origins

🖥 User Agent (Browser), 👥 User, or 🎨 Author

🖥 User Agent Styles
aka Browser Defaults

resource://gre-resources/

all: revert Not all: initial

see also * { all: initial !important; }

👥 User Styles
aka Preferences

usually not CSS, but treated the same

🎨 Author Styles
aka Document Styles

absolutely everything we write

Stacked in Layers

  1. 🎨 Author
  2. 👥 User
  3. 🖥 User Agent

Like 🎯 Specificity Highest 🗺 Origin Wins

  1. 🎨 Author Styles
  2. 👥 User Preferences
  3. 🖥 User Agent Defaults

If conflicts arise the user should have the last word

– Håkon Lie

The Real Reason Forimportance

  1. ❗🖥 User Agent Important
  2. ❗👥 User Important
  3. ❗🎨 Author Important
  4. 🎨 Author Styles
  5. 👥 User Preferences
  6. 🖥 User Agent Defaults
  1. ❗🖥 User Agent Important
  2. ❗👥 User Important
  3. ❗🎨 Author Important
  4. 🎨 Author Styles
  5. 👥 User Preferences
  6. 🖥 User Agent Defaults
  1. ❗🖥 User Agent Important
  2. ❗👥 User Important
  3. ❗🎨 Author Important
  4. 🎨 Author Styles
  5. 👥 User Preferences
  6. 🖥 User Agent Defaults
  1. ❗🖥 User Agent Important
  2. ❗👥 User Important
  3. ❗🎨 Author Important
  4. 🎨 Author Styles
  5. 👥 User Preferences
  6. 🖥 User Agent Defaults

Feels Like Specificity

🐢layers all the way down…

  1. ❗🖥 User Agent Important
  2. ❗👥 User Important
  3. ❗🎨 Author Important
  4. 🏇🏽 Animations
  5. 🎨 Author Styles
  6. 👥 User Preferences
  7. 🖥 User Agent Defaults
  1. 🎠 Transitions
  2. ❗🖥 User Agent Important
  3. ❗👥 User Important
  4. ❗🎨 Author Important
  5. 🏇🏽 Animations
  6. 🎨 Author Styles
  7. 👥 User Preferences
  8. 🖥 User Agent Defaults

Where the 🌊 Cascade Starts In Theory & Practice

  1. 🗺 Origin &importance
  2. 🎯 Selector Specificity
  3. ⏭ Source Order

The 🌊 Cascade Isn’t Only About Us

  1. 🗺 Origin &importance
    1. 🎠 Transitions
    2. ❗🖥 User Agent Important
    3. ❗👥 User Important
    4. ❗🎨 Author Important
    5. 🏇🏽 Animations
    6. 🎨 Author Styles
    7. 👥 User Preferences
    8. 🖥 User Agent Defaults
  2. 🎯 Selector Specificity
  3. ⏭ Source Order
  1. 🗺 Origin &importance
    1. 🎠 Transitions
    2. ❗🖥 User Agent Important
    3. ❗👥 User Important
    4. ❗🎨 Author Important
    5. 🏇🏽 Animations
    6. 🎨 Author Styles
    7. 👥 User Preferences
    8. 🖥 User Agent Defaults
  2. 🎯 Selector Specificity
  3. ⏭ Source Order
  1. Origin: 🎨 Author Styles
    1. 🎯 Selector Specificity
    2. ⏭ Source Order
  1. Origin: 🎨 Author Styles
    1. Inline Styles
    2. IDs
    3. Classes & Attributes
    4. Elements
    5. Universal *
  1. Origin: 🎨 Author Styles
    1. Inline Styles
    2. IDs
    3. Classes & Attributes
    4. Elements
    5. Universal *

If there are still options… The ⏭ Final Value Wins

  1. 🗺 Origin &importance
  2. 🎯 Selector Specificity
  3. ⏭ Source Order
  1. Origin: 🎨 Author Styles
    1. Specificity: Classes & Attributes
      1. ⏭ Source Order

The 🌊 Cascade Filters Out Extra Values

🧬 Inheritance Fills In Missing Values

  1. filtering -> declared values?
  2. cascading -> cascaded value?
  3. defaulting -> specified value
  4. resolving -> computed value
  5. formatting -> used value?
  6. constraining -> actual value?

Sometimes 🧬 Inheritance And Sometimes Initial Values

Generally… Text Styles Inherit
Box Styles Don’t

🎯Specified Values Can Get There First

🧬 Inherited Values Don’t Care About Specificity

🧬 Inherited Values Only Care About Proximity

So We Filter Based On… 🗺 Where Sheets Come From

A Wider 🌊 Cascade Allows More Nuance in Layering

Conventions like BEM Flatten 🌊 The Cascade

(every selector is a single class)

When Frameworks Often Automate Source Order

Authors Should Learn To Use The Full Cascade

(We’ll come back to this in more detail)

“scoped” styles? Custom Elements
& Web Components