A presentation at Women Who Code in in Bristol, UK by Michelle Barker
Building Challenging Layouts with CSS Grid
Why do we need CSS Grid?
Intrinsic Web Design
Grid terminology
Grid display: grid;
Tracks grid-template-rows
Tracks grid-template-columns
Cells
Grid areas
Gutters column-gap (Formerly grid-column-gap)
Gutters row-gap (Formerly grid-row-gap)
Defining a grid
On the container: .grid { display: grid; grid-template-columns: 200px 200px 200px 200px; grid-template-rows: 150px 150px 150px 150px; } codepen.io/michellebarker/pen/eLZwVg
On the container: .grid { display: grid; grid-template-columns: 200px 200px 200px 200px; grid-template-rows: 150px 150px 150px 150px; column-gap: 20px; row-gap: 20px; } codepen.io/michellebarker/pen/eLZwVg
codepen.io/michellebarker/pen/eLZwVg
repeat() .grid { display: grid; grid-template-columns: repeat(4, 200px); grid-template-rows: repeat(4, 150px); } grid-gap: 20px; codepen.io/michellebarker/pen/eLZwVg
Shorthand .grid { display: grid; grid-template: repeat(4, 150px) / repeat(4, 200px); } codepen.io/michellebarker/pen/eLZwVg
Shorthand .grid { display: grid; grid-template: repeat(4, 150px) / repeat(4, 200px); gap: 20px; // row-gap / column-gap } codepen.io/michellebarker/pen/eLZwVg
Flexible units (fr) .grid { display: grid; grid-template-columns: repeat(4, 1fr); } grid-template-rows: 150px; gap: 20px; codepen.io/michellebarker/pen/eLZwVg
Fr a fraction of the leftover space in the grid container
Flexible units (fr) .grid { display: grid; grid-template-columns: repeat(4, 1fr); } grid-template-rows: repeat(4, 150px); gap: 20px; codepen.io/michellebarker/pen/eLZwVg
Flexible units (fr) .grid { display: grid; grid-template-columns: repeat(3, 200px) 1fr; } grid-template-rows: 150px; grid-gap: 20px; codepen.io/michellebarker/pen/wEdjqX
Flexible units (fr) codepen.io/michellebarker/pen/wEdjqX
Implicit / Explicit tracks
Implicit tracks .grid { display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: 150px; } gap: 20px; codepen.io/michellebarker/pen/eLZwVg
Implicit tracks .grid { display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: repeat(4, 150px); grid-auto-rows: 150px; } gap: 20px; codepen.io/michellebarker/pen/eLZwVg
codepen.io/michellebarker/pen/eLZwVg
Placing items
Auto placement
<div class="grid"> <div class="grid__item">1</div> <div class="grid__item">2</div> <div class="grid__item">3</div> </div> codepen.io/michellebarker/pen/gdrVXPcodepen.io/michellebarker/pen/gdrVXP
Placing items by grid line <div class="grid"> <header></header> <main></main> <aside></aside> </div>
codepen.io/michellebarker/pen/YOqmjP
Placing items by grid line header { grid-column-start: 1; grid-column-end: 5; } codepen.io/michellebarker/pen/YOqmjP
codepen.io/michellebarker/pen/YOqmjP
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; } codepen.io/michellebarker/pen/YOqmjP
codepen.io/michellebarker/pen/YOqmjP
Placing items by grid line 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; } codepen.io/michellebarker/pen/YOqmjP
codepen.io/michellebarker/pen/YOqmjP
Placing items by grid line Start line / end line main { grid-column: 1 / 4; grid-row: 2 / 4; } codepen.io/michellebarker/pen/YOqmjP
Placing items by grid line Span (with auto-placement) main { grid-column: span 3; grid-row: 2 / 4; } codepen.io/michellebarker/pen/YOqmjP
Placing items by grid line Start line / span main { grid-column: 1 / span 3; grid-row: 2 / 4; } codepen.io/michellebarker/pen/YOQLLZ
Placing items by grid line Span / end line main { grid-column: span 3 / 4; grid-row: 2 / 4; } codepen.io/michellebarker/pen/YOqmjP
Naming lines .grid { display: grid; grid-template-columns: [header-start main-start] repeat(3, 1fr) [main-end] 1fr [header-end]; grid-auto-rows: 150px; } codepen.io/michellebarker/pen/OobJaa
header-start main-start main-end header-end codepen.io/michellebarker/pen/OobJaa
Naming lines header { grid-column: header-start / header-end; } main { grid-column: main-start / main-end; grid-row: span 3; }
Naming lines header { grid-column: header; } main { grid-column: main grid-row: span 3; } codepen.io/michellebarker/pen/rqZevv
grid-template-areas .grid { display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: 150px; grid-template-areas: "h h h h" "m m m a" "m m m a” "m m m a” "m m m .”; gap: 20px; }
grid-template-areas header { grid-area: h; } main { grid-area: m; } aside { grid-area: a; }
CSS Grid for Complex Components A Case Study wbsl.com
Requirements - 24-column grid - 9 variants - Grid items can align with content wrapper, inner columns or outer edge - Heading must be vertically centred - Text can be above or below the heading - Text should align to top/bottom of image unless the content is longer than the available space - Responsive (of course)
Unknowns
Requirements - 24-column grid - 9 variants - Grid items can align with content wrapper, inner columns or outer edge - Heading must be vertically centred - Text can be above or below the heading (controlled in CMS) - Text should align to top/bottom of image unless the content is longer than the available space - Responsive (of course)
Requirements - 24-column grid - 9 variants - Grid items can align with content wrapper, inner columns or outer edge - Heading must be vertically centred - Text can be above or below the heading (controlled in CMS) - Text should align to top/bottom of image unless the content is longer than the available space - Responsive (of course)
.grid { display: grid; grid-template-columns: repeat(26, 1fr); column-gap: 20px; }
1fr 1fr repeat(24, 60px)
.grid { display: grid; grid-template-columns: 1fr // flexible outer column repeat(24, 60px) // 24 central columns 1fr; // flexible outer column column-gap: 20px; }
minmax() minmax(20px, 1fr) Minimum size Maximum size
minmax() minmax(20px, 1fr) minmax(0, 60px) codepen.io/michellebarker/pen/wYGMPQ
.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; }
Responsive (of course)
.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; }
1fr auto 1fr
.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; }
.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; } align-items: center; // Vertically centre our image and heading
.grid { display: 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; gap: 40px 20px; align-items: center; }
Placing items .grid__media { 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; }
.grid { display: 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: auto auto auto; gap: 40px 20px; align-items: center; }
.grid { display: 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: auto 40px auto 40px auto; gap: 0 20px; align-items: center; }
.grid { display: 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: auto 40px auto 40px auto; gap: 0 20px; }
.grid { display: 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 auto 40px auto 40px auto; gap: 0 20px; }
1fr auto 40px auto 40px auto
.grid { display: grid; grid-template-columns: [outer-start] minmax(20px, 1fr) [wrapper-start] repeat(24, minmax(0, 40px)) [wrapper-end] minmax(20px, 1fr) [outer-end]; grid-template-rows: [text-start] 1fr [media-start] auto [text-end] 40px [heading-start] auto [heading-end] 40px auto [media-end]; gap: 0 20px; }
.grid__media { grid-column: wrapper-start / 14; grid-row: media; } .grid__body { grid-column: span 5 / -3; grid-row: text; align-self: flex-start; } .grid__heading { grid-column: 5 / -5; grid-row: heading; }
.grid { grid-template-rows: [text-start] 1fr // hidden row [media-start] auto [text-end] 40px [heading-start] auto [heading-end] 40px auto [media-end]; } .grid--text-bottom { grid-template-rows: [media-start] auto 40px [heading-start] auto [heading-end] 40px [text-start] auto [media-end] 1fr [text-end]; // hidden row }
.grid--text-bottom { grid-template-rows: [media-start] auto 40px [heading-start] auto [heading-end] 40px [text-start] auto [media-end] 1fr [text-end]; // hidden row } .grid--text-bottom .grid__body { align-self: flex-end; }
.grid--text-bottom
Variants /* Second variant of our component */ .grid--2 { .grid__media { grid-column: 13 / outer-end; } .grid__body { grid-column: wrapper-start / span 5; } }
Requirements ✓ 24-column grid ✓ 9 variants ✓ Grid items can align with content wrapper, inner columns or outer edge ✓ Heading must be vertically centered ✓ Text can be above or below the heading (controlled in CMS) ✓ Text should align to top/bottom of image unless the content is longer than the available space - Responsive (of course)
CSS Variables (a.k.a. Custom Properties)
Dynamic variables
Defining variables :root { --bgColor: red; }
Using variables .my-component { background-color: var(--bgColor); }
Using variables for item placement .grid__media { grid-column: var(--mediaColStart) / var(--mediaColEnd); grid-row: media; } .grid__body { grid-column: var(--textColStart) / span 5; grid-row: text-top; }
Using variables for item placement .grid { --mediaColStart: wrapper-start; --mediaColEnd: 14; --textColStart: wrapper-end; } .grid—-2 { --mediaColStart: 13; --mediaColEnd: wrapper-end; --textColStart: wrapper-start; }
Requirements ✓ 24-column grid ✓ 9 variants ✓ Grid items can align with content wrapper, inner columns or outer edge ✓ Heading must be vertically centred ✓ Text can be above or below the heading (controlled in CMS) ✓ Text should align to top/bottom of image unless the content is longer than the available space - Responsive (of course)
https://codepen.io/michellebarker/pen/yGzWme
Wrapping up
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
Thank you for listening @mbarker_84 / @CSSInRealLife
When it comes to crafting layouts on the web, CSS Grid is more powerful than anything we’ve had available to us before. In this talk I’ll look at ways in which we can harness the power of Grid to tackle complex layout challenges and build responsive, two-dimensional components. I’ll also demonstrate how we can use CSS variables to keep our Grid code DRY, reusable and maintainable.