Skip to content

Instantly share code, notes, and snippets.

@pixelspencil
Last active March 22, 2021 23:51
Show Gist options
  • Select an option

  • Save pixelspencil/d9bb47db693ec48bec5ee3ffcf778d72 to your computer and use it in GitHub Desktop.

Select an option

Save pixelspencil/d9bb47db693ec48bec5ee3ffcf778d72 to your computer and use it in GitHub Desktop.
CSS Grid 101

CSS Grid 101

Gaps

  • You can set gaps between your rows and columns
  • They only apply to the inner tracks
  • Outer tracks stay flush against the edges like we want them to 99% of the time.
<div class="container">
  <div class="item orange"></div>
  <div class="item blue"></div>
  <div class="item purple"></div>
</div>
    .container {
      outline: 5px solid black;
      display: grid;
      width: 500px;
      height: 300px;
      gap: 30px;
    }
  • Gaps handle disabling margins on first/last children
  • Gaps also handle when content shifts to multiple lines
  • People behind spec are currently working to enable gaps in flexbox.


Named Grid Lines

  • Grid provides a way to size and position everything that goes into the grid.
  • Items can span forwards or backwards, overlap with other items, span multiple columns or rows, etc.
  • Further reading: Naming Your CSS Grid Lines


Fraction Units

  • The fr unit can only be used in a grid.
  • Different from percentages and viewport units ( vw, vh) etc.
  • When assigning a column or row a fraction unit, it is basically saying take up a certain fraction of the free space left over after all other tracks/gaps take their fixed space.
  • The first (orange) column is set to 50px wide
  • The grid is set to have 10px gaps between tracks
  • This lets the second (blue) column take up 1 fraction of remaining space
  • The last (purple) column takes up 2 fractions of remaining space.
<div class="container">
  <div class="item orange"></div>
  <div class="item blue"></div>
  <div class="item purple"></div>
</div>
.container{
  outline: 5px solid black;
  display: inline-grid;
  width: 300px;
  height: 300px;
  gap: 10px;
  grid-template-columns: 50px 1fr 2fr;
}

The math

  • gridWidth = 300px
  • totalGaps = gridGap (10px) * 2 = 20px;
  • column1Width [orange] = 50px;
  • freeSpace = gridWidth - totalGaps - column1Width = 230px
  • numFRUnits = 3 (the sum of all the fr units used in the grid columns)
  • column2Width = freeSpace * ( 1(fr) / numFRUnits) —-> 230 * (1 / 3) = 76.66px
  • column3Width = freeSpace * ( 2(fr) / numFRUnits) —-> 230 * (2 / 3) = 153.33px

Notes

  • fr units place nicely with all other units.
  • Unlike percentages (which are based on the size of the Grid container), fractions are based only on the free space that’s left. - You won’t accidentally cause overflow/scroll issues like you might if you used percentages.

It’s easy to think fr units are just like flexbox’s flex-grow, but there’s a big difference.



Minmax

Idea/future

Imagine being able to set a range for your padding, at least 10px but no more than 10%.

  element {
    padding: minmax(10px, 10%)
  }


Implicit Tracks

  • Implicit tracks are auto-generate tracks that default to a size of auto
  • You do not need to explicitly spell out a new column or row for each item that will go into your grid
  • You just define the template using grid-template-rows and grid-template-columns.
  • When your grid has more stuff in it than what was defined, it will go ahead and create new columns & rows beyond what was specified
  • In the example below the purple item does not have any content, it's only size is it's borders
  • The grid spec allows us to specify exactly how we want any auto-generated implicit tracks to behave
  • We only define two columns and one row (two cells total).
  • When a third item went into the grid it created a new second row automatically
<div class="container">
  <div class="item orange"></div>
  <div class="item blue"></div>
  <div class="item purple"></div>
</div>
.container{
  outline: 5px solid black;
  display: inline-grid;
  width: 300px;
  height: 300px;
  gap: 10px;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr;
}
  • Same example but this time telling our Grid to make any new rows take up an equal share of the available space, using grid-auto-rows: 1fr;
<div class="container">
  <div class="item orange"></div>
  <div class="item blue"></div>
  <div class="item purple"></div>
</div>
.container{
  outline: 5px solid black;
  display: inline-grid;
  width: 300px;
  height: 300px;
  gap: 10px;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr;
  grid-auto-rows: 1fr;
}
  • Our new implicit row forced our original first row to stop hogging all the space.
  • If you set grid-auto-rows to a fixed unit, like 50px each new row would adopt that value as it's row height.


True Column Flow

Question

Make items fill up entire columns first rather than rows first.

The DOM doesn’t work this way: it always places elements horizontally.

<div class="container">
  <div class="item numbered orange">1</div>
  <div class="item numbered blue">2</div>
  <div class="item numbered purple">3</div>
  <div class="item numbered red">4</div>
  <div class="item numbered green">5</div>
  <div class="item numbered grey">6</div>
</div>
.container{
  outline: 5px solid black;
  width: 300px;
  height: 300px;
}

.item{ 
  width: 50%;
  float: left;
  height: calc(300px / 3);
}

To make the items stack in columns would take some JS to do so:

1 4
2 5
3 6

With CSS Grid it’s easy using the grid-auto-flow property:

<div class="container">
  <div class="item numbered orange">1</div>
  <div class="item numbered blue">2</div>
  <div class="item numbered purple">3</div>
  <div class="item numbered red">4</div>
  <div class="item numbered green">5</div>
  <div class="item numbered grey">6</div>
</div>
.container{
  display: grid;
  grid-auto-flow: column;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr 1fr;
  outline: 5px solid black;
  width: 300px;
  height: 300px;
}
  • This makes the content fill up column first instead of row first.
  • The left column is filled first with items 1, 2 & 3
  • Then the right with items 4,5 & 6 than the row first
  • Any new items that are added will make the grid create new implicit columns instead of implicit rows.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment