The Matrix of Layout: CSS Grid

I am rebuilding this website with CSS Grid. I was always afraid of doing CSS because in the early days when I learned CSS, there are just too many weird hacks of using tables/float/whatever with compromised markup (not semantic) to achieve layout.1

But now in 2019, we have CSS Flexbox and CSS Grid, matured solutions (as of 2017, most browsers shipped native, unprefixed support for CSS Grid) for building grid system! I pick Grid over Flexbox since G comes after F. 2

Study

First off, I read this intro post + A Complete Guide to Grid.

Watched this fantastic video to see it in action.

Miriam is a wizard, thank you so much!

Let me quickly show you how awesome it's:

HTML
<header>
  <h1>header</h1>
</header>
<nav>
  <h2>nav</h2>
  <ul>
    <li>item</li>
    <li>item</li>
    <li>item</li>
  </ul>
</nav>
<main>
  <h2>main</h2>
  <p>
    lorem ipsum...
  </p>
</main>
<footer><h2>footer</h2></footer>
CSS

And some additional colors applied3

body {
  min-height: 100vh;
  display: grid;
  grid-gap: 1em;
  grid: 'header' auto
        'nav' auto
        'main' 1fr
        'footer' auto
      / 1fr;
}

@media (min-width: 40em) {
  body {
    grid: 'header header' auto
          'nav main' 1fr
          'nav footer' auto
        / 12em 1fr;
  }
}

header { grid-area: header; }
nav { grid-area: nav; }
main { grid-area: main; }
footer { grid-area: footer; }
Result

NO MORE HACKS. EVERYTHING LOOKS REASONABLE.

I dont remember how many different hacks could achieve this in early days...

Grid Terminologies

I suggest do not use shorthand syntax until you're familiar, it's simialr we first learn how to use margin-top, margin-bottom, margin-left, margin-right, then we grow to use margin. Also it hinders yourself when you are learning something new.

Grid has container and children (element of container, Grid Items). Right now grid only applies to direct children until Subgrid support4 kicks in.

To make a container grid:

display: grid | inline-grid;

The direct elements enclosed by a grid contianer are called Grid Items.

Properties for Grid Items

Grid Column Starts and Ends

grid-column-start: <number> | <name> | span <number> | span <name> | auto;
  grid-column-end: <number> | <name> | span <number> | span <name> | auto;
Grid Column Syntax
grid-column: <start-line> / <end-line> | <start-line> / span <value>;
header img {
  grid-column: 2 / 6
}

Means header image will be at column 2, extends to column 6.

Grid Row Starts and Ends

grid-row-start: <number> | <name> | span <number> | span <name> | auto;
  grid-row-end: <number> | <name> | span <number> | span <name> | auto;
Grid Row
grid-row: <start-line> / <end-line> | <start-line> / span <value>;

Name a Grid

Name a grid item so it can be referenced in grid-template-areas property.

nav {
  grid-area: nav;
}

Also could be a short hand for grid-row-start + grid-column-start + grid-row-end + grid-column-end:

grid-area: 1 / col4-start / last-line / 6

Alignment of Grid item inside Cell

justify-self: start | end | center | stretch;
align-self: start | end | center | stretch;
Properties for Grid Container

Grid Columns and Rows

Defines columns and rows of the grid.

grid-template-columns: <track-size> ... | [<line-name>] <track-size> ...;
grid-template-rows: <track-size> ... | [<line-name>] <track-size> ...;

You can name the grid lines with [<line-name>]:

grid-template-columns: [col0] 40px [col1] 50px;
grid-template-rows: [row0] 25% [row1] 800px [row2] auto;

Grid Gaps

Specifies the size of the grid column/row lines.

grid-column-gap: <size>;
grid-row-gap: <size>;

Shorthand: grid-gap: <grid-row-gap> <grid-column-gap>;

Development

Use Firefox. It comes with an awesome CSS Grid debugging tool as of 2019 November 30, that no other browser has something like it. It can show you grid column and row number. If you applied a grid container property to a grid item, it will show this has no effect.

Result

I rebuilt Travels page with a simple layout using CSS Grid. I will come back to this post as I built more pages.

Resources I'm learning from

Thanks for being here!