0% found this document useful (0 votes)
6 views

CSS Overview

Uploaded by

Danh
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views

CSS Overview

Uploaded by

Danh
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 390

CSS Overview

Selectors, Integration, Inheritance, Cascading

R. Scott Granneman r Jans Carton

© 2009 R. Scott Granneman


Last updated 2021-08-16
You are free to use this work, with certain restrictions.
2.8 For full licensing information, please see the last slide/page.
Notes & URLs for this presentation can be found…

» underneath the link to this slide show on


granneman.com
» at files.granneman.com/presentations/webdev/CSS-
Overview.txt
History
CSS 1: December 1996

CSS 2: May 1998

CSS 2.1: July 2007

CSS 3: June 1999–Now

CSS 4: 2012–Now
CSS 1 & 2 each were one big document

CSS 3 (& 4) is not one large single spec

Instead, it’s divided into many separate documents


called modules
Currently 50+ modules!

Different modules have different statuses

www.w3.org/Style/CSS/current-work
W3C CSS Working Group: Colors & Status Codes
Why CSS?
95.5% of all websites use CSS

Why?

As of September 2020
Separation of Concerns

Divide computer program into separate concerns, each


focusing on a specific resource

Meaning: HTML

Presentation: CSS

Behavior: JavaScript
Separate content (HTML) from presentation (CSS)
Site-wide consistency: control how all content looks
using only 1 (or a few) CSS file/s
Apply different styles to same content in different
media:

» desktop web browser


» mobile web browser
» auditory
» print
» & more!
Adherence to standards
🎉 🎊 🥳 👯🕺
It’s fun!
Integrating
CSS
4 ways to connect your HTML with your CSS

1. Inline styles
2. Embedded styles
3. Linking to external styles

4. @import
Inline
Uses the style global attribute
Quick & easy to create, but difficult & time-consuming
to manage

Must repeat over and over

Can’t change the style according to the media, so styles


apply to all media

Doesn’t separate content & presentation


So why use it?

Testing (use the Inspector instead)

Use inline styles for unique instances (very rare!)

High specificity: overrides conflicting declaration (only when


absolutely necessary!)

JavaScript often uses inline styles to apply styles dynamically

HTML email
Embedded
Styles inserted inside <style> … </style>

Most often in the <head>, but can be found anywhere in


the <body>
Embedded styles are great for one page …

… but they rapidly become difficult to manage on


multiple pages
So why use it?

Resource inlining: embedding reduces outbound


requests (so does inline CSS)

Portability: You have a widget that may get embedded


into another webpage on another site

To style the widget, you include embedded styles with it


inside <style> … </style>
Linking
HTML 4.01

<head>
<link rel="stylesheet" type="text/css"
href="/css/main.css">
</head>

HTML 5

<head>
<link rel="stylesheet" href="/css/main.css">
</head>
Start with a basic project 1
Create a css folder 2
Create /css/main.css 3
Link to /css/main.css 4
What should you name your CSS file?

It doesn’t matter

main.css
typography.css
client.css
search.css
navigation.css
Where should you place your CSS file?

In your website’s root directory, (almost) always create


these directories:

css (or styles)


fonts
images (or media)
js (or scripts)
A CSS file is made up of rulesets & comments

/* Common */
blockquote, p, td {
font-family: Verdana, sans-serif;
font-size: 1em;
}

#footer {
font-size: .9em;
}

.emphasis {
font-weight: bold;
}
You can link to more than one style sheet, but you
should try to keep those links to a minimum
If you have more than one webpage, you really ought to
use an external style sheet

You can now change the look & behavior of an entire


site by changing only one document!
✏ SIDE NOTE

You might see advice telling you to add this as the 1st
line of your style sheet so the browser knows that
main.css is encoded as UTF-8:

@charset "utf-8";

This is not correct & can be ignored


✏ SIDE NOTE
In CSS 2.1, browsers try to figure out if main.css is
UTF-8 using this order (& stop at the 1st match):

1. Unicode byte-order character at beginning of main.css


2. Value given by charset attribute of Content-Type:
HTTP header or equivalent in protocol used to serve
the style sheet
3. @charset CSS at-rule
4. Value of the charset attribute of <link> in the HTML;
now obsolete in HTML5 & not to be used
5. Assume the document is UTF-8 (!)
✏ SIDE NOTE

“However, there is no actual at-rule named @charset.


When a stylesheet is actually parsed, any occurrences
of an @charset rule must be treated as an
unrecognized rule, and thus dropped as invalid when
the stylesheet is grammar-checked.

Note: In CSS 2.1, @charset was a valid rule. Some


legacy specs may still refer to a @charset rule, and
explicitly talk about its presence in the stylesheet.” —
W3C, 2019
✏ SIDE NOTE

In CSS Syntax Module Level 3 (W3C Candidate


Recommendation, 16 July 2019), this is the order:

1. Value given by charset attribute of Content-Type:


HTTP header or equivalent in protocol used to serve
the style sheet
2. Unicode byte-order character at beginning of
main.css
3. Environment encoding (which should not be used)
4. Assume the document is UTF-8
✏ SIDE NOTE

So, as long as you have Visual Studio Code or another


editor set to save all files as UTF-8 automatically (which
is the default, as it should be!), you are covered
@import
💡PRO TIP

If you have used @import with a CSS preprocessor like


Sass or Less, @import here is different & will cause a
server call
@import allows you to include external stylesheets in
your CSS; in other words, it allows you to link to
another CSS file from within a CSS file (yes, this is a
little weird)

@import must always come 1st, ahead of any other CSS


import.css included via @import
Put @import 1st so it can be overridden
Don’t use it unless you absolutely need to use it, as it
can slow down your page loads*

* Unless you are using a build system like SCSS; more on that in CSS - Preprocessors
✏ SIDE NOTE

Delay User Perception

0–100 ms Instant

100–300 ms Small perceptible delay

300–1,000 ms Machine is working

1,000+ ms Likely mental context switch

10,000+ ms Task abandoned


The Browser
Processing
Pipeline
HTML DOM

JavaScript Render Tree Layout Paint

CSS CSSOM
To understand CSS, you have to understand

