Dirk Harriman Banner Image

 

Notes CSS - Grid



CSS Grid


.container { display: grid | inline-grid; }


.container { grid-template-columns: ... ...; /* e.g. 1fr 1fr minmax(10px, 1fr) 3fr repeat(5, 1fr) 50px auto 100px 1fr */ grid-template-rows: ... ...; /* e.g. min-content 1fr min-content 100px 1fr max-content */ }

Grid lines are automatically assigned positive numbers from these assignments (-1 being an alternate for the very last row).

But you can choose to explicitly name the lines. Note the bracket syntax for the line names:

.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]; }

Note that a line can have more than one name. For example, here the second line will have two names: row1-end and row2-start:

.container { grid-template-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end]; }

If your definition contains repeating parts, you can use the repeat() notation to streamline things:

.container { grid-template-columns: repeat(3, 20px [col-start]); }

Which is equivalent to this:

.container { grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start]; }

If multiple lines share the same name, they can be referenced by their line name and count.

.item { grid-column-start: col-start 2; }

The fr unit allows you to set the size of a track as a fraction of the free space of the grid container.
For example, this will set each item to one third the width of the grid container:

.container { grid-template-columns: 1fr 1fr 1fr; }

The free space is calculated after any non-flexible items. In this example the total amount of free space available to the fr units doesn't include the 50px:

.container { grid-template-columns: 1fr 50px 1fr 1fr; }

grid-template-area

Defines a grid template by referencing the names of the grid areas which are specified with the grid-area property. Repeating the name of a grid area causes the content to span those cells. A period signifies an empty cell. The syntax itself provides a visualization of the structure of the grid.

Values:
.container { grid-template-areas: " | . | none | ..." "..."; }
Example:
.item-a {grid-area: header;background-color:orange;color:#000;padding:1rem;} .item-b {grid-area: main;background-color:blue;color:#fff;padding:1rem;} .item-c {grid-area: sidebar;background-color:red;color:#fff;padding:1rem;} .item-d {grid-area: footer;background-color:green;color:#fff;padding:1rem;} .example1 { display: grid; grid-template-columns: 100px 100px 100px 100px; grid-template-rows: auto; grid-template-areas: "header header header header" "main main . sidebar" "footer footer footer footer"; }
<div class="example1"> <div class="item-a">Header</div> <div class="item-b">Main</div> <div class="item-c">Side</div> <div class="item-d">Foot</div> </div>


Header
Main
Side
Foot

That'll create a grid that's four columns wide by three rows tall. The entire top row will be composed of the header area. The middle row will be composed of two main areas, one empty cell, and one sidebar area. The last row is all footer.

Each row in your declaration needs to have the same number of cells.

You can use any number of adjacent periods to declare a single empty cell. As long as the periods have no spaces between them they represent a single cell.

Notice that you're not naming lines with this syntax, just areas. When you use this syntax the lines on either end of the areas are actually getting named automatically. If the name of your grid area is foo, the name of the area's starting row line and starting column line will be foo-start, and the name of its last row line and last column line will be foo-end. This means that some lines might have multiple names, such as the far left line in the above example, which will have three names: header-start, main-start, and footer-start.


grid-template

A shorthand for setting grid-template-rows, grid-template-columns, and grid-template-areas in a single declaration.

Values:
.container { grid-template: none | <grid-template-rows> / <grid-template-columns>; }

It also accepts a more complex but quite handy syntax for specifying all three. Here's an example:

.container { grid-template: [row1-start] "header header header" 25px [row1-end] [row2-start] "footer footer footer" 25px [row2-end] / auto 50px auto; }

That's equivalent to this:

.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"; }

Since grid-template doesn't reset the implicit grid properties (

), which is probably what you want to do in most cases, it's recommended to use the grid property instead of grid-template.


column-gap
row-gap
grid-column-gap
grid-row-gap

Specifies the size of the grid lines. You can think of it like setting the width of the gutters between the columns/rows.

Values: <line-size> - a length value

.container { /* standard */ column-gap: <line-size>; row-gap: <line-size>; /* old */ grid-column-gap: <line-size>; grid-row-gap: <line-size>; }
Example:
.example2 { display: grid; grid-template-columns: 200px 100px 200px; grid-template-rows: 80px auto 80px; column-gap: 10px; row-gap: 15px; } .example2 div {border:1px solid #333;padding:0.25rem;}


Item
Item
Item
Item
Item
Item
Item
Item
Item

gap
grid-gap

A shorthand for row-gap and column-gap

Values: <grid-row-gap> <grid-column-gap> - length values

.container { /* standard */ gap: <grid-row-gap> <grid-column-gap>; /* old */ grid-gap: <grid-row-gap> <grid-column-gap>; }
Example:
.container { grid-template-columns: 100px 50px 100px; grid-template-rows: 80px auto 80px; gap: 15px 10px; }

If no row-gap is specified, it's set to the same value as column-gap

The grid-prefix is deprecated (but who knows, may never actually be removed from browsers). Essentially grid-gap renamed to gap. The unprefixed property is already supported in Chrome 68+, Safari 11.2 Release 50+, and Opera 54+


justify-items

Sometimes the total size of your grid might be less than the size of its grid container. This could happen if all of your grid items are sized with non-flexible units like px. In this case you can set the alignment of the grid within the grid container. This property aligns the grid along the inline (row) axis (as opposed to align-content which aligns the grid along the block (column) axis).

Values: start, end, center, stretch, space-around, space-between, space-evenly


.container { justify-items: start; }

.container { justify-items: end; }

.container { justify-items: center; }

.container { justify-items: stretch; }

align-items

Sometimes the total size of your grid might be less than the size of its grid container. This could happen if all of your grid items are sized with non-flexible units like px. In this case you can set the alignment of the grid within the grid container. This property aligns the grid along the block (column) axis (as opposed to justify-content which aligns the grid along the inline (row) axis).

Values: start, end, center, stretch, space-around, space-between, space-evenly


place-items

place-items sets both the align-items and justify-items properties in a single declaration.

Values: <align-items> / <justify-items> - The first value sets align-items, the second value justify-items. If the second value is omitted, the first value is assigned to both properties.

.center { display: grid; place-items: center; }

justify-content

Sometimes the total size of your grid might be less than the size of its grid container. This could happen if all of your grid items are sized with non-flexible units like px. In this case you can set the alignment of the grid within the grid container. This property aligns the grid along the inline (row) axis (as opposed to align-content which aligns the grid along the block (column) axis).

Values: start, end, center, stretch, space-around, space-between, space-evenly


align-content

Sometimes the total size of your grid might be less than the size of its grid container. This could happen if all of your grid items are sized with non-flexible units like px. In this case you can set the alignment of the grid within the grid container. This property aligns the grid along the block (column) axis (as opposed to justify-content which aligns the grid along the inline (row) axis).

Values: start, end, center, stretch, space-around, space-between, space-evenly


place-content

place-content sets both the align-content and justify-content properties in a single declaration.

Values: <align-content> / <justify-content>


grid-auto-columns
grid-auto-rows

Specifies the size of any auto-generated grid tracks (aka implicit grid tracks). Implicit tracks get created when there are more grid items than cells in the grid or when a grid item is placed outside of the explicit grid.

Values: <track-size> - can be a length, a percentage, or a fraction of the free space in the grid (using the fr unit)

.container { grid-auto-columns: <track-size> ...; grid-auto-rows: <track-size> ...; }

To illustrate how implicit grid tracks get created, think about this:

.container { grid-template-columns: 60px 60px; grid-template-rows: 90px 90px; }

This creates a 2 x 2 grid.

But now imagine you use grid-column and grid-row to position your grid items like this:

.item-a { grid-column: 1 / 2; grid-row: 2 / 3; } .item-b { grid-column: 5 / 6; grid-row: 2 / 3; }

grid-auto-flow

If you have grid items that you don't explicitly place on the grid, the auto-placement algorithm kicks in to automatically place the items. This property controls how the auto-placement algorithm works.

Values: row, column, dense

Examples:

Consider this HTML:

<section class="container"> <div class="item-a">item-a</div> <div class="item-b">item-b</div> <div class="item-c">item-c</div> <div class="item-d">item-d</div> <div class="item-e">item-e</div> </section>

You define a grid with five columns and two rows, and set grid-auto-flow to row (which is also the default):

.container { display: grid; grid-template-columns: 60px 60px 60px 60px 60px; grid-template-rows: 30px 30px; grid-auto-flow: row; }

When placing the items on the grid, you only specify spots for two of them:

.item-a { grid-column: 1; grid-row: 1 / 3; } .item-e { grid-column: 5; grid-row: 1 / 3; }

Because we set grid-auto-flow to row, our grid will look like this. Notice how the three items we didn't place (item-b, item-c and item-d) flow across the available rows:

If we instead set grid-auto-flow to column, item-b, item-c and item-d flow down the columns:

.container { display: grid; grid-template-columns: 60px 60px 60px 60px 60px; grid-template-rows: 30px 30px; grid-auto-flow: column; }

grid

A shorthand for setting all of the following properties in a single declaration: grid-template-rows, grid-template-columns, grid-template-areas, grid-auto-rows, grid-auto-columns, and grid-auto-flow (Note: You can only specify the explicit or the implicit grid properties in a single grid declaration).

Examples:

The following two code blocks are equivalent:

.container { grid: 100px 300px / 3fr 1fr; } .container { grid-template-rows: 100px 300px; grid-template-columns: 3fr 1fr; }

The following two code blocks are equivalent:

.container { grid: auto-flow / 200px 1fr; } .container { grid-auto-flow: row; grid-template-columns: 200px 1fr; }

The following two code blocks are equivalent:

.container { grid: auto-flow dense 100px / 1fr 2fr; } .container { grid-auto-flow: row dense; grid-auto-rows: 100px; grid-template-columns: 1fr 2fr; }

And the following two code blocks are equivalent:

.container { grid: 100px 300px / auto-flow 200px; } .container { grid-template-rows: 100px 300px; grid-auto-flow: column; grid-auto-columns: 200px; }

It also accepts a more complex but quite handy syntax for setting everything at once. You specify grid-template-areas, grid-template-rows and grid-template-columns, and all the other sub-properties are set to their initial values. What you're doing is specifying the line names and track sizes inline with their respective grid areas. This is easiest to describe with an example:

.container { grid: [row1-start] "header header header" 1fr [row1-end] [row2-start] "footer footer footer" 25px [row2-end] / auto 50px auto; }

That's equivalent to this:

.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; }

grid-column-start
grid-column-end
grid-row-start
grid-row-end

Determines a grid item's location within the grid by referring to specific grid lines. grid-column-start/grid-row-start is the line where the item begins, and grid-column-end/grid-row-end is the line where the item ends.

Values:
.item { grid-column-start: <number> | <name> | span <number> | span <name> | auto; grid-column-end: <number> | <name> | span <number> | span <name> | auto; grid-row-start: <number> | <name> | span <number> | span <name> | auto; grid-row-end: <number> | <name> | span <number> | span <name> | auto; }
Examples:
.item-a { grid-column-start: 2; grid-column-end: five; grid-row-start: row1-start; grid-row-end: 3; }
.item-b { grid-column-start: 1; grid-column-end: span col4-start; grid-row-start: 2; grid-row-end: span 2; }

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.

Values:

<start-line> / <end-line> - each one accepts all the same values as the longhand version, including span

.item { grid-column: <start-line> / <end-line> | <start-line> / span <value>; grid-row: <start-line> / <end-line> | <start-line> / span <value>; }
Example:
.item-c { grid-column: 3 / span 2; grid-row: third-line / 4; }

If no end line value is declared, the item will span 1 track by default.


grid-area

Gives an item a name so that it can be referenced by a template created with the grid-template-areas property. Alternatively, this property can be used as an even shorter shorthand for grid-row-start + grid-column-start + grid-row-end + grid-column-end.

Values:
.item { grid-area: <name> | <row-start> / <column-start> / <row-end> / <column-end>; }
Examples:

As a way to assign a name to the item:

.item-d { grid-area: header; }

As the short-shorthand for grid-row-start + grid-column-start + grid-row-end + grid-column-end:

.item-d { grid-area: 1 / col4-start / last-line / 6; }

justify-self

Aligns a grid item inside a cell along the inline (row) axis (as opposed to align-self which aligns along the block (column) axis). This value applies to a grid item inside a single cell.

Values: start, end, center, stretch

.item { justify-self: start | end | center | stretch; }
Examples:
.item-a { justify-self: start; }
.item-a { justify-self: end; }
.item-a { justify-self: center; }
.item-a { justify-self: stretch; }

To set alignment for all the items in a grid, this behavior can also be set on the grid container via the justify-items property.


align-self

Aligns a grid item inside a cell along the block (column) axis (as opposed to justify-self which aligns along the inline (row) axis). This value applies to the content inside a single grid item.

Values: start, end, center, stretch

.item { align-self: start | end | center | stretch; }
Examples:
.item-a { align-self: start; }
.item-a { align-self: end; }
.item-a { align-self: center; }
.item-a { align-self: stretch; }

To align all the items in a grid, this behavior can also be set on the grid container via the align-items property.


place-self

place-self sets both the align-self and justify-self properties in a single declaration.

Values: auto, <align-self> / <justify-self>

.item-a { place-self: center; }
.item-a { place-self: center stretch; }

All major browsers except Edge support the place-self shorthand property.


Special Units & Functions

fr units

You'll likely end up using a lot of fractional units in CSS Grid, like 1fr.
They essentially mean “portion of the remaining space”. So a declaration like:

grid-template-columns: 1fr 3fr;

Means, loosely, 25% 75%. Except that those percentage values are much more firm than fractional units are. For example, if you added padding to those percentage-based columns, now you've broken 100% width (assuming a content-box box model). Fractional units also much more friendly in combination with other units, as you can imagine:

grid-template-columns: 50px min-content 1fr;

Sizing Keywords

When sizing rows and columns, you can use all the lengths you are used to, like px, rem, %, etc, but you also have keywords:


Sizing Functions


The repeat() Function and Keywords

The repeat() function can save some typing:

grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr; /* easier: */ grid-template-columns: repeat(8, 1fr); /* especially when: */ grid-template-columns: repeat(8, minmax(10px, 1fr));

But repeat() can get extra fancy when combined with keywords:

This bears the most famous snippet in all of CSS Grid and one of the all-time great CSS tricks:

grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));

Masonry

An experimental feature of CSS grid is masonry layout. Note that there are lots of approaches to CSS masonry, but mostly of them are trickery and either have major downsides or aren't what you quite expect.

The spec has an official way now, and this is behind a flag in Firefox:

.container { display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: masonry; }

Subgrid

Subgrid is an extremely useful feature of grids that allows grid items to have a grid of their own that inherits grid lines from the parent grid.

.parent-grid { display: grid; grid-template-columns: repeat(9, 1fr); } .grid-item { grid-column: 2 / 7; display: grid; grid-template-columns: subgrid; } .child-of-grid-item { /* gets to participate on parent grid! */ grid-column: 3 / 6; }
This is only supported in Firefox right now, but it really needs to get everywhere. It's also useful to know about display: contents;. This is not the same as subgrid, but it can be a useful tool sometimes in a similar fashion.
<div class="grid-parent"> <div class="grid-item"></div> <div class="grid-item"></div> <ul style="display: contents;"> <!-- These grid-items get to participate on the same grid!--> <li class="grid-item"></li> <li class="grid-item"></li> </ul> </div>

Overlapping Images

<div class="image_stack"> <div class="image_stack_item image_stack_item_1"> <img src="images/ppt_10.jpg" /> </div> <div class="image_stack_item image_stack_item_2"> <img src="images/ppt_11.jpg" /> </div> </div>
.image_stack { display:grid; position:relative; grid-template-columns: repeat(12, 1fr); width:50%; } .image_stack_item_1 { grid-column: 1 / span 8; grid-row: 1; padding-top: 40%; z-index: 1; } .image_stack_item_2 { grid-column: 4 / -1; grid-row: 1; } .image_stack_item > img { width:100%; display:block; }