Modern Layouts with CSS Grid

Revolutionising visual design on the web

Mozilla
Writing CSS meme
CSS floats meme
CSS inheritence meme
Launch of the web Where the web was born

Web layouts over the years

No layout Table-based layout Float-based layout Panel-style from frameworks

2017: the year of CSS grid

CSS1Recommendation: 17 Dec 1996CSS2Recommendation: 12 May 1998CSS3Decision to modularise: 14 Apr 2000 (26 modules)CSS2.1Recommendation: 7 Jun 2011CSS2.2Working draft: 12 Apr 2016Completed CSS Snapshot 2017 CSS Snapshot 2015 CSS Snapshot 2010 CSS Snapshot 2007 CSS Color Level 3 CSS Namespaces Selectors Level 3 CSS Level 2 Revision 1 CSS Level 1 CSS Print Profile Media Queries CSS Style AttributesTesting CSS Image Values and Replaced Content Level 3 CSS Speech CSS Flexible Box Layout Level 1 CSS Text Decoration Level 3 CSS Shapes Level 1 CSS Masking Level 1 CSS Fragmentation Level 3 CSS Cascading Variables Compositing and Blending Level 1 CSS Syntax Level 3 CSS Grid Layout Level 1 CSS Basic User Interface Level 3 CSS Will Change Level 1 Media Queries Level 4 Geometry Interfaces Level 1 CSS Cascading and Inheritance Level 4 CSS Scroll Snap Level 1 CSS Containment Level 1Refining CSS Animations Web Animations 1.0 CSS Text Level 3 CSS Transforms CSS Transitions CSS Box Alignment Level 3 CSS Display Level 3 Preview of CSS Level 2 CSS Timing Functions Level 1Exploring CSS Backgrounds and Borders Level 4 CSS Device Adaptation CSS Exclusions Filter Effects CSS Generated Content for Paged Media CSS Page Floats CSS Template Layout CSS Line Grid CSS Lists Level 3 CSS Positioned Layout Level 3 CSS Regions CSS Table Level 3 CSS Object Model CSS Font Loading CSS Scoping Level 1 Non-element SelectorsCSS Inline Layout Level 3 Motion Path Level 1 CSS Round Display Level 1 CSS Basic User Interface Level 4 CSS Text Level 4 CSS Painting API Level 1 CSS Properties and Values API Level 1 CSS Typed OM Level 1 Worklets Level 1 CSS Color Level 4 CSS Fonts Level 4 CSS Rhythmic Sizing Level 1 CSS Image Values and Replaced Content Level 4 CSS Fill and Stroke Level 3 CSS Logical Properties and Values Level 1 CSS Overflow Level 4Stable CSS Backgrounds and Borders Level 3 CSS Conditional Rules Level 3 CSS Multi-column Layout Level 1 CSS Values and Units Level 3 CSS Cascading and Inheritance Level 3 CSS Fonts Level 3 CSS Writing Modes Level 3 CSS Counter Styles Level 3Rewriting CSS Basic Box Model Level 3 CSS Generated Content Level 3CSS Snapshot 2017(88 modules)Evolution of CSS Specifications

Team Layout

And more...

Grid versus Flexbox?

Wrong question

Grid AND Flexbox

Flexbox ➡ single dimension

flex-direction: row
flex-direction: column

What is CSS grid?

Defines a two-dimensional grid-based layout system, optimized for user interface design.

Basic terminology

Grid terminology

Flexbox and Grid

Based on the container-child relationship

Flex/Grid containerFlex/Grid item
“Grid works from the container in, other layout methods start with the item
Rachel Andrew

Layout technique: inline-block

Item A

Item B

Item C

Item D

Item E

Item F

Layout technique: float

Item A

Item B

Item C

Item D

Item E

Item F

Layout technique: flex

Item A

Item B

Item C

Item D

Item E

Item F

“Grid is the only layout technique that establishes a relationship between rows and columns of grid items.”

CSS grid basics

Define your grid.

Define a grid

Place items in the grid.

Place items in the grid

Properties on the Grid container

Defining a grid

<div class="grid1">
  <div class="grid1__item">
    <p>Item A</p>
  </div>
  <div class="grid1__item">
    <p>Item B</p>
  </div>
  <div class="grid1__item">
    <p>Item C</p>
  </div>
  <div class="grid1__item">
    <p>Item D</p>
  </div>
  <div class="grid1__item">
    <p>Item E</p>
  </div>
  <div class="grid1__item">
    <p>Item F</p>
  </div>