» the DOM (Document Object Model)


» the CSSOM (CSS Object Model)
» the browser processing pipeline
The DOM
“A conceptual model is a representation of a system,
made of the composition of concepts which are used to
help people know, understand, or simulate a subject
the model represents.” —Wikipedia

We often illustrate conceptual models of both tangible


& intangible things so we can better understand them
Maslow’s
Hierarchy of
Needs
Bloom’s
Taxonomy of
educational
learning
objectives
U.S. Army
adaptation of
Data
Information
Knowledge
Wisdom
Pyramid
Atomic nucleus
composed of
neutrons (blue)
& protons (red)
Carbon atom,
with electron
cloud around
nucleus
Different models for a
water molecule (an
electrically neutral
group of 2 or more
atoms held together
by chemical bonds)
3D schematic
representation
of a sucrose
(sugar) mole-
cule, with atoms
of carbon
(black), oxygen
(red), & hydro-
gen (white)
Animal cell,
made up of
molecules,
which contain
millions or even
trillions of
atoms
Cells, ducts, &
blood vessels in
part of a
mammalian
liver lobule
Major systemic arteries in
the human body
HTML DOM

JavaScript Render Tree Layout Paint

CSS CSSOM
Before a webpage appears in a viewport, the rendering
engine downloads the HTML & parses it to figure out
how to display the webpage on screen

During this process, the rendering engine creates the


DOM tree
“A Web page is a document. This document can be
either displayed in the browser window, or as the
HTML source. But it is the same document in both
cases.

The Document Object Model (DOM) provides another


way to represent, store and manipulate that same
document. The DOM is a fully object-oriented
representation of the web page, and it can be
modified with … JavaScript.” —Mozilla Developer
Network
What’s the DOM?

A JavaScript developer will say, “It’s a JavaScript


interface so that I can manipulate the page”

A CSS developer will say, “It’s a set of boxes to style”

An HTML developer will say, “It’s hierarchy & meaning”

They are all correct!


When is the DOM different than your HTML?
If you have mistakes in your HTML, the rendering
engine “fixes” them when it generates the DOM
Source Code
DOM as rendered by browser Inspector
Source Code

No <tbody>
<tbody> added

Rendered DOM
<table> <table>
<tr> <tbody>
<td>Foo</td> <tr>
<td>Bar</td> <td>Foo</td>
</tr> <td>Bar</td>
<tr> </tr>
<td>Baz</td> <tr>
<td>Qux</td> <td>Baz</td>
</tr> <td>Qux</td>
</table> </tr>
</tbody>
</table>

Source code DOM tree


DOM tree
as org chart

Each box you see


here is a DOM node
DOM tree as nested boxes, each one a node
DOM tree as HTML elements,
each one a node, with <html>
<html> as the document root
<head> … </head>
<body>
<header> … </header>
<main>
<h1>The Call of Cthulhu</h1>
<p>Ph’nglui Cthulhu R’lyeh!</p>
</main>
<footer> … </footer>
</body>
</html>
Firefox up to version 47 had a cool feature called 3D
View that let you “rotate and re-orient the 3D
presentation of the DOM hierarchy of your page to see
it from different angles”
The CSSOM
HTML DOM

JavaScript Render Tree Layout Paint

CSS CSSOM
The CSSOM is built by the rendering engine using
specified stylesheet rules from:

» built-in rules that come with the browser


» rules added by user
» rules created by CSS authors (developers)
Bringing It All
Together
HTML DOM

JavaScript Render Tree Layout Paint

CSS CSSOM

JavaScript can change the DOM & the CSSOM


The combination of the DOM, CSSOM, & JavaScript
means that webpages are dynamic because
JavaScript can:

» add, change, & remove any DOM elements &


attributes
» change any CSSOM styles
» react to all existing events
» create new events
As of July 2020, there are 69 Web APIs
Ambient Light Events • Background Tasks • Battery • Beacon • Bluetooth •
Broadcast Channel • CSS Counter Styles • CSS Font Loading • CSSOM •
Canvas • Channel Messaging • Console • Credential Management • DOM •
Encoding • Encrypted Media Extensions • Fetch • File System • Frame Timing
• Fullscreen • Gamepad • Geolocation • HTML Drag and Drop • High
Resolution Time • History • Image Capture • IndexedDB • Intersection
Observer • Long Tasks • Media Capabilities • Media Capture and Streams •
Media Session • Media Source Extensions • MediaStream Recording •
Navigation Timing • Network Information • Page Visibility • Payment
Request • Performance • Performance Timeline • Permissions • Pointer
Events • Pointer Lock • Proximity Events • Push • Resize Observer • Resource
Timing • Server Sent Events • Service Workers • Storage • Storage Access •
Streams • Touch Events • URL • Vibration • Visual Viewport • Web
Animations • Web Audio • Web Authentication • Web Crypto • Web
Notifications • Web Storage • Web Workers • WebGL • WebRTC • WebVR •
WebVTT • WebXR Device • Websockets
HTML DOM

JavaScript Render Tree Layout Paint

CSS CSSOM

The rendering engine matches HTML element objects


with CSS rule objects to generate the Render Tree
HTML DOM

JavaScript Render Tree Layout Paint

CSS CSSOM

The rendering engine uses the Render Tree to layout


boxes in the viewport
HTML DOM

JavaScript Render Tree Layout Paint

CSS CSSOM

The rendering engine displays (paints) all the content


of the page in the viewport, from back to front
Events

HTML DOM

JavaScript Render Tree Layout Paint

CSS CSSOM

JavaScript events can further change the DOM & the CSSOM
The big takeaway: when you’re working with CSS, you
are manipulating objects that will be rendered as boxes
Basic
Selectors
A CSS selector declares which DOM objects should
have particular styles applied to them

The browser’s rendering engine…


» parses the CSS & HTML
» matches selectors to the appropriate DOM objects
» applies the CSS style to the rendered DOM objects
HTML CSS
<h1 align="center"> h1 {text-align: center;}
Entire thing is a tag Entire thing is a style rule
h1 is an element h1 is a selector
align is an attribute text-align is a property
center is a value center is a value
align="center" is an text-align: center is a
attribute-value pair declaration
Everything inside { & } is a
declaration block
CSS 1: 10 different selectors (including selectors,
combinators, pseudo-classes, & pseudo-elements)

