coryhouse / coryhouse/reactjsconsulting
CSS Grid
- Dominant language
- JavaScript
- Stars
- 374
- Forks
- 33
- PR merge metrics
- No merged PRs in 30d
Description
## [CSS Grid](https://css-tricks.com/snippets/css/complete-guide-grid/)
- 2 dimensional grid system (unlike Flexbox which is mostly 1 dimensional). Eliminates need for tables, floats, inline-block approaches. [Example of a complex 2 dimensional design that justifies grid](https://getflywheel.com/wp-content/uploads/2017/08/grid-sketch.jpg).
- To align elements in just one direction, prefer Flexbox.
- Works well w/ Flexbox
- [Browser support](https://caniuse.com/#search=css%20grid)
- [Firefox has excellent Grid and Flexbox tools](https://www.dropbox.com/s/k59kaewefvoczwx/Screenshot%202019-09-17%2020.56.45.png?dl=0) - shows track line labels
**Key terms**:
- Declare a `grid container`, with `grid items` (direct descendants) inside. If it's not a direct descendant, it's **not** a grid item.
- `grid line` - the dividing line that makes up the grid's structure. Can be vert (column grid lines) or horiz (row grid lines).
- `grid track` - The columns/rows of the grid. (Space between adjacent grid lines)
- `grid cell` - Like a cell in a table/spreadsheet. A single "unit" of the grid.
- `grid area` - Total space surrounded by four grid lines. Can be comprised of any number of grid cells.
**grid**
Declare a grid container:
```css
display: grid | inline-grid
```
`grid` - block-level grid
`inline-grid` - inline-level grid
**columns and rows**
Define columns and rows via space-separated track sizes
```css
.container {
grid-template-columns: 40px 50px auto 50px 40px;
grid-template-rows: 25% 100px auto;
}
```
Code above generates [this](https://css-tricks.com/wp-content/uploads/2018/11/template-columns-rows-01.svg). Note that line numbers are assigned automatically.
[Can use line numbers to change order](https://gridbyexample.com/examples/example2/), or preferably, [use shorthand syntax](https://gridbyexample.com/examples/example3/), or even shorter with [grid-area](https://gridbyexample.com/examples/example4/)
Can optionally name lines:
```css
.container {
grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end];
grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line];
}
```
Can even give a line multiple names:
```css
.container {
grid-template-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end];
}
```
Can repeat to save typing:
```css
.container {
grid-template-columns: repeat(3, 20px [col-start]);
}
```
Above is equivalent to:
```css
.container {
grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start];
}
```
If multiple lines have the same name, you can slap a count on the end. This references the 2nd `col-start` line
```css
.item {
grid-column-start: col-start 2;
}
```
Use `fr` to set size as a fraction of the grid container's free space:
```css
.container {
grid-template-columns: 1fr 1fr 1fr;
}
```
This is calculated **after** any non-flexible items. For example, the free space here is the total space minus 50px:
```css
.container {
grid-template-columns: 1fr 50px 1fr 1fr;
}
```
**grid-template-areas**
Defines a grid template. How? It references `grid-area`'s by name. 3 potential values:
1. `` - The targeted `grid-area`
2. A period - signifies an empty cell.
3. `none` - no grid areas defined.
Note `grid-template-areas` below: The syntax visualizes the grid's structure! 👍
```css
.item-a {
grid-area: header;
}
.item-b {
grid-area: main;
}
.item-c {
grid-area: sidebar;
}
.item-d {
grid-area: footer;
}
.container {
display: grid;
grid-template-columns: 50px 50px 50px 50px;
grid-template-rows: auto;
grid-template-areas:
"header header header header"
"main main . sidebar"
"footer footer footer footer";
}
```
Above produces [this](https://css-tricks.com/wp-content/uploads/2018/11/dddgrid-template-areas.svg).
Each row in the declaration needs to have the same number of cells. This syntax names **areas**. The associated lines are automatically named. So if your grid area is called `header`, the area's starting row line will be `header-start`, and the last row line will be called `header-end`. So some lines might have multiple names such as `main-start`, `header-start`, etc.
**grid-template**
Shorthand for `grid-template-rows`, `grid-template-columns`, and `grid-template-areas` in one declaration.
Values:
- none - sets all 3 to their initial values
- `` - sets `grid-template-columns` and `grid-template-rows` to the specified values, respectively. Sets `grid-template-areas` to none.
So this:
```css
.container {
grid-template:
[row1-start] "header header header" 25px [row1-end]
[row2-start] "footer footer footer" 25px [row2-end]
/ auto 50px auto;
}
```
is equivalent to:
```css
.container {
grid-template-rows: [row1-start] 25px [row1-end row2-start] 25px [row2-end];
grid-template-columns: auto 50px auto;
grid-template-areas:
"header header header"
"footer footer footer";
}
```
**Note**: You typically want to use `grid` instead. Why? Because `grid-template` doesn't reset the implicit grid properties (`grid-auto-columns, `grid-auto-rows`, and `grid-auto-flow`), which you probably want to do.
**grid-column-gap**
**grid-row-gap**
Set gap between cells (okay, technically sets the grid line size).
```css
.container {
grid-template-columns: 100px 50px 100px;
grid-template-rows: 80px auto 80px;
grid-column-gap: 10px;
grid-row-gap: 15px;
}
```
[Result](https://css-tricks.com/wp-content/uploads/2018/11/dddgrid-gap.svg)
Note: Gutters aren't added on the outer edges. Only between columns/rows. Also, the grid- prefix will be removed and `grid-column-gap` and `grid-row-gap` renamed to `column-gap` and `row-gap`. The unprefixed properties are already supported in Chrome 68+, Safari 11.2 Release 50+ and Opera 54+.
**grid-gap**
Shorthand for `grid-row-gap` and `grid-column-gap`
```css
.container {
grid-template-columns: 100px 50px 100px;
grid-template-rows: 80px auto 80px;
grid-gap: 15px 10px;
}
```
If no grid-row-gap is specified, it's set to the same value as grid-column-gap
Note: The grid- prefix will be removed and `grid-gap` renamed to `gap`. The unprefixed property is already supported in Chrome 68+, Safari 11.2 Release 50+ and Opera 54+.
**justify-items**
Aligns grid items horizontally. (`align-items` does the opposite, it aligns vertically)
Values:
- start
- end
- center
- stretch
Can be set on individual grid items via `justify-self`.
**align-items**
Aligns grid items vertically. See `justify-items` above for horiz. Same values as `justify-items`.
Can be set on individual items via `align-self`.
**place items**
Shorthand. Sets `align-items` and `justify-items`. First val is align, second is justify. Not supported in Edge yet.
**justify-content**
Aligns entire grid horizontally inside container. So, only applicable when grid doesn't fill entire container).
Values:
- start
- end
- center
- stretch
- space-around
- space-between
- space-evenly
**align-content**
Same as `justify-content` above, but vertically aligns.
**place-content**
Sets both `align-content` and `justify-content`, align listed first, justify 2nd. Not in Edge yet.
**grid-auto-rows**
**grid-auto-columns**
Sets the size of any auto-generated grid tracks (aka implicit grid tracks). These are created when there are more grid items than cells in the grid.
Example:
You create a container with a 2x2 grid:
```css
.container {
grid-template-columns: 60px 60px;
grid-template-rows: 90px 90px;
}
```
But then you position items like this:
```css
.item-a {
grid-column: 1 / 2;
grid-row: 2 / 3;
}
.item-b {
grid-column: 5 / 6;
grid-row: 2 / 3;
}
```
This tells item-b to start on column line 5 and end on 6. But we never defined that column, so it results in [this](https://css-tricks.com/wp-content/uploads/2018/11/grid-auto-columns-rows-02.svg)! So implicit tracks are created. This setting specifies the width of those auto-generated columns:
```css
.container {
grid-auto-columns: 60px;
}
```
New [result](https://css-tricks.com/wp-content/uploads/2018/11/grid-auto-columns-rows-03.svg)
**grid-auto-flow**
If you have grid items that you don't explicitly place on the grid, this controls how they're automatically placed.
Values:
row - fill each row in turn, add new rows as needed
column - fill each column in turn, add new columns as needed
dense - fill in holes earlier in the grid if smaller items come up later
```css
.container {
grid-auto-flow: row | column | row dense | column dense;
}
```
Note: Dense changes the visual order, which might cause them to display out of order. Consider the a11y risks of this.
Example:
Step 1: Declare some html for 5 columns
```html
```
Then, declare a grid with 5 columns, 2 rows:
```css
.container {
display: grid;
grid-template-columns: 60px 60px 60px 60px 60px;
grid-template-rows: 30px 30px;
grid-auto-flow: row;
}
```
Then, when placing them on the grid, only specify spots for 2:
```css
.item-a {
grid-column: 1;
grid-row: 1 / 3;
}
.item-e {
grid-column: 5;
grid-row: 1 / 3;
}
```
Because `grid-auto-flow` is set to row above, the grid looks like [this](https://css-tricks.com/wp-content/uploads/2018/11/grid-auto-flow-01.svg).
If we switch `grid-auto-flow` to column, then item-b, c, and d will [flow down columns](https://css-tricks.com/wp-content/uploads/2018/11/grid-auto-flow-02.svg) instead.
**grid**
Shorthand for `grid-template-rows`, `grid-template-columns`, `grid-template-areas`, `grid-auto-rows`, `grid-auto-columns`, `grid-auto-flow`.
These 2 are equivalent:
```css
.container {
grid-template-rows: 100px 300px;
grid-template-columns: 3fr 1fr;
}
```
```css
.container {
grid: 100px 300px / 3fr 1fr;
}
```
These 2 are equivalent:
```css
.container {
grid-auto-flow: row;
grid-template-columns: 200px 1fr;
}
```
```css
.container {
grid: auto-flow / 200px 1fr;
}
```
These 2 are equivalent:
```css
.container {
grid-template-rows: 100px 300px;
grid-auto-flow: column;
grid-auto-columns: 200px;
}
```
```css
.container {
grid: 100px 300px / auto-flow 200px;
}
```
Finally, a more complex example that sets `grid-template-areas`, `grid-template-rows`, and `grid-template columns` - all other properties are set to their initial values. So this specifies line names and track sizes inline with their grid areas.
These are equivalent:
```css
.container {
grid-template-areas:
"header header header"
"footer footer footer";
grid-template-rows: [row1-start] 1fr [row1-end row2-start] 25px [row2-end];
grid-template-columns: auto 50px auto;
}
```
```css
.container {
grid: [row1-start] "header header header" 1fr [row1-end]
[row2-start] "footer footer footer" 25px [row2-end]
/ auto 50px auto;
}
```
### Grid Item properties (the children)
**Note**: float, display: inline-block, display: table-cell, vertical-align and column-* properties have no effect on a grid item.
**grid-column-start**
**grid-column-end**
**grid-row-start**
**grid-row-end**
Determines the grid item's location in the grid. Refers to specific grid lines. *-start is where it begins. *-end is where the item ends.
Values:
- `` - Can be a number (to refer to a numbered grid line) or name (to refer to a named grid line)
- span - number of grid tracks to span across, or name of line where it should stop
- auto - auto-placement. Default span of one.
```css
.item {
grid-column-start: | | span | span | auto;
grid-column-end: | | span | span | auto;
grid-row-start: | | span | span | auto;
grid-row-end: | | span | span | auto;
}
```
```css
.item-a {
grid-column-start: 2;
grid-column-end: five;
grid-row-start: row1-start;
grid-row-end: 3;
}
```
[Result](https://css-tricks.com/wp-content/uploads/2018/11/grid-column-row-start-end-01.svg)
If no grid-column-end/grid-row-end is declared, the item will span 1 track by default.
Items can overlap each other. You can use z-index to control their stacking order.
**grid-column**
**grid-row**
Shorthand for `grid-column-start` + `grid-column-end` and `grid-row-start` + `grid-row-end` respectively.
This sets row to start at line 3, and ends at line 4. And sets the column to start at line 3 and end 2 lines later (line 5). [Result](https://css-tricks.com/wp-content/uploads/2018/11/grid-column-row.svg).
```css
.item-c {
grid-column: 3 / span 2;
grid-row: third-line / 4;
}
```
Note: If no end value is declared, the item will span one item by default.
**grid-area**
Gives item a name so it can be referenced by `grid-template-areas`.
This assigns the name:
```css
.item-d {
grid-area: header;
}
```
Can also be used as shorthand for `grid-row-start` + `grid-column-start` + `grid-row-end` + `grid-column-end`:
```css
.item-d {
grid-area: 1 / col4-start / last-line / 6;
}
```
[Result](https://css-tricks.com/wp-content/uploads/2018/11/grid-area.svg)
**justify-self**
Horiz align (along row) a single item inside a cell
Values:
start
end
center
stretch
**align-self**
Like justify-self, but for vert align (column).
**place-self**
Shorthand for setting both `align-self` and `justify-self`, in that order. So vert, then horiz.
```css
.item-a {
place-self: center stretch;
}
```
### Special funcs and keywords
When sizing rows/columns, you can use all the usual lengths like px, %. But also have keywords like `min-content`, `max-content` and fractional units.
- `minmax` can set boundaries for otherwise flexible units. For example to set a column to be 1fr, but shrink no further than 200px: grid-template-columns: 1fr minmax(200px, 1fr);
- `repeat()` - saves typing. Example: Make 10 columns: grid-template-columns: repeat(10, 1fr);
Combining all of these things can be extremely powerful, like grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
[Codepen of above](https://codepen.io/chriscoyier/pen/ecff0af160b3fd32cf67841b1eb6cfc3)
## Examples
[Simple example](https://codepen.io/rachelandrew/pen/BNXyQa)
[Named grid areas](https://codepen.io/rachelandrew/pen/oXKgoQ?editors=1100#0)
[Excellent simple responsive grid with media query example]
(https://gridbyexample.com/examples/example13/)
[Source order doesn't effect grid](https://gridbyexample.com/examples/example14/) - can weave ads from bottom into content
[Repeat example](https://codepen.io/chriscoyier/pen/ecff0af160b3fd32cf67841b1eb6cfc3)
[Layering](https://gridbyexample.com/examples/example15/)
[Auto placement](https://gridbyexample.com/examples/example17/)
[Auto flow columns instead of rows](https://gridbyexample.com/examples/example18/)
[Mix auto placement with placed item](https://gridbyexample.com/examples/example19/)
[Full site example](https://codepen.io/coryhouse/pen/zYOLjLM?editors=1100#0) - Compare to [Flexbox version](https://codepen.io/coryhouse/pen/wvwxjxJ).
[Complex grid layout example](https://codepen.io/abbeyjfitzgerald/pen/zzqqYo)
## Grid resources
[Josh Comeau's interactive guide](https://www.joshwcomeau.com/css/interactive-guide-to-grid/)
[CSS Grid Generator](https://cssgrid-generator.netlify.com/)
[Box alignment cheatsheet](https://rachelandrew.co.uk/css/cheatsheets/box-alignment) - Compares Flexbox and Grid alignment
[Grid by example](https://gridbyexample.com/examples)
[Grid Critters learning game](https://gridcritters.com)
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.