</div>

Item A

Item B

Item C

Item D

Item E

Item F

“Cede control of your designs to the browsers that render them.”

The fr unit

Represents a fraction of the free space in the grid container.

Item A

Item B

Item C

Fluid CSS grid

.container {
  display: grid;
  grid-template-columns: repeat(3, 3fr 2fr);
}

The minmax() function

Defines a size range for columns or rows in the grid.

Item A

Item B

Item C

The repeat() function

To specify a large number of columns or rows that follow a similar pattern

Item

Item

Item

Item

Item

Item

Item

Item

auto-fill vs. auto-fit

Allow browser to determine how many tracks to create depending on track size.

Auto-fill
repeat(auto-fill, 100px);
Auto-fit
repeat(auto-fit, 100px);

auto-fit collapses empty tracks.

auto-fill versus auto-fit

A

B

C

D

E

F

Responsive grid without media queries

.container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(10em, 1fr));
}

Explicit Grid and Implicit Grid

Implicit grid
.grid-container {
  display: grid;
  grid-template-columns: 150px 150px 150px; /* three columns  */
  grid-template-rows: 150px 150px; /* two rows  */
}

.item {
  grid-column: 5 / 6; /* grid-column-start: 5; grid-column-end: 6;  */
  grid-row:  2 / 3; /* grid-row-start: 2; grid-row-end: 3;  */
}

The browser will create an implicit grid to hold items placed outside the grid.

Aligning your grid items

Property Axis Aligns Applies to
justify-content main/inline

content within element
(effectively adjusts padding)

Content diagram
block containers, flex containers and grid containers
align-content cross/block
justify-self inline

element within parent
(effectively adjusts margins)

Self diagram
block-level boxes, absolutely-positioned boxes and grid items
align-self cross/block absolutely-positioned boxes, flex items and grid items
justify-items inline

items inside box
(controls child items)

Items diagram
block containers and grid containers
align-items cross/block flex-containers and grid-containers

Source: CSS Box Alignment Module Level 3

justify/align-content

content-distribution properties

A
B
C
D
Values justify-content align-content
center justify-content:center align-content:center
start justify-content:start align-content:start
end justify-content:end align-content:end
space-around justify-content:space-around align-content:space-around
space-between justify-content:space-between align-content:space-between
space-evenly justify-content:space-evenly align-content:space-evenly

justify/align-self

self-alignment properties

A
B
C
D

justify/align-items

defaults for justify/align-self

A
B
C
D
Malerei, Fotografie, Film (pg. 126)
Original print version
Recreated with CSS grid
CSS grid web version

Self-alignment properties, maybe?

Self-alignment properties
These are not the borders you are looking for

Flexbox to the rescue

Display flex on grid items
That's more like it

Properties on the grid item

Chessboard

Grid placement with grid lines / named lines

grid-template-columns: [first sidebar-start] 250px [sidebar-end content-start] 1fr [content-end last];
grid-template-rows: [first header-start] 100px [header-end content-start] 1fr [content-end footer-start] 100px [footer-end last];
Named lines

Using grid-column and grid-row

(1) 🍏

(2) 🍊

(3) 🥥

(4) 🥑

(5) 🍇

(6) 🍌

Grid placement with named areas

Named grid areas
.grid-container {
  display: grid;
  grid-template-areas: "logo stats"
                       "score stats"
                       "board board"
                       "... controls";
}

.logo { grid-area: logo; }
.score { grid-area: score; }
.stats { grid-area: stats; }
.board { grid-area: board; }
.controls { grid-area: controls; }

Using grid areas

Item A

Item B

Item C

Vertical whitespace

Braun wide layout
Braun mid-width layout Braun narrow layout
.steuergerät {
  grid-gap: 0.5em;
  grid-template-columns: 50% 50%;
  grid-template-areas: "title title"
                       "text text"
                       "key key"
                       "detail1 detail2"
                       "detail3 detail4";
}

@media screen and (min-aspect-ratio: 1/1) and (min-height: 22em) {
  .steuergerät {
    grid-template-columns: 18.75em 1fr 1fr 1fr;
    grid-template-rows: calc((100vh - 3em) / 3) calc((100vh - 3em) / 3) calc((100vh - 3em) / 3);
    grid-template-areas: "title detail1 key key"
                         "text detail2 key key"
                         "text detail3 detail4 braun";
  }
}