CSS 2: 13

CSS 3: 21

CSS 4: 26 (so far!)

70 in total
1. Simple selectors 3. Complex selectors with
combinators
» Universal
» Type » Descendant
» Class » Child
» ID » Adjacent sibling
» Pseudo-classes » General sibling
» Pseudo-elements
» Attribute 4. Selector list

2. Compound selectors
Simple Selectors
A simple selector describes a single condition on an
element

If the condition is true, the element is selected

* (universal): Is this an element?


element: Is this the specific type of element?
.class: Does this element have this class on it?
#ID: Does this element have this ID on it?
Universal
*

Selects every HTML element

(Though later CSS rules can override these


declarations)
Type
element

Selects every matching HTML element (e.g., <p>, <ul>,


or <h3>)

AKA Element Selectors

Used when you want to affect every instance of an


element
Class
.class

Selects any element to which the class has been applied,


as many times per page as needed

HTML:
<p class="intro">…</p>

CSS:
.intro {
font-weight: bold;
}
Dot in front of the class name
in CSS, but no dot in HTML

Dot labels the class in CSS

The class attribute labels the


element in HTML
The paragraph with class
applied to it is different from
the paragraph that does not
have that class
A class can be applied as many
times per page as you wish
You can use multiple (2, 3, 4, whatever) classes on an
element when needed
✏ SIDE NOTE

A student once did this:

<figcaption class="center" class="image-


caption"> 🤨

This will not work! No duplicate attributes!

You must use:

<figcaption class="center image-caption">


✏ SIDE NOTE

How do you match an element that has a particular


combination of classes on it?

<p class="center note">

See Compound Selectors later in this slide deck


There is no default list of class names

You come up with the class names your project uses (or
you use those provided by a framework like Bootstrap)
Don’t use spaces

Rules for class values in HTML5


In fact, you can use emoji for class names

.📰 {
background-color: hsl(0,0%,76%);
}

.🤮 {
font-family: "Comic Sans", cursive;
}
The big rule for class names: describe function, not
appearance

Not “what does it look like?” but instead “what is it


for?”
Bad class names Good class names

.author name .author-name


.big-red .caption
.small .alert
.footnote
.center
Multiple words in a class name?

.main-content-nav ← What most developers use


.main_content_nav
.maincontentnav
.mainContentNav
.MainContentNav

Just be consistent!
ID
#id

Selects any element to which the ID has been applied,


but each ID can only be used once per page

You can use multiple IDs on a page, but each ID must


be unique
#id & .class share a lot of similarities

» Names are made up by developers, not specs


» Names shouldn’t have spaces
» Names should denote purpose, not appearance
» Names containing multiple words should be
combined with a - or something else consistently
A specific ID can be applied
one time per page
Class ID
CSS .foo #bar
HTML class="foo" id="bar"
Unique on page No Yes
class="foo" 10x id="bar" once
Values per element Multiple One
class="foo bar" id="baz"
Specificity 10× 100×
URL addressable No Yes
Bad ID names Good ID names

#top nav #sidebar (use <aside>)


#tiny-little-fonts #utility-nav (use <nav>)
#site-footer (use
<footer>)
#logo
#legalese
Use classes instead of IDs (in fact, try to avoid IDs as
much as possible when it comes to CSS)*

Classes can be reused, while IDs cannot

IDs can make the cascade (more about that soon!) very
complicated

Many (most?) frameworks (like Bootstrap) stick to


classes entirely
* OK, you may need one every once in a blue moon
However, even if we don’t use IDs in CSS as much as
we used to, they are still necessary

» Page fragment identifiers


» Unique hooks for JavaScript
IDs as page fragment identifiers

Given this HTML on http://www.foo.com/toc/:


<h2 id="chapter2">

You could link directly to it on the same page:


<a href="#chapter2">

Or from a different page:


<a href="http://www.foo.com/toc/#chapter2">
This parameter…

…helps the JavaScript…

…target this ID
Other simple selectors

» Attribute selector
» Pseudo-class
» Pseudo-element

Those will be covered in CSS - Selectors


Compound Selectors
A compound selector describes multiple conditions on
an element

If all conditions are true, the element is selected

Consists of a chain of simple selectors connected


together, but not connected by a combinator (which is
coming up next)
p.alert matches
<p class="alert">

table.inventory matches
<table class="inventory">

table.inventory.northwest matches
<table class="inventory northwest">

.cthulhu:first-child matches the first


<element class="cthulhu">
A compound selector is used to match an element that
has two classes on it
<p class="center note">

.center { Selects elements with the


text-align: center; .center class
}

.note { Selects elements with the


font-size: .9em; .note class
}

.center.note { Selects elements with the


font-style: italic; .center and .note classes
}
Complex Selectors
Using Combinators
A complex selector uses combinator(s) to combine
multiple selectors together into 1 selector

.ws-gallery img { … }

ul > li { … }

h2 + p.lead { … }
Combinator Name Ex. Which B is selected?
␣ (space) Descendant A B Any descendant of A
> Child A > B Direct children of A

+ Next Sibling A + B Next sibling after A


~ (tilde) Subsequent A ~ B All siblings after A
Siblings

A combinator expresses a relationship between


selectors
Key Selectors
Rendering engines match selectors from right to left

The right-most part is the key selector, the actual object


being selected

Really helpful understanding complex selectors


ul li

ul > li

ul > li a[title="home"]

.callOut > p:last-child

.ws-header .nav > li > a

p code, pre code, blockquote code


Descendant Combinator
selectorA selectorB

Selects all selectorB who have selectorA as an


ancestor

selectorB can be a child, grandchild, or later


descendant of selectorA

Any other selectorB who does not have selectorA as


an ancestor is unaffected
Default for nested <li>:
disc •, circle ◦, square ▪
I only wanted these <li>s to
change to ▪, not all of them
You can often use a descendant combinator instead of a
class (& you must if you cannot change the HTML)
👎
HTML
<aside>
<img
class="headshot"
src="…">
</aside>

