A presentation at CSS Dev Conf in in New Orleans, LA, USA by Greg Whitworth
@ gregwhitworth
Fantasia” 1940 © Disney•Pixar . All rights reser ved.
Fantasia” 1940 © Disney•Pixar . All rights reser ved.
Fantasia” 1940 © Disney•Pixar . All rights reser ved.
Fantasia” 1940 © Disney•Pixar . All rights reser ved.
Fantasia” 1940 © Disney•Pixar . All rights reser ved.
Fantasia” 1940 © Disney•Pixar . All rights reser ved.
Fantasia” 1940 © Disney•Pixar . All rights reser ved.
Fantasia” 1940 © Disney•Pixar . All rights reser ved.
{ the pipeline }
Compose Paint Layout Style DOM Content Parsing Network {the pipeline} @ gregwhitworth
Compose Paint Layout Style DOM Content Parsing Network @ gregwhitworth {the pipeline} JS
JS Input Compose Paint Layout Style DOM Content Parsing Network @ gregwhitworth {the pipeline}
Input Compose Paint Layout Style DOM Network @ gregwhitworth {the pipeline} Content Parsing JS
{ parsing } Compose Paint Layout Style DOM Content Parsing Network YOU ARE HERE
button { background : green ; } @ gregwhitworth {style} I found a selector!
button { background : green ; } @ gregwhitworth {style} I found an opening curly brace!
button { background : green ; } @ gregwhitworth {style} I found a property
button { background : green ; } @ gregwhitworth {style} I found a colon!
button { background : green ; } @ gregwhitworth {style} I found a value!
colon!
button { background : green ; } @ gregwhitworth {style} I found a closing curly brace!
button
button
color rgb (0,255,0)
size : 1em; }
size 1em
{ style } Compose Paint Layout Style DOM Content Parsing Network YOU ARE HERE
{ style: terminology }
@ gregwhitworth {style} Declared: What the author wrote Value Types width: 506.456789132456489787px
@ gregwhitworth {style} Specified: Declared + defaults Value Types width: auto
size: 1em 16px
@ gregwhitworth {style} Used: Result of layout calculations Value Types width: 50% 300px
@ gregwhitworth {style} Actual: UA specific adjustments Value Types width: 506.456789132456489787px 506.45px
{ style: computation }
DOM Tree Collection of styles Collection of styles Collection of styles Matching Algorithm @ gregwhitworth {style}
The User Agent should have ever ything resolved except what requires layout @ gregwhitworth {style}
color : rgb (0,255,0); height: 540px;
{ style: cascade }
A score awarded to a selector based on the count of tags, classes, id’s, !important, & attribute selectors used @ gregwhitworth {style} Specificity
Inline styles win out over all selectors unless an !important was used @ gregwhitworth {style} Specificity
• !Important • Style Attribute • ID • Classes, Psuedo Classes, attr • Elements & Psuedo Elements @ gregwhitworth {style} Specificity
li 0 0 0 0 1 @ gregwhitworth {style}
li 0 0 0 0 1 li.foo 0 0 0 1 1 @ gregwhitworth {style}
li 0 0 0 0 1 li.foo 0 0 0 1 1 #comment li.foo.bar 0 0 1 2 1 @ gregwhitworth {style}
li 0 0 0 0 1 li.foo 0 0 0 1 1 #comment li.foo.bar 0 0 1 2 1
<li style=“color : red”> 0 1 0 0 0 @ gregwhitworth {style}li 0 0 0 0 1 li.foo 0 0 0 1 1 #comment li.foo.bar 0 0 1 2 1
<li style=“color : red”> 0 1 0 0 0 color : red !important 1 0 0 0 0 @ gregwhitworth {style}selectors @ gregwhitworth {style} “Keep your CSS selectors short” by Harr y Roberts
An origin is what determines where the stylesheet is placed within the cascade @ gregwhitworth {style} Style Origins
User Agent Author User 3 currently specified origins @ gregwhitworth {style} : Renders CSS : Web Developer : Person using site
button
{
background
:
yellow
;
}
@
gregwhitworth
{style}
button
{
background
:
yellow
;
}
@
gregwhitworth
{style}
button
{
background
:
yellow
;
}
@
gregwhitworth
{style}
button
{
background
:
yellow
;
}
@
gregwhitworth
{style}
button @ gregwhitworth {style}
@ gregwhitworth {style} #document body header div p p #document body header div
type { background: orange }
type div p { background: blue }
type { background: orange } div p { background: blue } #document body header div p p p p
{ layout } Compose Paint Layout Style DOM Content Parsing Network YOU ARE HERE
{ layout: terminology }
captions) that are not block boxes, and block boxes with 'overflow' other than 'visible' (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents. @ gregwhitworth {layout}
Block formatting context (BFC) @ gregwhitworth {layout} Absolute Positioned Box This box creates a new BFC
Containing block The ancestor block that styles are resolved against @ gregwhitworth {layout}
block @ gregwhitworth {layout} W3C CSS 2.2 Definition of Containing Block
Containing Block @ gregwhitworth {layout} position: fixed
most box or page box. @ gregwhitworth {layout}
Initial Containing Block (ICB) @ gregwhitworth {layout} The red dashed box is the ICB
@ gregwhitworth {layout} LTR/RTL Writing Mode INLINE DIRECTION INLINE DIRECTION Vertical Writing Mode
@ gregwhitworth {layout} LTR/RTL Writing Mode BLOCK DIRECTION BLOCK DIRECTION Vertical Writing Mode
{ layout: flow }
The flow You move in document order laying out each child in the direction of the boxes writing mode @ gregwhitworth {layout}
Float @ gregwhitworth {layout}
<body> <div> <p> DOM Tree float: left; text node <p> text nodeFloat @ gregwhitworth {layout}
<body> <div> <p> DOM Tree float: left; text node <p> text nodeFloat @ gregwhitworth {layout}
<body> <div> <p> DOM Tree float: left; text node <p> text node{ layout: box generation }
For each element in the DOM there will be 0 or more boxes in the box tree @ gregwhitworth {layout}
Box Model Padding Box Content Box Border Box Margin Box @ gregwhitworth {layout}
When necessar y, boxes will be generated that are not in the DOM, these are known as anonymous boxes @ gregwhitworth {layout}
{ layout: basic }
DOM Tree Basic Example
<body> <p> width: 50px text node Box Tree CSS Box CSS Box Line Box Line Box Why are there 2 line boxes for the 1 text node? @ gregwhitworth {layout}Basic Example Box Tree CSS Box width: 50px @ gregwhitworth {layout}
<body>Basic Example Box Tree CSS Box CSS Box @ gregwhitworth {layout}
<body> <p>Basic Example Box Tree CSS Box CSS Box Line Box Hello World @ gregwhitworth {layout}
<body> <p>Basic Example Box Tree CSS Box CSS Box Line Box Hello World @ gregwhitworth {layout}
<body> <p>Basic Example Box Tree CSS Box CSS Box Line Box Hello World Line Box @ gregwhitworth {layout}
<body> <p>{ layout: content measure }
fit Context @ gregwhitworth {layout}
Lorem ipsum dolor sit
amet
,
consectetur
ad
adipiscing
elit
.
Nullam
pellentesq
SHARE IT
@
gregwhitworth
{layout}
DOM Tree
<article> <button> <p> Box Tree Text node Text node CSS Box CSS Box CSS Box Line Box LB LB LB @ gregwhitworth {layout}width: 800px padding: 5px Box Tree CSS Box @ gregwhitworth {layout}
<article>Box Tree CSS Box CSS Box Line Box float: left @ gregwhitworth {layout}
<article> <button>Box Tree
CSS Box
Line Box
float: left
background: orange
padding: 3px 10px;
border: 2px solid blue;
margin: 5px;
@
gregwhitworth
{layout}
Box Tree CSS Box Line Box SHARE IT @ gregwhitworth {layout} Max Width SHARE IT Min Width 115px 86px
Box Tree CSS Box CSS Box Line Box SHARE IT @ gregwhitworth {layout}
<article> <button>Box Tree CSS Box CSS Box CSS Box Line Box Line Box SHARE IT @ gregwhitworth {layout}
<article> <button> <p>Box Tree
CSS Box
CSS Box
CSS Box
Line Box
Line Box
@
gregwhitworth
{layout}
Lorem ipsum dolor sit
SHARE IT
amet
,
consectetur
adi
Box Tree
CSS Box
CSS Box
CSS Box
Line Box
LB
LB
@
gregwhitworth
{layout}
Lorem ipsum dolor sit
amet
,
consectetur
SHARE IT
adipiscing
elit
.
Nullam
pell
Box Tree
CSS Box
CSS Box
CSS Box
Line Box
LB
LB
LB
@
gregwhitworth
{layout}
Lorem ipsum dolor sit
amet
,
consectetur
adipiscing
elit
.
Nullam
pellentesq
SHARE IT
{ layout: fragmentation }
A box — such as a page box, column box, or region — that contains a portion (or all) of a fragmented flow. Fragmentainer @ gregwhitworth {layout}
@ gregwhitworth {layout} DOM Tree
<body> <div> Text node Box Tree CSS Box MultiCol Box CSS Box LB LB LB LB LB LB CSS Box LB LB LB LB LBBox Tree CSS Box @ gregwhitworth {layout}
<body>Box Tree CSS Box MultiCol Box @ gregwhitworth {layout}
<body> <div> columns: 2 column - fill: auto; height: 300pxBox Tree CSS Box MultiCol Box CSS Box @ gregwhitworth {layout} Fragmentainer created
<body> <div> columns: 2 column - fill: auto; height: 300pxBox Tree CSS Box MultiCol Box CSS Box @ gregwhitworth {layout} Lorem ipsum dolor sit amet , consectetur adipiscing elit . Cras nibh orci , tincidunt eget enim et, pellentesque condimentum risus . Aenean sollicitudin risus LB LB LB LB LB
<body> <div> columns: 2 column - fill: auto; height: 300pxBox Tree CSS Box MultiCol Box CSS Box @ gregwhitworth {layout} LB LB LB LB LB LB CSS Box
<body> <div> Lorem ipsum dolor sit amet , consectetur adipiscing elit . Cras nibh orci , tincidunt eget enim et, pellentesque condimentum risus . Aenean sollicitudin risus columns: 2 column - fill: auto; height: 300pxfill: auto; height: 300px LB LB LB LB LB LB CSS Box LB LB LB LB LB
<body> <div> Lorem ipsum dolor sit amet , consectetur adipiscing elit . Cras nibh orci , tincidunt eget enim et, pellentesque condimentum risus . Aenean sollicitudin risus{ paint } Compose Paint Layout Style DOM Content Parsing Network YOU ARE HERE
@ gregwhitworth {paint} SHARE IT
@ gregwhitworth {paint} Step 1: Paint the elements background
@ gregwhitworth {paint} Step 2: Paint the element’s border
@ gregwhitworth {paint} Step 3: Paint the element’s content
@ gregwhitworth {paint} SHARE IT
Stacking Context (SC) The order in which the rendering tree is painted onto the canvas is described by stacking contexts @ gregwhitworth {paint}
Stacking Context (SC) Stacking context layers Actually it sort of does though? @ gregwhitworth {paint}
Stacking Context (SC)
¯
(
ツ
)/¯
@
gregwhitworth
{paint}
@ gregwhitworth {paint}
<body> <div id= "one" > Item 1 </div> <div id= "two" > Item 2 </div> </body> HTML CSS div { width : 300px; height : 300px; position : absolute ; background : blue ; z - index : 2; } #two { background : green ; z - index : 1; }Box Tree CSS Box CSS Box CSS Box Line Box @ gregwhitworth {paint} Line Box Item 1 Root Stacking Context Stacking Context
<body> <div> <div> z - index: 2; z - index: 1;index: 1;
<body> <div> <div>index: 1;
<body> <div> <div>index: 1;
<body> <div> <div>index: 1;
<body> <div> <div>index: 1;
<body> <div> <div>{ paint: bounds }
shadow: black 20px 20px Display Node Disp Node width: 420px height: 420px 420px 420px @ gregwhitworth {paint}
{ compose } Compose Paint Layout Style DOM Content Parsing Network YOU ARE HERE
@ gregwhitworth {compose} Large Heading
@ gregwhitworth {paint}
<div class= " clippy " > </div> HTML CSS . clippy { width : 100px; height : 100px; animation : pulse 1s infinite ; background : green ; } @ keyframes pulse { from { transform : scale(1, 1); } to { transform : scale(2, 2) } }@ gregwhitworth {compose} Large Heading Root Composite Layer
@ gregwhitworth {compose} Large Heading
@ gregwhitworth {compose} Large Heading
{ invalidation } Compose DOM Content Parsing Network Style Layout Paint JS Input
@
gregwhitworth
{invalidation}
SHARE IT
CSS
button {
float
:
left;
background
:
orange
;
padding
: 3px 10px;
border
: 2px
solid blue
;
}
button
:hover
{
background
:
green
;
color
:
white
;
}
@ gregwhitworth {invalidation} Hit Testing Algorithm Mouse movement Box Tree button:hover SHARE IT Compose
@ gregwhitworth {invalidation} Mouse move Compose Paint Layout Style DOM Content Parsing Network Hit Testing Algorithm
@ gregwhitworth {layout} Modifying the box model on :hover
@ gregwhitworth {layout} Not modifying the box model on :hover
@ gregwhitworth {invalidation}
@ gregwhitworth {paint} var moved = 0; var tooFar = 500; function move(el) { if( moved <= tooFar ) moved ++; el.style.marginLeft = moved + " px "; } JS
@ gregwhitworth {invalidation} Compose Paint Layout Style DOM Content Parsing Network JS
@ gregwhitworth {paint} #move { width : 300px; height : 300px; background : blue ; animation : move 1s; } @ keyframes { to { transform : translateX (500px); } } CSS
@ gregwhitworth {invalidation} Compose Paint Layout Style DOM Content Parsing Network
{ take aways } @ gregwhitworth {take aways }
@ gregwhitworth {take aways } • Audit your CSS at least twice a year • Remove unused CSS or redundant styles • !important should be a sign that it may be time for a CSS refactor
@ gregwhitworth {take aways } • Try and keep DOM structure as flat as possible • Try and use simple selectors ( eg : ID, classes, tags) • Limit Layout thrashing
@ gregwhitworth {take aways } • Make display only invalidations (layout is computationally heavy) • Elicit feedback on the way you solved the solution
@ gregwhitworth
CSS, it almost feels like magic at times; doesn't it? Well, in order to remove some of that magic let's take a look at the engine and how it handles converting your CSS into the layout of your site.
Here’s what was said about this presentation on social media.
First #cssdevconf session of the afternoon@gregwhitworth: [warp speed brilliant information about DOMs and stuff]
— Newman (@helleaux_newman) October 9, 2017
Me, trying to follow: pic.twitter.com/lMOffDE0Lc
I will get these slides them and use them to pretend I know what the hell I’m talking about for many years to come.
— Newman (@helleaux_newman) October 9, 2017