- CSS Grid 101
- 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.
- 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
- The
frunit 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;
}gridWidth= 300pxtotalGaps=gridGap(10px) * 2 = 20px;column1Width[orange] = 50px;freeSpace=gridWidth-totalGaps-column1Width= 230pxnumFRUnits= 3 (the sum of all the fr units used in the grid columns)column2Width=freeSpace* ( 1(fr) /numFRUnits) —-> 230 * (1 / 3) = 76.66pxcolumn3Width=freeSpace* ( 2(fr) /numFRUnits) —-> 230 * (2 / 3) = 153.33px
frunits 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.
- The minmax value lets you set ranges of values for your Grid columns & rows.
- See grid is perfect for responsive layout for an example of minmax.
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 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-rowsandgrid-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-rowsto a fixed unit, like 50px each new row would adopt that value as it's row height.
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&6than the row first - Any new items that are added will make the grid create new implicit columns instead of implicit rows.