CSS
.headshot {}
👎 👍
HTML Cleaner HTML
<aside> <aside>
<img <img src="…">
class="headshot" </aside>
src="…">
</aside> Better CSS using the
descendant combinator
CSS aside img {}
.headshot {}
Child Combinator
selectorA > selectorB

Selects any selectorB who is a direct child of selectorA,


not a grandchild or any other descendants

All siblings who are direct children of selectorA are


selected

Siblings: 2 or more elements that share a parent

Contrasts with the descendant combinator, which selects


both direct children & any descendants, no matter how deep
Default for nested <li>:
disc •, circle ◦, square ▪
👍

} 🤨

}
1st level changed from • to ▪,
but 3rd level remains ▪ because
that’s the default
Let’s change all 3 level defaults:
1st from • to ▪, 2nd from ◦ to •,
& 3rd from ▪ to ◦
An illustration of the difference between the descendant
& child combinators
Using > limits the scope of the styles
Selector List
selectorA, selectorB, selectorC

List selectors that have similar declarations for


simpler & cleaner CSS & HTML
Don’t do this: Do this:

p { blockquote, p {
font-family: serif; font-family: serif;
font-size: 1em; font-size: 1em;
} }

blockquote {
font-family: serif;
font-size: 1em;
}
Any selector can be included in the list

.emphasis, .title {font-style: italic;}

em, .title {font-style: italic;}

p, #nav, .pullquote {font-family: Verdana,


sans-serif;} 🤪
A very common selector list

h1, h2, h3, h4, h5, h6 {


font-family: "Georgia Pro", Georgia, serif;
}
Group similar selectors, but be specific where needed

CSS is cumulative unless overridden

blockquote, p {
font-family: Verdana, sans-serif;
}

p {
line-height: 1.5;
}
Turn this… …into this:

h1 { h1, h2 {
font-weight: normal; font-weight: normal;
font-size: 2.5em; font-family: serif;
font-family: serif; }
}
h1 {
font-size: 2.5em;
h2 {
}
font-weight: normal;
border-bottom: 1px h2 {
dotted black; border-bottom: 1px dotted
font-family: serif; black;
font-size: 1.8em; font-size: 1.8em;
} }
Good practice Elements, then IDs, then classes
blockquote,
Alphabetical order within
option,
p,
each grouping of selectors
td,
#sidebar,
.legalese {
font-family: Verdana, sans-serif;
font-size: 1em;
}
Formatting
Don’t do this:

h1 {color: dimgray;}
h1 {font-size: 1.4em;}
h1 {font-weight: bold;}
h1 {font-family: Verdana, sans-serif;}
Instead, combine related declarations

h1 {
color: dimgray;
font-family: Verdana, sans-serif;
font-size: 1.4em;
font-weight: bold;
}
Formatting CSS rulesets

selector {
property: value;
property: value;
property: value;

}

The order of declarations in the declaration block


doesn’t matter
Do not forget to put ; at the end of every line in a
ruleset

You do not actually have to put ; at the end of the last line in a ruleset, but that is a very bad
habit to get into
Use comments in CSS for the same reasons as in
HTML

» Notes to yourself & others


» Debugging: comment out troublesome CSS for testing
(use your browser’s Inspector)

HTML comments
<!-- blah blah html blah blah html -->

CSS comments
/* blah blah css css blah blah css css */
✏ SIDE NOTE

Design Pattern

“a formal way of documenting a solution to a design


problem in a particular field of expertise.” —Wikipedia

“Each pattern describes a problem that occurs over and


over again in our environment, and then describes the
core of the solution to that problem” —Christopher
Alexander, architect & author of A Pattern Language
(1977)
✏ SIDE NOTE

Bootstrap 4’s classes for the common design pattern of


rounded borders
✏ SIDE NOTE

Bootstrap 4’s classes for the common design pattern of


cards
💡PRO TIP
Here’s the order Jans normally uses in his
stylesheets

1. General rules that apply to the whole site (linked


libraries, typography)
2. Site-wide design patterns (header, nav, footer)
3. Page type design patterns (sidebar, news, post)
4. Specific page design patterns (home page)
5. Content design patterns (callouts, image gallery)

With appropriate comments sprinkled throughout


💡PRO TIP
Here’s the order I sometimes shoot for in my stylesheets

@font-face
html
body
/* General */
<type selectors, A➝Z>
<ID selectors, A➝Z>
<class selectors, A➝Z>
/* <New Section> */
<type>
<ID>
<class>

<span>
&
<div>
HTML elements “work” without attributes & values

(with a tiny few exceptions, like <img> & <a>)


<span> & <div> are HTML elements exist solely to
work with CSS*

<span> & <div> by themselves do nothing on a


webpage (except draw invisible boxes)

They must use CSS (class="foo" or id="bar") to do


anything productive

* & JavaScript
<span>
<span> is a text semantic element that creates an inline box &
does nothing else without CSS

Use <span> to hold attribute-value pairs relevant to CSS

As a text semantic element, it usually doesn’t have other


elements nested inside it

<span class="foo">Ph’nglui mglw’nafh Cthulhu R’lyeh


wgah’nagl fhtagn!</span>

Use it when other text semantic elements are not semantically


appropriate
<div>
<div> is a grouping element that creates a block box by
default & does nothing else without CSS

Use <div> to hold attribute-value pairs relevant to CSS

As a grouping element, it groups other elements, e.g.,


put a <div> around 3 <p>s & a <ul>

Use it when other grouping elements are not


semantically appropriate
I want the table of contents to stand
out with a background color,
borders, & rounded corners
Well that looks stupid…
Much better—& that is why we have
<div>
Actually, to be semantic, I should
really use an <ol>
This is a useless <div>

<div class="lead-copy">
<p>
When a traveller in north central Massachusetts takes
the wrong fork at the junction of the Aylesbury pike just
beyond Dean’s Corners he comes upon a lonely and
curious country.
</p>
</div>

Only use <div> around 2 or more elements that create block


boxes*

* It’s OK to wrap a <div> around 1 element in a few cases