@media screen and (min-aspect-ratio: 8/5) and (min-height: 36em) {
  .steuergerät {
    grid-template-columns: 17.5em 1fr 3fr 1fr 1fr;
    grid-template-rows: calc((100vh - 3em) / 3) calc((100vh - 3em) / 3) calc((100vh - 3em) / 3);
    grid-template-areas: "title . key . ."
                         "text detail1 key detail2 detail3"
                         "text . . detail4 .";
  }
}

Overlap

.container {
  display: grid;
  grid-template-columns: repeat(9, 1.25em);
  grid-template-rows: repeat(6, 1.25em);
}

h2 {
  grid-row: 3 / 5;
  grid-column: 1 / 10;
}

.container::before {
  grid-row: 1 / 7;
  grid-column: 1 / 7;
}

.container::after {
  grid-row: 1 / 7;
  grid-column: 4 / 10;
}

Building a grid layout

Tycho artist blog/profile concept

Design credit: Drew Sullivan

Planning the grid
Good ol' pencil and paper
Markup only
Markup without any CSS
General styles
Basic styles
“Websites do NOT have to look the same in every browser.”
Fallback for browsers without grid
Fallback layout
main {
  max-width: 45em;
  margin: 0 auto;
  position: relative;
  padding: 1em;
}

_:-ms-input-placeholder, :root main {
  display: block;
}

h1 {
  margin-bottom: 0.25em;
}

h2 {
  margin-bottom: 1em;
}

.about {
  margin-bottom: 1em;
}

a {
  margin-bottom: 2em;
}

button {
  padding: 1em 2em;
  position: absolute;
  right: 1em;
  bottom: 1em;
}
Grid layout styles
CSS grid in action
@supports (display:grid) {
  @media (min-width: 42em) and (min-height: 27em) {
    main {
      max-width: none;
      padding: 0;
      display: grid;
      grid-template-columns: 2fr minmax(10em, max-content) minmax(14em, max-content) minmax(1em, 1fr) fit-content(28em) calc(2em + 0.5vw);
      grid-template-rows: 35vh 40vh 15vh 10vh;
    }

    h1 {
      grid-column: 3 / 6;
      grid-row: 1 / 2;
      z-index: 2;
      padding-left: 0.25em;
      margin-bottom: initial;
    }

    h2 {
      grid-row: 1 / -1;
      grid-column: 6 / 7;
      writing-mode: vertical-rl;
      margin-bottom: initial;
      color: $text;
    }

    hr {
      grid-column: 5 / 6;
      grid-row: 2;
      height: 6px;
      background-color: $text;
      width: 20ch;
    }

    .about {
      grid-column: 5 / 6;
      grid-row: 2;
      align-self: end;
      padding-bottom: 4vh;
      margin-bottom: initial;
    }

    a {
      grid-column: 5 / 6;
      justify-self: end;
      align-self: center;
      margin-bottom: initial;

      &::before {
        content: '';
        display: block;
        height: 4px;
        background-color: $accent;
        width: 4ch;
        margin-bottom: 1em;
      }
    }

    img {
      grid-column: 1 / 4;
      grid-row: 1 / 4;
    }

    .location {
      grid-column: 3 / 4;
      grid-row: 3 / 4;
      z-index: 2;
      background: $main;
      text-align: center;
      display: flex;

      p {
        margin: auto;
      }
    }

    button {
      grid-column: 2 / 3;
      grid-row: 4 / 5;
      position: initial;
      padding: 0;
    }
  }

  @media (min-width: 48em) {
    hr {
      opacity: 1;
    }
  }
}

Fallback with feature queries

A conditional group rule whose condition tests whether the user agent supports CSS property: value pairs.

Anatomy of a feature query

.selector {
  /* Styles that are supported in old browsers */
}

@supports (property:value) {
  .selector {
    /* Styles for browsers that support the specified property */
  }
}

Browser support for @supports

header::before {
  content: 'This example requires a browser that supports CSS Flexbox or Grid. If your browser did support CSS Grid, you would have seen something that resembles the image below, except recreated in HTML and CSS instead.';
  display: inline-block;
  background-color: rgba(253, 182, 182, 0.75);
  font-size: initial;
  max-width: 36em;
  color: #000;
  padding: 0.5em;
}

header > * {
  display: none;
}

