A presentation at WordCamp Bristol in in Bristol, UK by Michelle Barker
Building Intelligent Layouts with CSS Grid @MicheBarks
“Intrinsic Web Design” Jen Simmons @MicheBarks
@MicheBarks
@MicheBarks
@MicheBarks
Why do we need Grid? 2D layout @MicheBarks
Why do we need Grid? Grid systems @MicheBarks
“Flexbox is great for taking a bunch of oddly-sized things and returning the most reasonable layout for those things” Rachel Andrew @MicheBarks
Why do we need Grid? Grid systems @MicheBarks
Why do we need Grid? Grid systems Fewer dependencies @MicheBarks
Why do we need Grid? Complete control @MicheBarks
Grid terminology @MicheBarks
Grid terminology Grid display: grid; @MicheBarks
Grid terminology Tracks grid-template-rows @MicheBarks
Grid terminology Tracks grid-template-columns @MicheBarks
Grid terminology Cells @MicheBarks
Grid terminology Grid areas @MicheBarks
Grid terminology Gutters column-gap (Formerly grid-column-gap) @MicheBarks
Grid terminology Gutters row-gap (Formerly grid-row-gap) @MicheBarks
Defining a grid @MicheBarks
CSS .grid { display: grid; } @MicheBarks codepen.io/michellebarker/pen/eLZwVg
CSS .grid { display: grid; grid-template-columns: 200px 200px 200px 200px; grid-template-rows: 150px 150px 150px 150px; } @MicheBarks codepen.io/michellebarker/pen/eLZwVg
CSS .grid { display: grid; grid-template-columns: 200px 200px 200px 200px; grid-template-rows: 150px 150px 150px 150px; column-gap: 20px; row-gap: 20px; } @MicheBarks codepen.io/michellebarker/pen/eLZwVg
@MicheBarks codepen.io/michellebarker/pen/eLZwVg
CSS repeat() .grid { display: grid; grid-template-columns: repeat(4, 200px); grid-template-rows: repeat(4, 150px); } @MicheBarks grid-gap: 20px; codepen.io/michellebarker/pen/eLZwVg
CSS Shorthand .grid { display: grid; grid-template: repeat(4, 150px) / repeat(4, 200px); } @MicheBarks codepen.io/michellebarker/pen/eLZwVg
CSS Shorthand .grid { display: grid; grid-template: repeat(4, 150px) / repeat(4, 200px); gap: 20px; // row-gap / column-gap } @MicheBarks codepen.io/michellebarker/pen/eLZwVg
CSS Fraction units (fr) .grid { display: grid; grid-template-columns: repeat(4, 1fr); } @MicheBarks grid-template-rows: repeat(4, 150px); gap: 20px; codepen.io/michellebarker/pen/eLZwVg
Fr = fraction units a fraction of the leftover space in the grid container @MicheBarks
CSS Fraction units (fr) .grid { display: grid; grid-template-columns: repeat(4, 1fr); } @MicheBarks grid-template-rows: repeat(4, 150px); gap: 20px; codepen.io/michellebarker/pen/eLZwVg
grid-template-columns: repeat(3, 1fr) 2fr; 1fr @MicheBarks 1fr 1fr 2fr
CSS Fraction units (fr) .grid { display: grid; grid-template-columns: repeat(3, 200px) 1fr; } @MicheBarks grid-template-rows: repeat(4, 150px); gap: 20px;
200px @MicheBarks 200px 200px 1fr
Implicit vs Explicit tracks @MicheBarks
CSS Implicit tracks .grid { display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: 150px; } @MicheBarks gap: 20px; codepen.io/michellebarker/pen/eLZwVg
CSS Implicit tracks .grid { display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: repeat(4, 150px); grid-auto-rows: 150px; } @MicheBarks gap: 20px; codepen.io/michellebarker/pen/eLZwVg
@MicheBarks codepen.io/michellebarker/pen/eLZwVg
Placing items @MicheBarks
HTML Auto-placement <div class=”grid”> <div class=”grid__item”>1</div> <div class=”grid__item”>2</div> <div class=”grid__item”>3</div> </div> @MicheBarks codepen.io/michellebarker/pen/gdrVXP
@MicheBarks codepen.io/michellebarker/pen/gdrVXP
HTML Placing items by grid line <div class=”grid”> <header></header> <main></main> <aside></aside> </div> @MicheBarks
@MicheBarks codepen.io/michellebarker/pen/YOqmjP
CSS Placing items by grid line header { grid-column-start: 1; grid-column-end: 5; } @MicheBarks codepen.io/michellebarker/pen/YOqmjP
@MicheBarks codepen.io/michellebarker/pen/YOqmjP
CSS Placing items by grid line main { grid-column-start: 1; grid-column-end: 4; grid-row-start: 2; grid-row-end: 5; } aside { grid-column-start: 4; grid-column-end: 5; grid-row-start: 2; grid-row-end: 4; } @MicheBarks codepen.io/michellebarker/pen/YOqmjP
@MicheBarks codepen.io/michellebarker/pen/YOqmjP
CSS header { grid-column: 1 / 5; } main { grid-column: 1 / 4; grid-row: 2 / 5; } aside { // grid-column: 4 / 5; - unnecessary as will be auto-placed grid-row: span 2; } @MicheBarks codepen.io/michellebarker/pen/YOqmjP
@MicheBarks codepen.io/michellebarker/pen/YOqmjP
CSS Start line / end line main { grid-column: 1 / 4; grid-row: 2 / 4; } @MicheBarks codepen.io/michellebarker/pen/YOqmjP
CSS Span (with auto-placement) main { grid-column: span 3; grid-row: 2 / 4; } @MicheBarks codepen.io/michellebarker/pen/YOqmjP
CSS Start line / span main { grid-column: 1 / span 3; grid-row: 2 / 4; } @MicheBarks codepen.io/michellebarker/pen/YOQLLZ
CSS Span / end line main { grid-column: span 3 / 4; grid-row: 2 / 4; } @MicheBarks codepen.io/michellebarker/pen/YOqmjP
CSS Naming grid lines .grid { display: grid; grid-template-columns: [header-start main-start] repeat(3, 1fr) [main-end] 1fr [header-end]; grid-auto-rows: 150px; } @MicheBarks codepen.io/michellebarker/pen/OobJaa
header-start main-start @MicheBarks main-end header-end codepen.io/michellebarker/pen/OobJaa
CSS header { grid-column: header; } main { grid-column: main; grid-row: span 3; } @MicheBarks codepen.io/michellebarker/pen/rqZevv
CSS grid-template-areas .grid { display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: 150px; grid-template-areas: gap: 20px; } @MicheBarks “h “m “m “m h m m m h m m m h” a” a” .”;
CSS grid-template-areas header { grid-area: h; } main { grid-area: m; } aside { grid-area: a; } @MicheBarks
Building a Complex Component A Case Study @MicheBarks
@MicheBarks
@MicheBarks
@MicheBarks
@MicheBarks
HTML
<div class=”grid”> <h2 class=”grid__heading”></h2> <figure class=”grid__image”></figure> <div class=”grid__body”></div> </div> @MicheBarksSome rules @MicheBarks
Dynamic content @MicheBarks
The heading must always be vertically centred over the image @MicheBarks
The heading must always be vertically centred over the image …no matter the size of the image or the text @MicheBarks
Text block must align to the top of the image @MicheBarks
Text block must align to the top of the image …unless the text is too long @MicheBarks
Space must always be maintained between the text block and heading @MicheBarks
Context-aware @MicheBarks
CSS Grid 2D Layout @MicheBarks
@MicheBarks
@MicheBarks
@MicheBarks
@MicheBarks
grid-template-columns: repeat(26, 1fr); @MicheBarks
grid-template-columns: repeat(26, 1fr); @MicheBarks
1fr @MicheBarks repeat(24, 60px) 1fr
grid-template-columns: 1fr repeat(24, 60px) 1fr; @MicheBarks
minmax() minmax(20px, 1fr) Minimum size @MicheBarks Maximum size
minmax(20px, 1fr) minmax(0, 60px) @MicheBarks codepen.io/michellebarker/pen/wYGMPQ
grid-template-columns: minmax(20px, 1fr) repeat(24, minmax(0, 60px)) minmax(20px, 1fr); @MicheBarks
grid-template-columns: minmax(20px, 1fr) repeat(24, minmax(0, 60px)) minmax(20px, 1fr); @MicheBarks
grid-template-columns: minmax(20px, 1fr) repeat(24, minmax(0, 60px)) minmax(20px, 1fr); @MicheBarks
CSS .grid { display: grid; grid-template-columns: minmax(20px, 1fr) // flexible outer column repeat(24, minmax(0, 60px)) // 24 central columns minmax(20px, 1fr); // flexible outer column column-gap: 20px; } @MicheBarks
grid-template-rows: 1fr auto 1fr; @MicheBarks
CSS .grid { display: grid; grid-template-columns: minmax(20px, 1fr) repeat(24, minmax(0, 60px)) minmax(20px, 1fr); grid-template-rows: 1fr auto 1fr; } @MicheBarks column-gap: 20px;
CSS .grid { display: grid; grid-template-columns: minmax(20px, 1fr) repeat(24, minmax(0, 60px)) minmax(20px, 1fr); grid-template-rows: 1fr auto 1fr; gap: 40px 20px; } @MicheBarks
CSS Placing items .grid { grid-template-columns: [outer-start] minmax(20px, 1fr) [wrapper-start] repeat(24, minmax(0, 60px)) [wrapper-end] minmax(20px, 1fr) [outer-end]; grid-template-rows: 1fr [heading-start] auto [heading-end] 1fr; … } @MicheBarks
CSS Placing items .grid { grid-template-columns: [outer-start] minmax(20px, 1fr) [wrapper-start] repeat(24, minmax(0, 60px)) [wrapper-end] minmax(20px, 1fr) [outer-end]; grid-template-rows: 1fr [heading-start] auto [heading-end] 1fr; … } @MicheBarks
CSS Placing items .grid { grid-template-columns: [outer-start] minmax(20px, 1fr) [wrapper-start] repeat(24, minmax(0, 60px)) [wrapper-end] minmax(20px, 1fr) [outer-end]; grid-template-rows: 1fr [heading-start] auto [heading-end] 1fr; … } @MicheBarks
CSS .grid__image { grid-column: wrapper-start / 14; grid-row: 1 / -1; } .grid__body { grid-column: span 5 / wrapper-end; grid-row: 1; align-self: flex-start; } .grid__heading { grid-column: 5 / -5; grid-row: heading; } @MicheBarks
CSS .grid__image { grid-column: wrapper-start / 14; grid-row: 1 / -1; } .grid__body { grid-column: span 5 / wrapper-end; grid-row: 1; align-self: flex-start; } .grid__heading { grid-column: 5 / -5; } @MicheBarks grid-row: heading;
CSS .grid__image { grid-column: wrapper-start / 14; grid-row: 1 / -1; } .grid__body { grid-column: span 5 / wrapper-end; grid-row: 1; align-self: flex-start; } .grid__heading { grid-column: 5 / -5; grid-row: heading; } @MicheBarks
@MicheBarks
@MicheBarks
I didn’t solve this problem @MicheBarks
Gutter rows @MicheBarks
Secret hidden row @MicheBarks
grid-template-rows: 1fr auto 40px auto 40px auto; @MicheBarks
grid-template-rows: 1fr auto 40px auto 40px auto; @MicheBarks
@MicheBarks
@MicheBarks
CSS .grid { … grid-template-rows: [text-start] 1fr auto [text-end] 40px // gap [heading-start] auto [heading-start] 40px // gap auto; … } @MicheBarks
.grid__body { grid-row: text; } @MicheBarks
@MicheBarks
grid-template-rows: auto 40px auto 40px auto 1fr; Secret hidden row @MicheBarks
CSS .grid—text-bottom { grid-template-rows: auto 40px [heading-start] auto [heading-end] 40px [text-start] auto 1fr [text-end]; // hidden row } @MicheBarks
CSS .grid—text-bottom .grid__body { align-self: flex-end; } @MicheBarks
CSS .grid—text-bottom { grid-template-rows: [media-start] auto 40px [heading-start] auto [heading-end] 40px [text-start] auto [media-end] 1fr [text-end]; } Component variants .grid—text-bottom .grid__body { align-self: flex-end; } @MicheBarks @mbarker_84
SCSS /* Second variant of our component */ .grid—2 { .grid__image { grid-column: 13 / outer-end; } .grid__body { grid-column: wrapper-start / span 5; } } @MicheBarks
CSS Variables (a.k.a. Custom Properties) @MicheBarks
Dynamic variables
CSS Defining variables :root { —bgColor: red; } @MicheBarks
CSS Using variables .my-component { background-color: var(—bgColor); } @MicheBarks
CSS .grid__image { grid-column: var(—imageColStart) / var(—-imageColEnd); grid-row: media; } .grid__body { grid-column: var(—textColStart) / span 5; grid-row: text; } @MicheBarks
CSS .grid__image { grid-column: var(—imageColStart) / var(—imageColEnd); } grid-row: media; .grid__body { grid-column: var(—textColStart) / span 5; grid-row: text; } @MicheBarks
CSS .grid__image { grid-column: var(—mediaColStart) / var(—mediaColEnd); grid-row: media; } .grid__body { grid-column: var(—textColStart) / span 5; } @MicheBarks grid-row: text;
CSS .grid { —imageColStart: wrapper-start; —imageColEnd: 14; —textColStart: -8; } .grid—-2 { —imageColStart: 13; —imageColEnd: outer-end; —textColStart: 3; } @MicheBarks
codepen.io/michellebarker/pen/yGzWme @MicheBarks
Resources Grid by Example (Rachel Andrew) gridbyexample.com Layout Land (Jen Simmons) layout.land CSS Grid Playground (MDN) mozilladevelopers.github.io/playground/css-grid CSS { In Real Life } css-irl.info @MicheBarks
Thank you for listening @MicheBarks / @CSSInRealLife
The CSS Grid Layout Module Level 1 (CSS Grid) has given developers the tools to build complex layouts with relatively little code. It affords us complete control over layout behaviour and positioning of items in two dimensions. At the same time, it has given us many more CSS properties to learn and understand, which can be overwhelming. How do you figure out the best way to build a layout when faced with so much choice?
In this talk, Michelle will demystify some of the new terminology, properties, and functions that have arrived with CSS Grid. We’ll bust some common myths and look at how we can harness these new tools to build robust layouts, even with dynamic content. We’ll take an in-depth look at a real-world example of a complex layout, and in the process learn about the superpowers that Grid provides us with.