Inheritance
Some properties, like font-size & color, are inherited:
elements with those properties pass those properties
down through the DOM to their descendant elements
(unless overridden)

Other properties, like background-image & border, are


not inherited: elements with those properties do not pass
those properties down to their descendent elements

Inheritance is for elements that do not have properties


set
border- font-style line-height
collapse font-variant orphans
border-spacing font quotes
caption-side letter-spacing text-align
color list-style- text-edge
cursor type text-indent
direction list-style- text-transform
empty-cells position visibility
font-family list-style- white-space
font-size image widows
font-weight list-style word-spacing

Partial list of inherited properties


Cascading
Style Sheets
How does the rendering engine know which style to apply
to an element?

If a selector matches an element, that selector’s styles are


used

Inheritance comes into play if an element does not have


properties set

But what if the CSS rules conflict; e.g., what if CSS tells
the rendering engine to make all <p>s use serif and sans-
serif fonts?
If an element’s CSS declaration conflicts with another
declaration, the rendering engine uses the Cascade to
find a winner

In other words, conflicting declarations follow a


cascade, & the rule with the most weight wins
3 parts to the Cascade

1. Origin & Importance

2. Specificity

3. Order

Note: as of CSS Cascading and Inheritance Level 4 (August 2020), things have changed if the
Shadow DOM is involved; more on this in the Web Components presentation
Origin & Importance
CSS can originate from 3 places:

» Browser, aka, the user agent


» User
» Author
All Web browsers have built-in CSS rules

In Firefox, for example, why does <p> have a certain


amount of space before & after it?

Because of Firefox’s built-in default CSS


Firefox
Equivalent to margin-top: 1em
& margin-bottom: 1em
WebKit (Safari)
Equivalent to margin-top: 1em
& margin-bottom: 1em
1em on top & bottom; 0 on right & left
“The CSS rules given in these subsections are, except
where otherwise specified, expected to be used as part
of the user-agent level style sheet defaults for all
documents that contain HTML elements.”
Users can specify CSS rules too

Why?

» All fonts are at least a certain size


» A certain font is used because it’s more readable
» Always enable text-decoration: underline so
links are obvious
» See outlines around elements with keyboard focus
using outline: solid
Firefox has always allowed users to create their own
styles in a file called userContent.css that goes into
your Firefox Profile

For more about your Profile: kb.mozillazine.org/


Profile_folder_-_Firefox

For more about userContent.css: kb.mozillazine.org/


UserContent.css
✏ SIDE NOTE
As of Firefox 69, userContent.css isn’t supported
by default unless users first enable the feature

1. Type about:config in the Firefox address bar &


select Enter
2. Click the button that confirms you Accept the Risk
and Continue
3. In the box at the top, search for toolkit.
legacyUserProfileCustomizations.stylesheets
4. Double-click on the resulting line to toggle to true
5. Restart Firefox
Internet Explorer
Chrome 33 (2014) dropped support for a user styles file
Chrome 33 (2014) dropped support for a user styles file
Edge: Never supported a user styles file!
Edge: Never supported a user styles file!
Safari — I created safari.css for my own use
My safari.css file

html {
font-family: "Source Sans Pro", sans-serif;
}

h1, h2, h3, h4, h5, h6 {


font-family: "Georgia Pro", serif;
}

code, kbd, pre, samp, tt, var {


font-family: "Source Code Pro", monospace;
}
✏ SIDE NOTE
Browser makers’ response when asked about missing
support for a user styles file: “Get an extension”

Do get:

» Stylus for Chromium-based browsers & Firefox (which


is excellent & removes all analytics, telemetry, & data
collection)
» Cascadea for Safari

Do not get: Stylish (used to be good, but now it’s


spyware)
If a user’s CSS contradicts a author’s CSS, the user can
make sure hers “wins”

Use !important after a property-value pair

p {
font-size: 36px !important;
}

However, CSS authors can do the same thing!


My safari.css file Notice: no !important

html {
font-family: "Source Sans Pro", sans-serif;
}

h1, h2, h3, h4, h5, h6 {


font-family: "Georgia Pro", serif;
}

code, kbd, pre, samp, tt, var {


font-family: "Source Code Pro", monospace;
}
The order of origin & importance

AKA

The order in which stylesheets are weighted, from


lightest to heaviest
Order of
origin & Browser
importance,
from lightest User
to heaviest

Author

Author !important

User !important
Author & Author !important?

Why are you contradicting yourself?


Do I contradict myself?
Very well then I contradict
myself,
(I am large, I contain
multitudes.)

From Walt Whitman’s


“Song of Myself” from
Leaves of Grass
You’re not contradicting yourself (hopefully!)

What if you’re using Bootstrap & its default CSS?

<link rel="stylesheet" href="bootstrap.css">

Is that CSS coming from the browser, user, or author?


You will want to override some of Bootstrap’s selectors

<link rel="stylesheet" href="bootstrap.css">


<link rel="stylesheet" href="me.css">

Author vs. author

Sometimes, you will have to use !important to beat the


other author
Be careful using !important

“!important: 3 seconds to type, 3 years to remove.”


—Harry Roberts

“!important is the Hammer of Thor, smiting


everything in its path.” —Jans Carton

Only use it as a last resort


Specificity
Specificity asks how specific is each selector?

Each simple selector is assigned a weight value

The greater the weight, the more specific the selector

In other words, with great weight comes great specificity 😜


Selector(s) Column
1 × #ID a
1 × .class, :pseudo-class, & [attribute] b
1 × type & ::pseudo-element c

Take the numbers & place them a,b,c, e.g., 0,2,1


a b c Total
* 0,0,0
li 1 0,0,1
.foo 1 0,1,0
#chapter1 1 1,0,0
Remember, compound & complex selectors are made
up of multiple simple selectors

Simply add their simple selector weight values together

p.foo.bar (compound) is made up of 1 type & 2


classes, so 0,2,1

.foo > cite (complex) is composed of 1 class & 1 type,


so 0,1,1
The following are ignored when calculating
specificity:

» Combinators: ␣, >, +, ~
» Universal selector: *
» Negation pseudo-class (but not the contents — that is
counted!): :not(.but-this-part-is-counted)
Inline styles (<style="foo">) always outweigh
everything else (a good reason to hate them 🤬)
a b c Total
* 0,0,0
li 1 0,0,1
.foo 1 0,1,0
#chapter1 1 1,0,0
ul li 1 × 2 0,0,2
.foo > li 1 1 0,1,1
ul ol li.steps 1 1 × 3 0,1,3
li.steps.mech 1×2 1 0,2,1
style="foo" ∞
A positive integer in a column
outweighs any positive
integer, even if it’s greater, in
a column to the right

26 in column b is outweighed
by 1 because it is in column a
Visual Studio Code shows you the specificity of a
selector when you hover over it & what it will look like
visually
Order
Later CSS in the stylesheet wins over earlier CSS
main.css:

.blue {color: blue}


.red {color: red}

index.html:

<p class="red blue">


What color am I?
</p>
main.css:

.blue {color: blue}


.red {color: red}

index.html:

<p class="red blue">


What color am I?
</p>
main.css:

.red {color: red}


.blue {color: blue}

index.html:

<p class="blue red">


What color am I?
</p>
main.css:

.red {color: red}


.blue {color: blue}

index.html:

<p class="blue red">


What color am I?
</p>
The Cascade
Here’s some code I have on a website:

<div class="callOut">
<p>
For the next 2 weeks…
</p>
</div>

.callOut {
background-color: #E6E8F2;
margin: 1em 1em 2em 1em;
padding: 1em;
border: 1px #ccc solid;
border-radius: 1em;
}
The result!
However…
That extra space at the
bottom really bothers me
That extra space at the
bottom really bothers me
To fix it, I put this in my CSS at lines 194–196:

.callOut > p:last-child {


margin-bottom: 0;
}

Let me explain what that means…


> is a combinator that selects the p:last-child is a
direct children of (not descendants pseudo-class that
of) the .callOut class means the <p> that
is the last child of
(not descendant of)
.callOut > p:last-child { the .callOut class
margin-bottom: 0;
}

So this selects the <p> that is the last direct child of


the .callOut class
.callOut > p:last-child {
EX
margin-bottom: 0; AM
}
PL
<div class="callOut"> E
<p>foo</p>
<p>bar</p>
<p>baz</p>
<p>quz</p> Selected!
<blockquote>
<p>quux</p> Not selected, as this <p> is
</blockquote> not the last direct child
</div>
Why use this?

.callOut > p:last-child {


margin-bottom: 0;
}

Why not just use this?

.callOut > p {
margin-bottom: 0;
}

Because sometimes there are 2 or more paragraphs inside


.callOut
So back to where I was… I put this in my CSS at line
194:

.callOut > p:last-child {


margin-bottom: 0;
}

Let’s check the webpage…


Nothing changed!
Why didn’t it work?

Let’s open the Inspector & find out why


Hmmm… mine is being beaten by earlier code
Lines 146–148:
#content p {
margin-bottom: 12px;
}

Lines 194–196:
.callOut > p:last-child {
margin-bottom: 0;
}

Why isn’t mine winning since it’s later in order?


Lines 146–148:
#content p {
margin-bottom: 12px;
}

Lines 194–196:
.callOut > p:last-child {
margin-bottom: 0;
}

Is origin & importance causing the 1st declaration block


to win? 🙅
Lines 146–148:
#content p {
margin-bottom: 12px;
}

Lines 194–196:
.callOut > p:last-child {
margin-bottom: 0;
}

Is specificity causing the 1st declaration block to win? 🤔


#content p { .callOut > p:last-
margin-bottom: 12px; child {
} margin-bottom: 0;
}

Specificity Specificity

(#content = 100) + (.callout = 10) +


(p = 1) = (p = 1) +
101 (:last-child = 10) =
21
Lines 146–148:
#content p {
margin-bottom: 12px;
}

Lines 194–196:
.callOut > p:last-child {
margin-bottom: 0;
}

Because specificity meant the 1st declaration block had


the most weight, order never entered into the picture
Nope—tied

Specificity beat me Never got to it


There are 3 solutions to this problem
Lines 146–148:
#content p {
margin-bottom: 12px;
}

Lines 194–196:
.callOut > p:last-child {
margin-bottom: 0 !important;
}

Adding !important makes the 2nd ruleset win due to origin


& importance, so specificity & order never come into play
I won before
we could get to
anything else

Never got to it
Lines 146–148:
#content p {
margin-bottom: 12px;
}

Lines 194–196:
#content .callOut > p:last-child {
margin-bottom: 0;
}

Adding #content to line 194 makes the 2nd ruleset win due
to specificity, so order & importance never comes into play
Lines 146–148: 100 + 1 = 101
#content p {
margin-bottom: 12px;
}

Lines 194–196: 100 + 10 + 1 + 10 = 121


#content .callOut > p:last-child {
margin-bottom: 0;
}

Adding #content to line 194 makes the 2nd ruleset win due
to specificity, so order & importance never comes into play
Nope—tied

I won (121 over 101)

Never got to it
Lines 146–148:
#content p {
margin-bottom: 12px;
}

Lines 194–196:
.callOut > p:last-child {
margin-bottom: 0;
}

Getting rid of #content on line 146 makes the 2nd


ruleset win due to specificity, but I can’t easily remove it!
Lines 146–148:
#content p { 1
margin-bottom: 12px;
}

Lines 194–196: 10 + 1 + 10 = 21
.callOut > p:last-child {
margin-bottom: 0;
}

Getting rid of #content on line 146 makes the 2nd


ruleset win due to specificity, but I can’t easily remove it!
Much better!
Much better!
Bonus question: how do we get rid of those extra pixels at
the top?

Much better!
Then I realized that <div class="callOut"> doesn’t
always end with <p>

#content .callOut > :last-child {


margin-bottom: 0;
}

Now it’s weighted to win and selecting the correct DOM


objects

Remember, :last-child is the same as *:last-child


What if I have nested last children inside other nested
last children?

.callOut > :last-child,


.callOut > :last-child > :last-child,
.callOut > :last-child > :last-child > :last-
child {
margin-bottom: 0;
}
CSS Reset
Keywords
✏ SIDE NOTE
CSS keywords have special meaning in CSS & are
reserved by the language, e.g.:

