Cascading & Inheritance
Miriam Suzanne
@
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>
💥 Conflict!
[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
- filtering
->
declared values?
- cascading
->
cascaded value?
- defaulting
->
specified value
- resolving
->
computed value
- formatting
->
used value?
- 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 style
s are explicit
The Highest 🎯 Specificity
- Inline
style
s
- Unique
ID
s
- Reusable
class
es & attributes
- Inline
style
s
- Unique
ID
s
- Reusable
class
es & attributes
- Element
type
s
- Inline
style
s
- Unique
ID
s
- Reusable
class
es & attributes
- Element
type
s
- Universal
*
Often Represented by Numbers
Using Factors of 10
(but I don’t recommend it)
1000
– Inline style
s
100
– Unique ID
s
10
– Reusable class
es & attributes
1
– Element type
s
0
– Universal *
button.action[type=“submit”] * { … }
10
*
10
!=
100
By That Logic…
.class.class.class.class.class
.class.class.class.class.class { … }
#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
More Like Versioning
v3.462.5
More Like Versioning
v3.462.5 <
v4.0
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
Move on When Tied
1.12.2 or
1.3.42
Move on When Tied
1.12.2 or
1.3.42
Ideally…
A Layering System
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
Some Limitations
👎 Too Few Layers
Use combinations!
👎 Only Classes & Attributes
Are Customized AND Reusable
👎 Selector Double-Duty
As hooks & weights
👍 It’s Super Clever
👍 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/
view
» page styles
» no style
all:
revert
Not all:
initial
see also * { all: initial !important; }
👥 User Styles
aka
Preferences
usually not CSS, but treated the same
(user preference demo)
🎨 Author Styles
aka
Document Styles
absolutely everything we write
Stacked in Layers
- 🎨 Author
- 👥 User
- 🖥 User Agent
Like 🎯 Specificity
Highest 🗺 Origin Wins
- 🎨 Author Styles
- 👥 User Preferences
- 🖥 User Agent Defaults
?!?!?
If conflicts arise the user should have the last word
–
Håkon Lie
?!?!?
What Gives!?
The Real Reason For
❗importance
When anyone adds…
!important
- ❗🖥 User Agent Important
- ❗👥 User Important
- ❗🎨 Author Important
- 🎨 Author Styles
- 👥 User Preferences
- 🖥 User Agent Defaults
- ❗🖥 User Agent Important
- ❗👥 User Important
- ❗🎨 Author Important
- 🎨 Author Styles
- 👥 User Preferences
- 🖥 User Agent Defaults
- ❗🖥 User Agent Important
- ❗👥 User Important
- ❗🎨 Author Important
- 🎨 Author Styles
- 👥 User Preferences
- 🖥 User Agent Defaults
- ❗🖥 User Agent Important
- ❗👥 User Important
- ❗🎨 Author Important
- 🎨 Author Styles
- 👥 User Preferences
- 🖥 User Agent Defaults
Feels Like Specificity
🐢layers all the way down…
A Few Special Origins
- ❗🖥 User Agent Important
- ❗👥 User Important
- ❗🎨 Author Important
- 🏇🏽 Animations
- 🎨 Author Styles
- 👥 User Preferences
- 🖥 User Agent Defaults
- 🎠 Transitions
- ❗🖥 User Agent Important
- ❗👥 User Important
- ❗🎨 Author Important
- 🏇🏽 Animations
- 🎨 Author Styles
- 👥 User Preferences
- 🖥 User Agent Defaults
Where the 🌊 Cascade Starts
In Theory & Practice
- 🗺 Origin & ❗importance
- 🎯 Selector Specificity
- ⏭ Source Order
The 🌊 Cascade
Isn’t Only About Us
Because The Web
Isn’t Only About Us
- 🗺 Origin & ❗importance
- 🎠 Transitions
- ❗🖥 User Agent Important
- ❗👥 User Important
- ❗🎨 Author Important
- 🏇🏽 Animations
- 🎨 Author Styles
- 👥 User Preferences
- 🖥 User Agent Defaults
- 🎯 Selector Specificity
- ⏭ Source Order
- 🗺 Origin & ❗importance
- 🎠 Transitions
- ❗🖥 User Agent Important
- ❗👥 User Important
- ❗🎨 Author Important
- 🏇🏽 Animations
- 🎨 Author Styles
- 👥 User Preferences
- 🖥 User Agent Defaults
- 🎯 Selector Specificity
- ⏭ Source Order
- Origin: 🎨 Author Styles
- 🎯 Selector Specificity
- ⏭ Source Order
- Origin: 🎨 Author Styles
- Inline Styles
- IDs
- Classes & Attributes
- Elements
- Universal
*
- Origin: 🎨 Author Styles
- Inline Styles
- IDs
- Classes & Attributes
- Elements
- Universal
*
If there are still options…
The ⏭ Final Value Wins
- 🗺 Origin & ❗importance
- 🎯 Selector Specificity
- ⏭ Source Order
- Origin: 🎨 Author Styles
- Specificity: Classes & Attributes
- ⏭ Source Order
The 🌊 Cascade
Filters Out Extra Values
🧬 Inheritance
Fills In Missing Values
- filtering
->
declared values?
- cascading
->
cascaded value?
- defaulting
->
specified value
- resolving
->
computed value
- formatting
->
used value?
- constraining
->
actual value?
Sometimes 🧬 Inheritance
And Sometimes Initial
Values
Generally…
Text Styles Inherit
Box Styles Don’t
🌊 Cascade
Is The Solid Architecture
🧬 Inheritance
Is What’s Left Open
🧬 Inheritance
Happens Last
🎯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
And…
How ❗Important They Are
Then…
What They 🎯 Target
And…
Finally The ⏭ Order
Then…
🧬 Fill Any Gaps
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
😬
Multiple Solutions
Authors Should
Learn To Use The Full Cascade
👍 #IDs are Good
When they
Express Meaning & Intent
👍 Nesting is Good
(We’ll come back to this in more detail)
W3C Should
Update & Extend The Cascade
More 🎯 Nuance
e.g. :where()
“scoped” styles?
Custom Elements
& Web Components
Custom Author Origins?
¯\_(ツ)_/¯
The Cascade is Important
The Cascade is Useful
The Cascade is
Not Going Away
Learn To Use It
@MiriSuzanne
#ResilientWebSystems