header {
  background-color: $background;
  background-image: url('./fallback.png');
  background-size: contain;
  background-repeat: no-repeat;
  background-position: bottom;
  overflow: hidden;
  max-height: 60vh;
  position: relative;
}
@supports (display: flex) {
  header::before {
    content: none;
  }

  header {
    background-image: none;
  }

  .grid {
    display: block;
  }

  .title {
    color: $txt-light;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    font-size: 2.5em;
    z-index: 1;
    padding-right: 0.25em;
  }

  .time {
    color: $txt-dark;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 0.5em;
  }

  .grid__item:nth-of-type(1) {
    background-color: $blue;
    width: 30vw;
  }

  .grid__item:nth-of-type(2) {
    background-color: $purple;
    width: 45vw;
  }

  .grid__item:nth-of-type(3) {
    background-color: $yellow;
    width: 60vw;
    position: relative;
    z-index: 2;
  }

  .time {
    width: calc(100% / 9);
    float: left;
    padding: 1em;
  }

  .time:nth-child(8) {
    position: relative;

    &::before {
      display: block;
      content: '';
      height: 3.5em;
      width: 3.5em;
      border-radius: 50%;
      position: absolute;
      border: 0.2em solid $blue;
      z-index: 1;
    }
  }

  .border {
    width: 0.2em;
    background-color: $red;
    position: absolute;
    top: 0;
    height: 100%;
    left: calc((100% / 9) * 7);
  }
}
@supports (display:grid) {
  .time {
    grid-row: 7;
  }

  .grid {
    display: grid;
    grid-template-columns: repeat(9, 1fr);
    grid-template-rows:  repeat(3, 2em) repeat(3, minmax(10vmin, 3em)) 2em 2em 10vh;
    grid-gap: 0.125em;
    position: relative;
  }

  @media screen and (min-width: 480px) {
    .grid {
      transform: rotate(-30deg) translateX(5vh);
      grid-template-rows:  repeat(3, 2em) repeat(3, minmax(10vmin, 3em)) 2em 2em 50vh;
    }
  }

  @media screen and (min-width: 640px) {
    .grid {
      transform: rotate(-30deg) translateY(-15vh);
    }
  }

  .grid__item:nth-of-type(1) {
    grid-row: 4;
    grid-column: span 3;
    width: auto;
  }

  .grid__item:nth-of-type(2) {
    grid-row: 5;
    grid-column: span 5;
    width: auto;
  }

  .grid__item:nth-of-type(3) {
    grid-row: 6;
    grid-column: span 7;
    width: auto;
  }

  .border {
    grid-row: 1 / -1;
    grid-column: 8;
    margin-left: -0.125em;
    width: 1px;
    border-left: 0.2em solid $red;
    left: initial;
  }

  .square1 {
    grid-column: 2;
    position: relative;
    
    &::before {
      display: block;
      content: '';
      height: 1.25em;
      width: 1.25em;
      border: 0.2em solid $purple;
      position: absolute;
      right: 0;
    }
  }

  .square2 {
    grid-column: 3;
    grid-row: 2;
    position: relative;

    &::before {
      display: block;
      content: '';
      height: 0.5em;
      width: 0.5em;
      background-color: $green;
      position: absolute;
      right: 1em;
      top: 1em;
    }
  }

  .circle {
    grid-column: 2;
    grid-row: 3;
    position: relative;
    
    &::before {
      display: block;
      content: '';
      border: 0.2em solid $yellow;
      border-radius: 50%;
      position: absolute;
      height: 4em;
      width: 4em;
      top: calc(50% -  0.5em);
      left: calc(50% - 2em);
    }
  }

  .square3 {
    grid-column: 8;
    grid-row: 6;
    position: relative;

    &::before {
      display: block;
      content: '';
      height: 0.75em;
      width: 0.75em;
      background-color: $yellow;
      position: absolute;
      right: 0;
      top: 1em;
    }
  }

  .square4 {
    grid-column: 6;
    grid-row: 8;
    position: relative;

    &::before {
      display: block;
      content: '';
      height: 1.5em;
      width: 1.5em;
      position: absolute;
      right: 0;
      top: 100%;
      border: 0.2em solid $green;
    }
  }
}
“CSS isn't a programming language. It's a stylesheet language. We shouldn't expect it to behave like a programming language. It has its own unique landscape and structures, ones that people with programming language mental maps might not expect.”
—Danielle Huntrods

Demos and examples

Useful references

Thank you!

Websitehttps://www.chenhuijing.com

Twitter@hj_chen

Medium@hj_chen

Codepen@huijing