» border & font-family are property keywords


» solid & dotted are value keywords
» black & red are color value keywords
» <length> & <color> are data type keywords
» @media & @supports are at-rule keywords
» attr() & calc() are function keywords
» :hover & :focus are pseudo-class keywords
» ::before & ::first-letter are pseudo-element
keywords
There are 5 global keywords in CSS

» 4 are values: initial, inherit, unset, & revert


» 1 is a property: all
initial value resets property back to its default value as
defined in the spec

inherit value forces an element to inherit styles from an


ancestor that it would not normally inherit

unset value acts as either inherit (if the property is


inherited) or initial (if the property is not)

revert value rolls back the property’s cascade, depending


upon who declared it: the browser, user, or author
initial value resets property back to its default
value as defined in the spec

Remember, in the specs for CSS…

» display default is inline


» font-size default is medium
» border-style default is none
» border-width default is medium
» margin & padding defaults are 0
» font-family default “depends on user agent”
Don’t get confused

Look at <p>

» Browsers set defaults by selector, so <p> defaults to


display: block
» The spec sets defaults by property, so display:
inline is the default

initial resets properties back to the spec, not the


browser!
The browser’s default for <p>
is display: block

The spec says that all boxes


default to display: inline

initial resets back to the


spec, not the browser
The inherit value forces an element to inherit values
from properties that are not normally inherited
unset value acts as either inherit (if the property is
inherited) or initial (if the property is not)

What’s the use case for this? See all just ahead
revert value rolls back the property’s cascade,
depending upon who declared it: the browser, user,
or author

» if the author is the origin, it rolls back to the user


» if the user is the origin, it rolls back to the browser
» if the browser is the origin, it rolls back to the spec

If the origin that is rolled back to does not declare a


value for the property, it is skipped & the rendering
engine rolls back another level
Effects of revert

Author
If revert is rolling back a property’s
User style set by an author, & the user has
not set a style, it skips the user &
Browser rolls back to the browser, & so on

Spec
Most common use-case for revert: you have a heavily-
modified selector & you want to revert back to the
browser’s defaults (remember, most users never set any
styles, so that one is skipped over)
all

Magic property that resets all property values, except


for direction & unicode-bidi

Really designed to be used with small components —


you wouldn’t want to do this for an entire page

Values are the 4 global keywords: initial, inherit,


unset (which now makes sense in a limited scenario!),
& revert
initial – 12 19 3.2 4 4 2.3
inherit 8 12 2 3.1 3.2 4 2.1
unset – 13 27 9.1* 9.3* 41 41
revert – 84 67 9.1 9.3 84 84
all – 79 27 9.1 9.3 37 4.4.4

* all: unset is buggy in Safari & sets color to black, preventing you from setting another color; the
* workaround is to use -webkit-text-fill-color everyplace you also use color; Safari 14 fixes this
Tools
Books
Great overview of HTML5
& CSS2 (& some CSS3)
References
developer.mozilla.org/en-US/docs/Web/CSS/Reference

As of July 2020 there are 617 terms!


MDN supporters & contributors
1st 8 Guides on CSS Tricks (there are lots more!):

» A Complete Guide to Flexbox ★


» Media Queries for Standard Devices
» A Complete Guide to Grid ★
» A Complete Guide to the Table Element
» Centering in CSS: A Complete Guide
» A Complete Guide to SVG Fallbacks
» A Nerd’s Guide to Color on the Web
» A Complete Guide to Data Attributes
apps.workflower.fi/vocabs/css/
pinboard.in/u:rsgranne/t:css
Browser Tools
Built-in developer tools are excellent
Validation
jigsaw.w3.org/css-validator/
Color Pickers
Sip

Color picker

theolabrothers.com

$0 (with $9.99 in-app purchase)


Just Color Picker

Small & with the necessary features

$0

annystudio.com/software/colorpicker/
ColorPro

Professional color picker

www.iconico.com/colorpro/

$30
Thank you!

[email protected]
www.granneman.com
ChainsawOnATireSwing.com
@scottgranneman

[email protected]
websanity.com
CSS Overview
Selectors, Integration, Inheritance, Cascading

R. Scott Granneman r Jans Carton

© 2009 R. Scott Granneman


Last updated 2021-08-16
You are free to use this work, with certain restrictions.
2.8 For full licensing information, please see the last slide/page.
Changelog

2021-08-16 2.8: Explained how @import is different


from Sass @import; removed wrong advice to put
@charset at top of style sheet with emoji; more detail
about @charset & how parsers detect UTF-8
Changelog

2021-07-13 2.7: Added another explanation of the DOM,


from Wikipedia; more improvements to Specificity;
updated chart in Reset Keywords; added conceptual
models to DOM

2021-04-12 2.6: Added in Notes that class & ID names are


identifiers; added better explanation & chart for Complex
Selectors Using Combinators; completely re-did Specificity
section; added Side Note under Linking about using
@charset "utf-8";; fixed W3C logo in MDN members
Changelog

2020-11-30 2.5: Re-ordered & changed wording slightly


in Specificity; updated examples in Compound Selectors;
added detail re: Shadow DOM & the Cascade; changed
Importance to Order & Importance to match the spec
more closely; updated Cascade diagram & improved
wording throughout Cascading Style Sheets

2020-07-31 2.4: Created diagram for the Browser


Processing Pipeline; made Descendant Combinator
examples clearer by adding arrows
Changelog

2020-07-21 2.3: Added list of Web APIs after


JavaScript; added slides about design patterns in
Formatting; added example of looking up property’s
initial value at MDN; updated screenshot for initial
value & added explanation to it; added additional,
easier examples for descendant & child combinators;
changed CSS Resets to CSS Reset Keywords; improved
wording explaining inherit value; moved Key
Selectors at the beginning of Complex Selectors
Changelog

2020-07-15 2.2: Minor fixes; re-did Specificity


completely; removed the Miller’s Crossing example;
made clearer in Order what is in HTML & what is in
CSS

2020-07-10 2.1: Added note about Safari bug with all:


unset
Changelog

2020-07-09 2.0: (con’t. from ↓) added better


descriptions of <span> & <div>; changed “Default
inherited properties” to “Partial list of inherited
properties” & added text-edge; added detail to MDN’s
CSS Reference in Tools; updated screenshots of CSS-
Tricks in Tools; added CSS Resets section for initial,
inherit, unset, revert, & all; added explanation of
CSS keywords; so many changes I bumped version
number up to 2!
Changelog

2020-07-09 2.0: Added more details to Specificity; minor


edits; added definition of simple selector; moved Key
Selectors under Complex Selectors; for user styles, gave
more detail re: Firefox’s userContent.css, Chrome, &
extensions, & updated screenshot of Safari’s Advanced
Preferences; better screenshot for embedded styles;
updated screenshot for .class selector; updated table
showing difference between HTML & CSS terms; added
order Jans places things in his stylesheets; (con’t. ↑)
Changelog

2018-12-06 1.20: Added screenshots showing embedding


with <style> & how to link to main.css; added logos for
MDN supporters; *:first-child is the same as :first-
child; added Side Note re: using 2 class attributes; in
Formatting, always put ; at the end of each declaration;
added CSS Tricks to Tools; in Class, told viewer to see
Compound to learn how to match an element with 2
classes; screenshots for @import & reorganized those
slides; minor wording changes; better example for
Compound selectors; replaced ID screenshots
Changelog

2018-11-21 1.19: Called out items on browser processing


pipeline illustration; fixed image for multiple classes
(<figurecaption>?!); updated screenshots for child
combinator; for selector lists, removed silly example &
added headings slide; added Side Note on <div> that it
should semantically be <ol>; fixed Cascade example so
proper method is shown; added slides showing difference
between descendant & child combinators; added table on
Time & User Perception to @import; replaced inherit
screenshot
Changelog

2018-10-01 1.18: Added how DOM changes attribute-


value pairs; replaced DOM section with The Browser
Processing Pipeline; fixed Default inherited properties
slide; updated theme to Granneman 1.5; added Walt
Whitman on contradicting yourself

2017-11-06 1.17: Improved key selectors; added reasons


for user CSS
Changelog

2017-10-30 1.16: Added Just Color Picker; added


screenshot of ColorPro website; changed color of some
arrows & shapes to Tulip Tree (#E8A433); better
solutions to specificity problem with .callOut; fixed
wording to be correct &/or more specific; added emoji
for class names; added Opera user-agent styles; better
examples for Key Selectors; applied Granneman 1.4
theme; fixed formatting issues; added default order I
use in stylesheets
Changelog

2017-10-25 1.15: Added better examples for DOM vs


source code; organized Basic Selectors much better;
moved Key Selectors, IDs as page fragment identifiers &
JavaScript hooks, & Compound Selector example from
CSS Selectors to here; gave full list of selectors & grayed
out ones we’re not covering here; fixed wording
introducing the Cascade
Changelog

2017-10-18 1.14: Took out details about how to turn on


Firefox 3D View, since it’s not longer supported; made
Cascading chapter slide italicized; corrected & added info
on anonymous boxes; in History, hid modules & added
Can I Use, minor fixes & corrections

2016-09-23 1.13: Moved slide comparing class & ID; under


Importance, rearranged IE & Safari & added Firefox for
Windows, Chrome, & Edge; re-ordered examples of
Descendant Combinator; fixed formatting errors
Changelog

2016-09-16 1.12: Updated theme to Granneman 1.2;


small changes in wording to make things clearer;
cleaned up formatting in a few places; added slide re:
using classes instead of IDs; fixed slides in Selector
Grouping; changed Important example from
WordPress to Bootstrap; fixed wrong information re:
class & id values & clarified; added example for
Descendant Combinator
Changelog

2016-01-20 1.11: Added slide re: CSS3 Taxonomy &


Status; better explanation why we need <div>; added note
re: specificity

2016-01-11 1.10: Minor improvements taken from CSS -


Selectors; added Child Combinator to Selectors; added
another example of Child Combinator; added screenshots
of browser CSS; explained author vs author in
Importance; explained how my Safari CSS works; added a
long example showing how the Cascade works in practice
Changelog

2015-12-13 1.9: Clarified source of DOM quote; changed numbers


of selectors; got rid of E & F in selectors & made them clearer;
changed .bigRed to .big-red; clarified source of class & ID names;
add tweet re: CSS to beginning

2015-05-10 1.8: Added info about CSS 4; clarified that <span> &
<div> draw boxes; added additional names of directories that are
always created; changed “What Google prefers” to “… uses”;
removed Hues & added Sip to Color Pickers; fixed URL &
screenshots for CSS Vocabulary; moved Viewport Resizer to
Bootstrap; for Separation of Concerns, added “& Meaning” to
HTML
Changelog

2015-03-06 1.7: Added another example of selector


grouping; added details about resource inlining

2015-01-12 1.6: Added my safari.css file; clarified &


added info on specificity

2015-01-11 1.5: Clarified Inheritance

2014-09-27 1.4: Changed “browser” to “rendering engine”


in a few places where it made sense
Changelog

2014-08-12 1.3: Improved Descendant Selector examples;


improved wording & added slides in DOM section; improved
Cascade diagram; fixed <div> screenshot; added URLs for
<div> & <span> screenshots; fixed Viewport Resizer
screenshots

2014-08-10 1.2: Added DOM spec info & screenshots of DOM


& Source Code; added details about Firefox Web Dev Tools

2014-08-04 1.1.1: Added definition of anonymous object


Licensing of this work
This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License.

To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/4.0/.

You are free to:

» Share — copy and redistribute the material in any medium or format


» Adapt — remix, transform, and build upon the material for any purpose, even commercially

Under the following terms:

Attribution. You must give appropriate credit, provide a link to the license, and indicate if changes were made.
You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your
use. Give credit to:

Scott Granneman • www.granneman.com • [email protected]

Share Alike. If you remix, transform, or build upon the material, you must distribute your contributions under
the same license as the original.

No additional restrictions. You may not apply legal terms or technological measures that legally restrict others
from doing anything the license permits.

Questions? Email [email protected]

You might also like