CSS Grid Collate 290622

Download as pdf or txt
Download as pdf or txt
You are on page 1of 233

MDN Plus now available in your country! Support MDN and make it your own.

Learn more ✨

CSS Multi-column Layout


CSS Multi-column Layout is a module of CSS that adds support for multi-column layouts. Support is included for establishing
the number of columns in a layout, as well as how content should flow from column to column, gap sizes between columns, and
column dividing lines (known as column rules) along with their appearance.

Basic example
In the following example the column-count property has been applied to the element with a class of container. As the value of
column-count is 3 , the content is arranged into 3 columns of equal size.
p
proinde vos postulo greens dandelion okra spinach avocado daikon
essum magis kohlrabi wakame tomato. napa cabbage asparagus
welsh onion daikon Dandelion cucumber winter purslane kale.
amaranth tatsoi tomatillo earthnut pea peanut soko Celery potato scallion
melon azuki bean garlic. zucchini. desert raisin horseradish
spinach carrot soko.
Gumbo beet greens corn Turnip greens yarrow
soko endive gumbo ricebean rutabaga endive
gourd. Parsley shallot

.container {

column-count: 3;

<p>Gumbo beet greens corn soko endive gumbo gourd. Parsley shallot courgette tatsoi
pea sprouts fava bean collard greens dandelion okra wakame tomato. Dandelion cucumber
earthnut pea peanut soko zucchini.</p>

<p>Turnip greens yarrow ricebean rutabaga endive cauliflower sea lettuce kohlrabi
amaranth water spinach avocado daikon napa cabbage asparagus winter purslane kale.
Celery potato scallion desert raisin horseradish spinach carrot soko.</p>

</div>

Reset

Relationship to Fragmentation
Multiple-column Layout is closely related to Paged Media, in that each column box becomes a fragment, much like a printed
page becomes a fragment of an overall document. Therefore the properties now defined in the CSS Fragmentation specification
are required in order to control how content breaks between columns.
Reference
Multiple-column Layout Properties
column-count

column-fill

column-gap

column-rule

column-rule-color

column-rule-style

column-rule-width

column-span

column-width

columns

Related CSS Fragmentation Properties


break-after

break-before

break-inside

orphans

widows
Guides
Basic Concepts of Multicol
An overview of the Multiple-column Layout specification
Styling Columns
How to use column rules and manage the spacing between columns.
Spanning and Balancing
How to make elements span across all columns and controlling the way columns are fil ed.
Handling Overflow in Multicol
What happens when an item overflows the column it is in and what happens when there is too much columned content to fit
a container.
Content Breaks in Multicol
Introduction to the Fragmentation specification and how to control where column content breaks.

Specifications
Specification
CSS Multi-column Layout Module Level 2
See also
Other CSS layout technologies include:
CSS Flexible Box Layout (CSS flexbox)
CSS Grid Layout

Last modified: Feb 22, 2022, by MDN contributors


MDN Plus now available in your country! Support MDN and make it your own. Learn more ✨

Flexbox
Flexbox is a one-dimensional layout method for arranging items in rows or columns. Items flex (expand) to fil additional space
or shrink to fit into smaller spaces. This article explains all the fundamentals.

Prerequisites: HTML basics (study


Introduction to HTML), and an idea of how CSS works (study
Introduction to CSS.)
Objective: To learn how to use the Flexbox layout system to create web layouts.

Why Flexbox?
For a long time, the only reliable cross-browser compatible tools available for creating CSS layouts were features like floats and
positioning. These work, but in some ways they're also limiting and frustrating.
The following simple layout designs are either difficult or impossible to achieve with such tools in any kind of convenient, flexible
way:
Vertically centering a block of content inside its parent.
Making all the children of a container take up an equal amount of the available width/height, regardless of how much
width/height is available.
Making all columns in a multiple-column layout adopt the same height even if they contain a different amount of content.
As you'l see in subsequent sections, flexbox makes a lot of layout tasks much easier. Let's dig in!

Introducing a simple example


In this article, you'l work through a series of exercises to help you understand how flexbox works. To get started, you should
make a local copy of the first starter file — flexbox0.html from our GitHub repo. Load it in a modern browser (like Firefox or
Chrome) and have a look at the code in your code editor. You can also see it live here .
You'l see that we have a <header> element with a top level heading inside it and a <section> element containing three
<article> s. We're going to use these to create a fairly standard three column layout.

Specifying what elements to lay out as flexible boxes


To start with, we need to select which elements are to be laid out as flexible boxes. To do this, we set a special value of
display on the parent element of the elements you want to affect. In this case we want to lay out the <article> elements,
so we set this on the <section> :
section {

display: flex;

This causes the <section> element to become a flex container and its children to become flex items. The result of this
should be something like so:

So, this single declaration gives us everything we need. Incredible, right? We have our multiple column layout with equal-sized
columns, and the columns are all the same height. This is because the default values given to flex items (the children of the flex
container) are set up to solve common problems such as this.
To be clear, let's reiterate what is happening here. The element we've given a display value of flex to is acting like a block-
level element in terms of how it interacts with the rest of the page, but its children are laid out as flex items. The next section
wil explain in more detail what this means. Note also that you can use a display value of inline-flex if you wish to lay out
an element's children as flex items, but have that element behave like an inline element.

The flex model


When elements are laid out as flex items, they are laid out along two axes:

The main axis is the axis running in the direction the flex items are laid out in (for example, as rows across the page, or
columns down the page.) The start and end of this axis are called the main start and main end.
The cross axis is the axis running perpendicular to the direction the flex items are laid out in. The start and end of this axis
are called the cross start and cross end.
The parent element that has display: flex set on it (the <section> in our example) is called the flex container.
The items laid out as flexible boxes inside the flex container are called flex items (the <article> elements in our
example).
Bear this terminology in mind as you go through subsequent sections. You can always refer back to it if you get confused about
any of the terms being used.

Columns or rows?
Flexbox provides a property called flex-direction that specifies which direction the main axis runs (which direction the
flexbox children are laid out in). By default this is set to row , which causes them to be laid out in a row in the direction your
browser's default language works in (left to right, in the case of an English browser).
Try adding the following declaration to your <section> rule:
flex-direction: column;

You'l see that this puts the items back in a column layout, much like they were before we added any CSS. Before you move on,
delete this declaration from your example.

Note: You can also lay out flex items in a reverse direction using the row-reverse and column-reverse values.
Experiment with these values too!
Wrapping
One issue that arises when you have a fixed width or height in your layout is that eventually your flexbox children wil overflow
their container, breaking the layout. Have a look at our flexbox-wrap0.html example and try viewing it live (take a local copy
of this file now if you want to follow along with this example):
Here we see that the children are indeed breaking out of their container. One way in which you can fix this is to add the
following declaration to your <section> rule:
flex-wrap: wrap;

Also, add the following declaration to your <article> rule:


flex: 200px;

Try this now. You'l see that the layout looks much better with this included:
We now have multiple rows. Each row has as many flexbox children fitted into it as is sensible. Any overflow is moved down to
the next line. The flex: 200px declaration set on the articles means that each wil be at least 200px wide. We'l discuss this
property in more detail later on. You might also notice that the last few children on the last row are each made wider so that
the entire row is stil fil ed.
But there's more we can do here. First of all, try changing your flex-direction property value to row-reverse . Now you'l
see that you stil have your multiple row layout, but it starts from the opposite corner of the browser window and flows in
reverse.

flex-flow shorthand
At this point it's worth noting that a shorthand exists for flex-direction and flex-wrap : flex-flow . So, for example, you
can replace
flex-direction: row;

flex-wrap: wrap;

with
flex-flow: row wrap;

Flexible sizing of flex items


Let's now return to our first example and look at how we can control what proportion of space flex items take up compared to
the other flex items. Fire up your local copy of flexbox0.html , or take a copy of flexbox1.html as a new starting point (see it
live ).
First, add the following rule to the bottom of your CSS:
article {

flex: 1;

This is a unitless proportion value that dictates how much available space along the main axis each flex item wil take up
compared to other flex items. In this case, we're giving each <article> element the same value (a value of 1), which means
they'l all take up an equal amount of the spare space left after properties like padding and margin have been set. This value is
proportionally shared among the flex items: giving each flex item a value of 400000 would have exactly the same effect.
Now add the following rule below the previous one:
article:nth-of-type(3) {

flex: 2;

Now when you refresh, you'l see that the third <article> takes up twice as much of the available width as the other two.
There are now four proportion units available in total (since 1 + 1 + 2 = 4). The first two flex items have one unit each, so they
each take 1/4 of the available space. The third one has two units, so it takes up 2/4 of the available space (or one-half).
You can also specify a minimum size value within the flex value. Try updating your existing article rules like so:
article {

flex: 1 200px;

article:nth-of-type(3) {

flex: 2 200px;

This basically states, "Each flex item wil first be given 200px of the available space. After that, the rest of the available space
wil be shared according to the proportion units." Try refreshing and you'l see a difference in how the space is shared.
The real value of flexbox can be seen in its flexibility/responsiveness. If you resize the browser window or add another
<article> element, the layout continues to work just fine.

flex: shorthand versus longhand


flex is a shorthand property that can specify up to three different values:
The unitless proportion value we discussed above. This can be specified separately using the flex-grow longhand
property.
A second unitless proportion value, flex-shrink , which comes into play when the flex items are overflowing their
container. This value specifies how much an item wil shrink in order to prevent overflow. This is quite an advanced flexbox
feature and we won't be covering it any further in this article.
The minimum size value we discussed above. This can be specified separately using the flex-basis longhand value.
We'd advise against using the longhand flex properties unless you really have to (for example, to override something previously
set). They lead to a lot of extra code being written, and they can be somewhat confusing.

Horizontal and vertical alignment


You can also use flexbox features to align flex items along the main or cross axis. Let's explore this by looking at a new
example: flex-align0.html (see it live also ). We're going to turn this into a neat, flexible button/toolbar. At the moment you'l
see a horizontal menu bar with some buttons jammed into the top left-hand corner.
First, take a local copy of this example.
Now, add the following to the bottom of the example's CSS:
div {

display: flex;

align-items: center;

justify-content: space-around;

Refresh the page and you'l see that the buttons are now nicely centered horizontally and vertically. We've done this via two
new properties.
align-items controls where the flex items sit on the cross axis.
By default, the value is stretch , which stretches all flex items to fil the parent in the direction of the cross axis. If the
parent doesn't have a fixed height in the cross axis direction, then all flex items wil become as tall as the tallest flex item.
This is how our first example had columns of equal height by default.
The center value that we used in our above code causes the items to maintain their intrinsic dimensions, but be centered
along the cross axis. This is why our current example's buttons are centered vertically.
You can also have values like flex-start and flex-end , which wil align all items at the start and end of the cross axis
respectively. See align-items for the full details.
You can override the align-items behavior for individual flex items by applying the align-self property to them. For
example, try adding the following to your CSS:
button:first-child {

align-self: flex-end;

Have a look at what effect this has and remove it again when you've finished.
justify-content controls where the flex items sit on the main axis.
The default value is flex-start , which makes all the items sit at the start of the main axis.
You can use flex-end to make them sit at the end.
center is also a value for justify-content . It'l make the flex items sit in the center of the main axis.

The value we've used above, space-around , is useful — it distributes all the items evenly along the main axis with a bit of
space left at either end.
There is another value, space-between , which is very similar to space-around except that it doesn't leave any space at
either end.
We'd like to encourage you to play with these values to see how they work before you continue.

Ordering flex items


Flexbox also has a feature for changing the layout order of flex items without affecting the source order. This is another thing
that is impossible to do with traditional layout methods.
The code for this is simple. Try adding the following CSS to your button bar example code:
button:first-child {

order: 1;

Refresh and you'l see that the "Smile" button has moved to the end of the main axis. Let's talk about how this works in a bit
more detail:
By default, all flex items have an order value of 0.
Flex items with higher specified order values wil appear later in the display order than items with lower order values.
Flex items with the same order value wil appear in their source order. So if you have four items whose order values have
been set as 2, 1, 1, and 0 respectively, their display order would be 4th, 2nd, 3rd, then 1st.
The 3rd item appears after the 2nd because it has the same order value and is after it in the source order.
You can set negative order values to make items appear earlier than items whose value is 0. For example, you could make the
"Blush" button appear at the start of the main axis using the following rule:
button:last-child {

order: -1;

Nested flex boxes


It's possible to create some pretty complex layouts with flexbox. It's perfectly OK to set a flex item to also be a flex container,
so that its children are also laid out like flexible boxes. Have a look at complex-flexbox.html (see it live also ).
The HTML for this is fairly simple. We've got a <section> element containing three <article> s. The third <article>
contains three <div> s, and the first <div> contains five <button> s :
section - article

article

article - div - button

div button

div button

button

button

Let's look at the code we've used for the layout.


First of all, we set the children of the <section> to be laid out as flexible boxes.
section {

display: flex;

Next, we set some flex values on the <article> s themselves. Take special note of the second rule here: we're setting the
third <article> to have its children laid out like flex items too, but this time we're laying them out like a column.
article {

flex: 1 200px;

article:nth-of-type(3) {

flex: 3 200px;

display: flex;

flex-flow: column;

Next, we select the first <div> . We first use flex: 1 100px; to effectively give it a minimum height of 100px, then we set its
children (the <button> elements) to also be laid out like flex items. Here we lay them out in a wrapping row and align them in
the center of the available space as we did with the individual button example we saw earlier.
article:nth-of-type(3) div:first-child {

flex: 1 100px;

display: flex;

flex-flow: row wrap;

align-items: center;

justify-content: space-around;

Finally, we set some sizing on the button. This time by giving it a flex value of 1 auto. This has a very interesting effect, which
you'l see if you try resizing your browser window width. The buttons wil take up as much space as they can. As many wil fit on
a line as is comfortable; beyond that, they'l drop to a new line.
button {

flex: 1 auto;

margin: 5px;

font-size: 18px;

line-height: 1.5;

Cross-browser compatibility
Flexbox support is available in most new browsers: Firefox, Chrome, Opera, Microsoft Edge, and IE 11, newer versions of
Android/iOS, etc. However, you should be aware that there are stil older browsers in use that don't support Flexbox (or do, but
support a really old, out-of-date version of it.)
While you're just learning and experimenting, this doesn't matter too much; however, if you're considering using flexbox in a real
website, you need to do testing and make sure that your user experience is stil acceptable in as many browsers as possible.
Flexbox is a bit trickier than some CSS features. For example, if a browser is missing a CSS drop shadow, then the site wil likely
stil be usable. Not supporting flexbox features, however, wil probably break a layout completely, making it unusable.
We discuss strategies for overcoming cross-browser support issues in our Cross browser testing module.

Test your skills!


You've reached the end of this article, but can you remember the most important information? You can find some further tests
to verify that you've retained this information before you move on — see Test your skil s: Flexbox.

Summary
That concludes our tour of the basics of Flexbox. We hope you had fun and wil have a good play around with it as you
proceed further with your learning. Next, we'l have a look at another important aspect of CSS layouts: CSS Grids.

See also
CSS-Tricks Guide to Flexbox — an article explaining everything about Flexbox in a visually appealing way
Flexbox Froggy — an educational game to learn and better understand the basics of Flexbox

In this module
Introduction to CSS layout
Normal flow
Flexbox
Grid
Floats
Positioning
Multiple-column layout
Responsive design
Beginner's guide to media queries
Legacy layout methods
Supporting older browsers
Fundamental layout comprehension

Last modified: May 6, 2022, by MDN contributors


MDN Plus now available in your country! Support MDN and make it your own. Learn more ✨

Relationship of grid layout to other layout methods


CSS Grid Layout has been designed to work alongside other parts of CSS, as part of a complete system for doing the layout. In
this guide, I wil explain how a grid fits together with other techniques you may already be using.

Grid and flexbox


The basic difference between CSS Grid Layout and CSS Flexbox Layout is that flexbox was designed for layout in one
dimension - either a row or a column. Grid was designed for two-dimensional layout - rows, and columns at the same time. The
two specifications share some common features, however, and if you have already learned how to use flexbox, the similarities
should help you get to grips with Grid.
One-dimensional versus two-dimensional layout
A simple example can demonstrate the difference between one- and two-dimensional layouts.
In this first example, I am using flexbox to lay out a set of boxes. I have five child items in my container, and I have given the
flex properties values so that they can grow and shrink from a flex-basis of 150 pixels.
I have also set the flex-wrap property to wrap , so that if the space in the container becomes too narrow to maintain the flex
basis, items wil wrap onto a new row.
<div class="wrapper">

<div>One</div>

<div>Two</div>

<div>Three</div>

<div>Four</div>

<div>Five</div>

</div>

.wrapper {

width: 500px;

display: flex;

flex-wrap: wrap;

.wrapper > div {

flex: 1 1 150px;

One Two Three

Four Five

In the image, you can see that two items have wrapped onto a new line. These items are sharing the available space and not
lining up underneath the items above. This is because when you wrap flex items, each new row (or column when working by
column) is an independent flex line in the flex container. Space distribution happens across the flex line.
A common question then is how to make those items line up. This is where you want a two-dimensional layout method: You
want to control the alignment by row and column, and this is where grid comes in.
The same layout with CSS grids
In this next example, I create the same layout using Grid. This time we have three 1fr column tracks. We do not need to set
anything on the items themselves; they wil lay themselves out one into each cell of the created grid. As you can see they stay
in a strict grid, lining up in rows and columns. With five items, we get a gap on the end of row two.
<div class="wrapper">

<div>One</div>

<div>Two</div>

<div>Three</div>

<div>Four</div>

<div>Five</div>

</div>

.wrapper {

display: grid;

grid-template-columns: repeat(3, 1fr);

One Two Three

Four Five

A simple question to ask yourself when deciding between grid or flexbox is:
do I only need to control the layout by row or column – use a flexbox
do I need to control the layout by row and column – use a grid
Content out or layout in?
In addition to the one-dimensional versus two-dimensional distinction, there is another way to decide if you should use flexbox
or grid for a layout. Flexbox works from the content out. An ideal use case for flexbox is when you have a set of items and
want to space them out evenly in a container. You let the size of the content decide how much individual space each item
takes up. If the items wrap onto a new line, they wil work out their spacing based on their size and the available space on that
line.
Grid works from the layout in. When you use CSS Grid Layout you create a layout and then you place items into it, or you allow
the auto-placement rules to place the items into the grid cells according to that strict grid. It is possible to create tracks that
respond to the size of the content, however, they wil also change the entire track.
If you are using flexbox and find yourself disabling some of the flexibility, you probably need to use CSS Grid Layout. An
example would be if you are setting a percentage width on a flex item to make it line up with other items in a row above. In that
case, a grid is likely to be a better choice.
Box alignment
The feature of flexbox that was most exciting to many of us was that it gave us proper alignment control for the first time. It
made it easy to center a box on the page. Flex items can stretch to the height of the flex container, meaning that equal height
columns were possible. These were things we have wanted to do for a very long time, and have come up with all kinds of
hacks to accomplish, at least visually.
The alignment properties from the flexbox specification have been added to a new specification called Box Alignment Level 3 .
This means that they can be used in other specifications, including Grid Layout. In the future, they may well apply to other
layout methods as well.
In a later guide in this series, I'l be taking a proper look at Box Alignment and how it works in Grid Layout. For now, here is a
comparison between simple examples of flexbox and grid.
In the first example, which uses flexbox, I have a container with three items inside. The wrapper min-height is set, so it
defines the height of the flex container. I have set align-items on the flex container to flex-end so the items wil line up at
the end of the flex container. I have also set the align-self property on box1 so it wil override the default and stretch to
the height of the container and on box2 so it aligns to the start of the flex container.
<div class="wrapper">

<div class="box1">One</div>

<div class="box2">Two</div>

<div class="box3">Three</div>

</div>

.wrapper {

display: flex;

align-items: flex-end;

min-height: 200px;

.box1 {

align-self: stretch;

.box2 {

align-self: flex-start;

One Two

Three

Alignment in CSS Grids


This second example uses a grid to create the same layout. This time we are using the box alignment properties as they apply
to a grid layout. So we align to start and end rather than flex-start and flex-end . In the case of a grid layout, we are
aligning the items inside their grid area. In this case that is a single grid cell, but it could be an area made up of several grid cells.
<div class="wrapper">

<div class="box1">One</div>

<div class="box2">Two</div>

<div class="box3">Three</div>

</div>

.wrapper {

display: grid;

grid-template-columns: repeat(3,1fr);

align-items: end;

grid-auto-rows: 200px;

.box1 {

align-self: stretch;

.box2 {

align-self: start;

One Two

Three

The fr unit and flex-basis


We have already seen how the fr unit works to assign a proportion of available space in the grid container to our grid tracks.
The fr unit, when combined with the minmax() function can give us very similar behavior to the flex properties in flexbox
while stil enabling the creation of a layout in two dimensions.
If we look back at the example where I demonstrated the difference between one and two-dimensional layouts, you can see
there is a difference between the way that the two layouts work responsively. With the flex layout, if we drag our window wider
and smaller, the flexbox does a nice job of adjusting the number of items in each row according to the available space. If we
have a lot of space all five items can fit on one row. If we have a very narrow container we may only have space for one.
In comparison, the grid version always has three column tracks. The tracks themselves wil grow and shrink, but there are
always three since we asked for three when defining our grid.
Auto-filling grid tracks
We can use grid to create a similar effect to flexbox, while stil keeping the content arranged in strict rows and columns, by
creating our track listing using repeat notation and the auto-fill and auto-fit properties.
In this next example, I have used the auto-fill keyword in place of an integer in the repeat notation and set the track listing
to 200 pixels. This means that grid wil create as many 200 pixels column tracks as wil fit in the container.
<div class="wrapper">

<div>One</div>

<div>Two</div>

<div>Three</div>

</div>

.wrapper {

display: grid;

grid-template-columns: repeat(auto-fill, 200px);

One Two Three

A flexible number of tracks


This isn't quite the same as flexbox. In the flexbox example, the items are larger than the 200 pixel basis before wrapping. We
can achieve the same in grid by combining auto-fit and the minmax() function. In this next example, I create auto fil ed
tracks with minmax . I want my tracks to be a minimum of 200 pixels, so I set the maximum to be 1fr . Once the browser has
worked out how many times 200 pixels wil fit into the container–also taking account of grid gaps–it wil treat the 1fr maximum
as an instruction to share out the remaining space between the items.
<div class="wrapper">

<div>One</div>

<div>Two</div>

<div>Three</div>

</div>

.wrapper {

display: grid;

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

One Two Three

We now have the ability to create a grid with a flexible number of flexible tracks, but see items laid out on the grid aligned by
rows and columns at the same time.

Grid and absolutely positioned elements


Grid interacts with absolutely positioned elements, which can be useful if you want to position an item inside a grid or grid area.
The specification defines the behavior when a grid container is a containing block and a parent of the absolutely positioned
item.
A grid container as containing block
To make the grid container a containing block you need to add the position property to the container with a value of relative,
just as you would make a containing block for any other absolutely positioned items. Once you have done this, if you give a grid
item position: absolute it wil take as its containing block the grid container or, if the item also has a grid position, the area
of the grid it is placed into.
In the below example I have a wrapper containing four child items. Item three is absolutely positioned and also placed on the
grid using line-based placement. The grid container has position: relative and so becomes the positioning context of this
item.
<div class="wrapper">

<div class="box1">One</div>

<div class="box2">Two</div>

<div class="box3">

This block is absolutely positioned. In this example the grid container is the containing block and so
the absolute positioning offset values are calculated in from the outer edges of the area it has been
placed into.

</div>

<div class="box4">Four</div>

</div>

.wrapper {

display: grid;

grid-template-columns: repeat(4,1fr);

grid-auto-rows: 200px;

gap: 20px;

position: relative;

.box3 {

grid-column-start: 2;

grid-column-end: 4;

grid-row-start: 1;

grid-row-end: 3;

position: absolute;

top: 40px;

left: 40px;

One Two Four

This block is absolutely positioned. In this example the grid


container is the containing block and so the absolute
positioning offset values are calculated in from the outer
edges of the area it has been placed into.

You can see that the item is taking the area from grid column line 2 to 4, and starting after line 1. Then it is offset in that area
using the top and left properties. However, it has been taken out of flow as is usual for absolutely positioned items and so the
auto-placement rules now place items into the same space. The item also doesn't cause the additional row to be created to
span to row line 3.
If we remove position: absolute from the rules for .box3 you can see how it would display without the positioning.
A grid container as parent
If the absolutely positioned child has a grid container as a parent but that container does not create a new positioning context,
then it is taken out of flow as in the previous example. The positioning context wil be whatever element creates a positioning
context as is common to other layout methods. In our case, if we remove position: relative from the wrapper above,
positioning context is from the viewport, as shown in this image.

Once again the item no longer participates in the grid layout in terms of sizing or when other items are auto-placed.
With a grid area as the parent
If the absolutely positioned item is nested inside a grid area then you can create a positioning context on that area. In the
below example we have our grid as before but this time I have nested an item inside .box3 of the grid.
I have given .box3 position relative and then positioned the sub-item with the offset properties. In this case, the positioning
context is the grid area.
<div class="wrapper">

<div class="box1">One</div>

<div class="box2">Two</div>

<div class="box3">Three

<div class="abspos">

This block is absolutely positioned. In this example the grid area is the containing block and so the
absolute positioning offset values are calculated in from the outer edges of the grid area.

</div>

</div>

<div class="box4">Four</div>

</div>

.wrapper {

display: grid;

grid-template-columns: repeat(4,1fr);

grid-auto-rows: 200px;

gap: 20px;

.box3 {

grid-column-start: 2;

grid-column-end: 4;

grid-row-start: 1;

grid-row-end: 3;

position: relative;

.abspos {

position: absolute;

top: 40px;

left: 40px;

background-color: rgba(255,255,255,.5);

border: 1px solid rgba(0,0,0,0.5);

color: #000;

padding: 10px;

One Three Two

This block is absolutely positioned. In this example the grid


area is the containing block and so the absolute positioning
offset values are calculated in from the outer edges of the
grid area.

Four

Grid and display: contents


A final interaction with another layout specification that is worth noting is the interaction between CSS Grid Layout and
display: contents . The contents value of the display property is a new value that is described in the Display specification
as follows:

"The element itself does not generate any boxes, but its children and pseudo-elements stil generate boxes as normal.
For the purposes of box generation and layout, the element must be treated as if it had been replaced with its children
and pseudo-elements in the document tree."

If you set an item to display: contents , the box it would normally create disappears and the boxes of the child elements
appear as if they have risen up a level. This means that children of a grid item can become grid items. Sound odd? Here is a
simple example.
Grid layout with nested child elements
In the following markup, I have a grid and the first item on the grid is set to span all three column tracks. It contains three
nested items. As these items are not direct children, they don't become part of the grid layout and so display using regular block
layout.
<div class="wrapper">

<div class="box box1">

<div class="nested">a</div>

<div class="nested">b</div>

<div class="nested">c</div>

</div>

<div class="box box2">Two</div>

<div class="box box3">Three</div>

<div class="box box4">Four</div>

<div class="box box5">Five</div>

</div>

.wrapper {

display: grid;

grid-template-columns: repeat(3, 1fr);

grid-auto-rows: minmax(100px, auto);

.box1 {

grid-column-start: 1;

grid-column-end: 4;

Two Three Four

Five
Using display: contents
If I now add display: contents to the rules for box1 , the box for that item vanishes and the sub-items now become grid
items and lay themselves out using the auto-placement rules.
<div class="wrapper">

<div class="box box1">

<div class="nested">a</div>

<div class="nested">b</div>

<div class="nested">c</div>

</div>

<div class="box box2">Two</div>

<div class="box box3">Three</div>

<div class="box box4">Four</div>

<div class="box box5">Five</div>

</div>

.wrapper {

display: grid;

grid-template-columns: repeat(3, 1fr);

grid-auto-rows: minmax(100px, auto);

.box1 {

grid-column-start: 1;

grid-column-end: 4;

display: contents;

a b c

Two Three Four

Five

This can be a way to get items nested into the grid to act as if they are part of the grid, and is a way around some of the
issues that would be solved by subgrids once they are implemented. You can also use display: contents in a similar way
with flexbox to enable nested items to become flex items.
As you can see from this guide, CSS Grid Layout is just one part of your toolkit. Don't be afraid to mix it with other methods of
doing layout to get the different effects you need.

See also
Flexbox Guides
Multiple-column Layout Guides

Last modified: May 20, 2022, by MDN contributors


MDN Plus now available in your country! Support MDN and make it your own. Learn more ✨

Relationship of grid layout to other layout methods


CSS Grid Layout has been designed to work alongside other parts of CSS, as part of a complete system for doing the layout. In
this guide, I wil explain how a grid fits together with other techniques you may already be using.

Grid and flexbox


The basic difference between CSS Grid Layout and CSS Flexbox Layout is that flexbox was designed for layout in one
dimension - either a row or a column. Grid was designed for two-dimensional layout - rows, and columns at the same time. The
two specifications share some common features, however, and if you have already learned how to use flexbox, the similarities
should help you get to grips with Grid.
One-dimensional versus two-dimensional layout
A simple example can demonstrate the difference between one- and two-dimensional layouts.
In this first example, I am using flexbox to lay out a set of boxes. I have five child items in my container, and I have given the
flex properties values so that they can grow and shrink from a flex-basis of 150 pixels.
I have also set the flex-wrap property to wrap , so that if the space in the container becomes too narrow to maintain the flex
basis, items wil wrap onto a new row.
<div class="wrapper">

<div>One</div>

<div>Two</div>

<div>Three</div>

<div>Four</div>

<div>Five</div>

</div>

.wrapper {

width: 500px;

display: flex;

flex-wrap: wrap;

.wrapper > div {

flex: 1 1 150px;

One Two Three

Four Five

In the image, you can see that two items have wrapped onto a new line. These items are sharing the available space and not
lining up underneath the items above. This is because when you wrap flex items, each new row (or column when working by
column) is an independent flex line in the flex container. Space distribution happens across the flex line.
A common question then is how to make those items line up. This is where you want a two-dimensional layout method: You
want to control the alignment by row and column, and this is where grid comes in.
The same layout with CSS grids
In this next example, I create the same layout using Grid. This time we have three 1fr column tracks. We do not need to set
anything on the items themselves; they wil lay themselves out one into each cell of the created grid. As you can see they stay
in a strict grid, lining up in rows and columns. With five items, we get a gap on the end of row two.
<div class="wrapper">

<div>One</div>

<div>Two</div>

<div>Three</div>

<div>Four</div>

<div>Five</div>

</div>

.wrapper {

display: grid;

grid-template-columns: repeat(3, 1fr);

One Two Three

Four Five

A simple question to ask yourself when deciding between grid or flexbox is:
do I only need to control the layout by row or column – use a flexbox
do I need to control the layout by row and column – use a grid
Content out or layout in?
In addition to the one-dimensional versus two-dimensional distinction, there is another way to decide if you should use flexbox
or grid for a layout. Flexbox works from the content out. An ideal use case for flexbox is when you have a set of items and
want to space them out evenly in a container. You let the size of the content decide how much individual space each item
takes up. If the items wrap onto a new line, they wil work out their spacing based on their size and the available space on that
line.
Grid works from the layout in. When you use CSS Grid Layout you create a layout and then you place items into it, or you allow
the auto-placement rules to place the items into the grid cells according to that strict grid. It is possible to create tracks that
respond to the size of the content, however, they wil also change the entire track.
If you are using flexbox and find yourself disabling some of the flexibility, you probably need to use CSS Grid Layout. An
example would be if you are setting a percentage width on a flex item to make it line up with other items in a row above. In that
case, a grid is likely to be a better choice.
Box alignment
The feature of flexbox that was most exciting to many of us was that it gave us proper alignment control for the first time. It
made it easy to center a box on the page. Flex items can stretch to the height of the flex container, meaning that equal height
columns were possible. These were things we have wanted to do for a very long time, and have come up with all kinds of
hacks to accomplish, at least visually.
The alignment properties from the flexbox specification have been added to a new specification called Box Alignment Level 3 .
This means that they can be used in other specifications, including Grid Layout. In the future, they may well apply to other
layout methods as well.
In a later guide in this series, I'l be taking a proper look at Box Alignment and how it works in Grid Layout. For now, here is a
comparison between simple examples of flexbox and grid.
In the first example, which uses flexbox, I have a container with three items inside. The wrapper min-height is set, so it
defines the height of the flex container. I have set align-items on the flex container to flex-end so the items wil line up at
the end of the flex container. I have also set the align-self property on box1 so it wil override the default and stretch to
the height of the container and on box2 so it aligns to the start of the flex container.
<div class="wrapper">

<div class="box1">One</div>

<div class="box2">Two</div>

<div class="box3">Three</div>

</div>

.wrapper {

display: flex;

align-items: flex-end;

min-height: 200px;

.box1 {

align-self: stretch;

.box2 {

align-self: flex-start;

One Two

Three

Alignment in CSS Grids


This second example uses a grid to create the same layout. This time we are using the box alignment properties as they apply
to a grid layout. So we align to start and end rather than flex-start and flex-end . In the case of a grid layout, we are
aligning the items inside their grid area. In this case that is a single grid cell, but it could be an area made up of several grid cells.
<div class="wrapper">

<div class="box1">One</div>

<div class="box2">Two</div>

<div class="box3">Three</div>

</div>

.wrapper {

display: grid;

grid-template-columns: repeat(3,1fr);

align-items: end;

grid-auto-rows: 200px;

.box1 {

align-self: stretch;

.box2 {

align-self: start;

One Two

Three

The fr unit and flex-basis


We have already seen how the fr unit works to assign a proportion of available space in the grid container to our grid tracks.
The fr unit, when combined with the minmax() function can give us very similar behavior to the flex properties in flexbox
while stil enabling the creation of a layout in two dimensions.
If we look back at the example where I demonstrated the difference between one and two-dimensional layouts, you can see
there is a difference between the way that the two layouts work responsively. With the flex layout, if we drag our window wider
and smaller, the flexbox does a nice job of adjusting the number of items in each row according to the available space. If we
have a lot of space all five items can fit on one row. If we have a very narrow container we may only have space for one.
In comparison, the grid version always has three column tracks. The tracks themselves wil grow and shrink, but there are
always three since we asked for three when defining our grid.
Auto-filling grid tracks
We can use grid to create a similar effect to flexbox, while stil keeping the content arranged in strict rows and columns, by
creating our track listing using repeat notation and the auto-fill and auto-fit properties.
In this next example, I have used the auto-fill keyword in place of an integer in the repeat notation and set the track listing
to 200 pixels. This means that grid wil create as many 200 pixels column tracks as wil fit in the container.
<div class="wrapper">

<div>One</div>

<div>Two</div>

<div>Three</div>

</div>

.wrapper {

display: grid;

grid-template-columns: repeat(auto-fill, 200px);

One Two Three

A flexible number of tracks


This isn't quite the same as flexbox. In the flexbox example, the items are larger than the 200 pixel basis before wrapping. We
can achieve the same in grid by combining auto-fit and the minmax() function. In this next example, I create auto fil ed
tracks with minmax . I want my tracks to be a minimum of 200 pixels, so I set the maximum to be 1fr . Once the browser has
worked out how many times 200 pixels wil fit into the container–also taking account of grid gaps–it wil treat the 1fr maximum
as an instruction to share out the remaining space between the items.
<div class="wrapper">

<div>One</div>

<div>Two</div>

<div>Three</div>

</div>

.wrapper {

display: grid;

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

One Two Three

We now have the ability to create a grid with a flexible number of flexible tracks, but see items laid out on the grid aligned by
rows and columns at the same time.

Grid and absolutely positioned elements


Grid interacts with absolutely positioned elements, which can be useful if you want to position an item inside a grid or grid area.
The specification defines the behavior when a grid container is a containing block and a parent of the absolutely positioned
item.
A grid container as containing block
To make the grid container a containing block you need to add the position property to the container with a value of relative,
just as you would make a containing block for any other absolutely positioned items. Once you have done this, if you give a grid
item position: absolute it wil take as its containing block the grid container or, if the item also has a grid position, the area
of the grid it is placed into.
In the below example I have a wrapper containing four child items. Item three is absolutely positioned and also placed on the
grid using line-based placement. The grid container has position: relative and so becomes the positioning context of this
item.
<div class="wrapper">

<div class="box1">One</div>

<div class="box2">Two</div>

<div class="box3">

This block is absolutely positioned. In this example the grid container is the containing block and so
the absolute positioning offset values are calculated in from the outer edges of the area it has been
placed into.

</div>

<div class="box4">Four</div>

</div>

.wrapper {

display: grid;

grid-template-columns: repeat(4,1fr);

grid-auto-rows: 200px;

gap: 20px;

position: relative;

.box3 {

grid-column-start: 2;

grid-column-end: 4;

grid-row-start: 1;

grid-row-end: 3;

position: absolute;

top: 40px;

left: 40px;

One Two Four

This block is absolutely positioned. In this example the grid


container is the containing block and so the absolute
positioning offset values are calculated in from the outer
edges of the area it has been placed into.

You can see that the item is taking the area from grid column line 2 to 4, and starting after line 1. Then it is offset in that area
using the top and left properties. However, it has been taken out of flow as is usual for absolutely positioned items and so the
auto-placement rules now place items into the same space. The item also doesn't cause the additional row to be created to
span to row line 3.
If we remove position: absolute from the rules for .box3 you can see how it would display without the positioning.
A grid container as parent
If the absolutely positioned child has a grid container as a parent but that container does not create a new positioning context,
then it is taken out of flow as in the previous example. The positioning context wil be whatever element creates a positioning
context as is common to other layout methods. In our case, if we remove position: relative from the wrapper above,
positioning context is from the viewport, as shown in this image.

Once again the item no longer participates in the grid layout in terms of sizing or when other items are auto-placed.
With a grid area as the parent
If the absolutely positioned item is nested inside a grid area then you can create a positioning context on that area. In the
below example we have our grid as before but this time I have nested an item inside .box3 of the grid.
I have given .box3 position relative and then positioned the sub-item with the offset properties. In this case, the positioning
context is the grid area.
<div class="wrapper">

<div class="box1">One</div>

<div class="box2">Two</div>

<div class="box3">Three

<div class="abspos">

This block is absolutely positioned. In this example the grid area is the containing block and so the
absolute positioning offset values are calculated in from the outer edges of the grid area.

</div>

</div>

<div class="box4">Four</div>

</div>

.wrapper {

display: grid;

grid-template-columns: repeat(4,1fr);

grid-auto-rows: 200px;

gap: 20px;

.box3 {

grid-column-start: 2;

grid-column-end: 4;

grid-row-start: 1;

grid-row-end: 3;

position: relative;

.abspos {

position: absolute;

top: 40px;

left: 40px;

background-color: rgba(255,255,255,.5);

border: 1px solid rgba(0,0,0,0.5);

color: #000;

padding: 10px;

One Three Two

This block is absolutely positioned. In this example the grid


area is the containing block and so the absolute positioning
offset values are calculated in from the outer edges of the
grid area.

Four

Grid and display: contents


A final interaction with another layout specification that is worth noting is the interaction between CSS Grid Layout and
display: contents . The contents value of the display property is a new value that is described in the Display specification
as follows:

"The element itself does not generate any boxes, but its children and pseudo-elements stil generate boxes as normal.
For the purposes of box generation and layout, the element must be treated as if it had been replaced with its children
and pseudo-elements in the document tree."

If you set an item to display: contents , the box it would normally create disappears and the boxes of the child elements
appear as if they have risen up a level. This means that children of a grid item can become grid items. Sound odd? Here is a
simple example.
Grid layout with nested child elements
In the following markup, I have a grid and the first item on the grid is set to span all three column tracks. It contains three
nested items. As these items are not direct children, they don't become part of the grid layout and so display using regular block
layout.
<div class="wrapper">

<div class="box box1">

<div class="nested">a</div>

<div class="nested">b</div>

<div class="nested">c</div>

</div>

<div class="box box2">Two</div>

<div class="box box3">Three</div>

<div class="box box4">Four</div>

<div class="box box5">Five</div>

</div>

.wrapper {

display: grid;

grid-template-columns: repeat(3, 1fr);

grid-auto-rows: minmax(100px, auto);

.box1 {

grid-column-start: 1;

grid-column-end: 4;

Two Three Four

Five
Using display: contents
If I now add display: contents to the rules for box1 , the box for that item vanishes and the sub-items now become grid
items and lay themselves out using the auto-placement rules.
<div class="wrapper">

<div class="box box1">

<div class="nested">a</div>

<div class="nested">b</div>

<div class="nested">c</div>

</div>

<div class="box box2">Two</div>

<div class="box box3">Three</div>

<div class="box box4">Four</div>

<div class="box box5">Five</div>

</div>

.wrapper {

display: grid;

grid-template-columns: repeat(3, 1fr);

grid-auto-rows: minmax(100px, auto);

.box1 {

grid-column-start: 1;

grid-column-end: 4;

display: contents;

a b c

Two Three Four

Five

This can be a way to get items nested into the grid to act as if they are part of the grid, and is a way around some of the
issues that would be solved by subgrids once they are implemented. You can also use display: contents in a similar way
with flexbox to enable nested items to become flex items.
As you can see from this guide, CSS Grid Layout is just one part of your toolkit. Don't be afraid to mix it with other methods of
doing layout to get the different effects you need.

See also
Flexbox Guides
Multiple-column Layout Guides

Last modified: May 20, 2022, by MDN contributors


MDN Plus now available in your country! Support MDN and make it your own. Learn more ✨

Basic Concepts of grid layout


CSS Grid Layout introduces a two-dimensional grid system to CSS. Grids can be used to lay out major page areas or small user
interface elements. This article introduces the CSS Grid Layout and the new terminology that is part of the CSS Grid Layout
Level 1 specification. The features shown in this overview wil then be explained in greater detail in the rest of this guide.

What is a grid?
A grid is a set of intersecting horizontal and vertical lines defining columns and rows. Elements can be placed onto the grid
within these column and row lines. CSS grid layout has the following features:
Fixed and flexible track sizes
You can create a grid with fixed track sizes – using pixels for example. This sets the grid to the specified pixel which fits to the
layout you desire. You can also create a grid using flexible sizes with percentages or with the new fr unit designed for this
purpose.
Item placement
You can place items into a precise location on the grid using line numbers, names or by targeting an area of the grid. Grid also
contains an algorithm to control the placement of items not given an explicit position on the grid.
Creation of additional tracks to hold content
You can define an explicit grid with grid layout. The Grid Layout specification is flexible enough to add additional rows and
columns when needed. Features such as adding "as many columns that wil fit into a container" are included.
Alignment control
Grid contains alignment features so we can control how the items align once placed into a grid area, and how the entire grid is
aligned.
Control of overlapping content
More than one item can be placed into a grid cell or area and they can partial y overlap each other. This layering may then be
controlled with the z-index property.
Grid is a powerful specification that, when combined with other parts of CSS such as flexbox, can help you create layouts that
were previously impossible to build in CSS. It all starts by creating a grid in your grid container.

The Grid container


We create a grid container by declaring display: grid or display: inline-grid on an element. As soon as we do this, all
direct children of that element become grid items.
In this example, I have a containing div with a class of wrapper and, inside are five child elements.
<div class="wrapper">

<div>One</div>

<div>Two</div>

<div>Three</div>

<div>Four</div>

<div>Five</div>

</div>

I make the .wrapper a grid container.


.wrapper {

display: grid;

One

Two

Three

Four

Five

All the direct children are now grid items. In a web browser, you won't see any difference to how these items are displayed
before turning them into a grid, as grid has created a single column grid for the items. At this point, you may find it useful to work
with the Grid Inspector , available as part of Firefox's Developer Tools. If you view this example in Firefox and inspect the grid,
you wil see a small icon next to the value grid . Click this and then the grid on this element wil be overlaid in the browser
window.
As you learn and then work with the CSS Grid Layout, this tool wil give you a better idea of what is happening with your grids
visually.
If we want to start making this more grid-like we need to add column tracks.

Grid tracks
We define rows and columns on our grid with the grid-template-rows and grid-template-columns properties. These
define grid tracks. A grid track is the space between any two lines on the grid. In the below image you can see a track
highlighted – this is the first row track in our grid.
Basic example
I can add to our earlier example by adding the grid-template-columns property, then defining the size of the column tracks.
I have now created a grid with three 200-pixel-wide column tracks. The child items wil be laid out on this grid one in each grid
cell.
<div class="wrapper">

<div>One</div>

<div>Two</div>

<div>Three</div>

<div>Four</div>

<div>Five</div>

</div>

.wrapper {

display: grid;

grid-template-columns: 200px 200px 200px;

One Two Three

Four Five

The fr unit
Tracks can be defined using any length unit. Grid also introduces an additional length unit to help us create flexible grid tracks.
The new fr unit represents a fraction of the available space in the grid container. The next grid definition would create three
equal width tracks that grow and shrink according to the available space.
<div class="wrapper">

<div>One</div>

<div>Two</div>

<div>Three</div>

<div>Four</div>

<div>Five</div>

</div>

.wrapper {

display: grid;

grid-template-columns: 1fr 1fr 1fr;

One Two Three

Four Five

Unequal sizes
In this next example, we create a definition with a 2fr track then two 1fr tracks. The available space is split into four. Two
parts are given to the first track and one part each to the next two tracks.
<div class="wrapper">

<div>One</div>

<div>Two</div>

<div>Three</div>

<div>Four</div>

<div>Five</div>

</div>

.wrapper {

display: grid;

grid-template-columns: 2fr 1fr 1fr;

One Two Three

Four Five

Mixing flexible and absolute sizes


In this final example, we mix absolute sized tracks with fr units. The first track is 500 pixels, so the fixed width is taken away
from the available space. The remaining space is divided into three and assigned in proportion to the two flexible tracks.
<div class="wrapper">

<div>One</div>

<div>Two</div>

<div>Three</div>

<div>Four</div>

<div>Five</div>

</div>

.wrapper {

display: grid;

grid-template-columns: 500px 1fr 2fr;

One Two Three

Four Five

Track listings with repeat() notation


Large grids with many tracks can use the repeat() notation, to repeat all or a section of the track listing. For example the grid
definition:
.wrapper {

display: grid;

grid-template-columns: 1fr 1fr 1fr;

Can also be written as:


.wrapper {

display: grid;

grid-template-columns: repeat(3, 1fr);

Repeat notation can be used for a part of the track listing. In this next example I have created a grid with an initial 20-pixel
track, then a repeating section of 6 1fr tracks then a final 20-pixel track.
.wrapper {

display: grid;

grid-template-columns: 20px repeat(6, 1fr) 20px;

Repeat notation takes the track listing, and uses it to create a repeating pattern of tracks. In this next example, my grid wil
consist of 10 tracks, a 1fr track, and then followed by a 2fr track. This pattern wil be repeated five times.
.wrapper {

display: grid;

grid-template-columns: repeat(5, 1fr 2fr);

The implicit and explicit grid


When creating our example grid we specifically defined our column tracks with the grid-template-columns property, but the
grid also created rows on its own. These rows are part of the implicit grid. Whereas the explicit grid consists of any rows and
columns defined with grid-template-columns or grid-template-rows .
If you place something outside of the defined grid—or due to the amount of content, more grid tracks are needed—then the
grid creates rows and columns in the implicit grid. These tracks wil be auto-sized by default, resulting in their size being based
on the content that is inside them.
You can also define a set size for tracks created in the implicit grid with the grid-auto-rows and grid-auto-columns
properties.
In the below example we use grid-auto-rows to ensure that tracks created in the implicit grid are 200 pixels tall.
<div class="wrapper">

<div>One</div>

<div>Two</div>

<div>Three</div>

<div>Four</div>

<div>Five</div>

</div>

.wrapper {

display: grid;

grid-template-columns: repeat(3, 1fr);

grid-auto-rows: 200px;

One Two Three

Four Five

Track sizing and minmax


When setting up an explicit grid or defining the sizing for automatically created rows or columns we may want to give tracks a
minimum size, but also ensure they expand to fit any content that is added. For example, I may want my rows to never collapse
smaller than 100 pixels, but if my content stretches to 300 pixels in height, then I would like the row to stretch to that height.
Grid has a solution for this with the minmax() function. In this next example I am using minmax() in the value of grid-auto-
rows . This means automatically created rows wil be a minimum of 100 pixels tall, and a maximum of auto . Using auto means
that the size wil look at the content size and wil stretch to give space for the tallest item in a cell, in this row.
.wrapper {

display: grid;

grid-template-columns: repeat(3, 1fr);

grid-auto-rows: minmax(100px, auto);

<div class="wrapper">

<div>One</div>

<div>Two

<p>I have some more content in.</p>

<p>This makes me taller than 100 pixels.</p>

</div>

<div>Three</div>

<div>Four</div>

<div>Five</div>

</div>

One Two Three

I have some more content in.

This makes me taller than 100 pixels.

Four Five

Grid lines
It should be noted that when we define a grid we define the grid tracks, not the lines. Grid then gives us numbered lines to use
when positioning items. In our three column, two row grid we have four column lines.
Lines are numbered according to the writing mode of the document. In a left-to-right language, line 1 is on the left-hand side of
the grid. In a right-to-left language, it is on the right-hand side of the grid. Lines can also be named, and we wil look at how to
do this in a later guide in this series.
Positioning items against lines
We wil be exploring line based placement in full detail in a later article. The following example demonstrates doing this in a
simple way. When placing an item, we target the line – rather than the track.
In the following example I am placing the first two items on our three column track grid, using the grid-column-start , grid-
column-end , grid-row-start and grid-row-end properties. Working from left to right, the first item is placed against column
line 1, and spans to column line 4, which in our case is the far-right line on the grid. It begins at row line 1 and ends at row line 3,
therefore spanning two row tracks.
The second item starts on grid column line 1, and spans one track. This is the default so I do not need to specify the end line. It
also spans two row tracks from row line 3 to row line 5. The other items wil place themselves into empty spaces on the grid.
<div class="wrapper">

<div class="box1">One</div>

<div class="box2">Two</div>

<div class="box3">Three</div>

<div class="box4">Four</div>

<div class="box5">Five</div>

</div>

.wrapper {

display: grid;

grid-template-columns: repeat(3, 1fr);

grid-auto-rows: 100px;

.box1 {

grid-column-start: 1;

grid-column-end: 4;

grid-row-start: 1;

grid-row-end: 3;

.box2 {

grid-column-start: 1;

grid-row-start: 3;

grid-row-end: 5;

One

Two Three Four

Five

Note: Don't forget that you can use the Grid Inspector in Firefox Developer Tools to see how the items are
positioned against the lines of the grid.

Line-positioning shorthands
The longhand values used above can be compressed onto one line for columns with grid-column , and one line for rows with
grid-row . The following example would give the same positioning as in the previous code, but with far less CSS. The value
before the forward slash character ( / ) is the start line, the value after the end line.
You can omit the end value if the area only spans one track.
.wrapper {

display: grid;

grid-template-columns: repeat(3, 1fr);

grid-auto-rows: 100px;

.box1 {

grid-column: 1 / 4;

grid-row: 1 / 3;

.box2 {

grid-column: 1;

grid-row: 3 / 5;

Grid cells
A grid cell is the smallest unit on a grid. Conceptually it is like a table cell. As we saw in our earlier examples, once a grid is
defined as a parent the child items wil lay themselves out in one cell each of the defined grid. In the below image, I have
highlighted the first cell of the grid.
Grid areas
Items can span one or more cells both by row or by column, and this creates a grid area. Grid areas must be rectangular – it
isn't possible to create an L-shaped area for example. The highlighted grid area spans two row and two column tracks.
Gutters
Gutters or alleys between grid cells can be created using the column-gap and row-gap properties, or the shorthand gap . In
the below example, I am creating a 10-pixel gap between columns and a 1em gap between rows.
.wrapper {

display: grid;

grid-template-columns: repeat(3, 1fr);

column-gap: 10px;

row-gap: 1em;

Note: When grid first shipped in browsers the column-gap , row-gap and gap were prefixed with the grid- prefix
as grid-column-gap , grid-row-gap and grid-gap respectively.
Browsers all now support unprefixed values, however the prefixed versions wil be maintained as aliases making them
safe to use.
<div class="wrapper">

<div>One</div>

<div>Two</div>

<div>Three</div>

<div>Four</div>

<div>Five</div>

</div>

One Two Three

Four Five

Any space used by gaps wil be accounted for before space is assigned to the flexible length fr tracks, and gaps act for sizing
purposes like a regular grid track, however you cannot place anything into a gap. In terms of line-based positioning, the gap acts
like a thick line.

Nesting grids
A grid item can become a grid container. In the following example, I have the three-column grid that I created earlier, with our
two positioned items. In this case the first item has some sub-items. As these items are not direct children of the grid they do
not participate in grid layout and so display in a normal document flow.
Nesting without subgrid
If I set box1 to display: grid I can give it a track definition and it too wil become a grid. The items then lay out on this new
grid.
.box1 {

grid-column-start: 1;

grid-column-end: 4;

grid-row-start: 1;

grid-row-end: 3;

display: grid;

grid-template-columns: repeat(3, 1fr);

* {box-sizing: border-box;}

.wrapper {

border: 2px solid #f76707;

border-radius: 5px;

background-color: #fff4e6;

display: grid;

grid-template-columns: repeat(3, 1fr);

.box {

border: 2px solid #ffa94d;

border-radius: 5px;

background-color: #ffd8a8;

padding: 1em;

color: #d9480f;

.box1 {

grid-column: 1 / 4;

.nested {

border: 2px solid #ffec99;

border-radius: 5px;

background-color: #fff9db;

padding: 1em;

a b c

Two Three Four

Five

In this case the nested grid has no relationship to the parent. As you can see in the example it has not inherited the gap of the
parent and the lines in the nested grid do not align to the lines in the parent grid.
Subgrid
In the working draft of the Level 2 Grid specification there is a feature called subgrid, which would let us create nested grids
that use the track definition of the parent grid.

Note: This feature shipped in Firefox 71, which is currently the only browser to implement subgrid.
In the current specification, we would edit the above nested grid example to change the track definition of grid-template-
columns: repeat(3, 1fr) , to grid-template-columns: subgrid . The nested grid wil then use the parent grid tracks to
layout items.
.box1 {

grid-column-start: 1;

grid-column-end: 4;

grid-row-start: 1;

grid-row-end: 3;

display: grid;

grid-template-columns: subgrid;

Layering items with z-index


Grid items can occupy the same cell, and in this case we can use the z-index property to control the order in which
overlapping items stack.
Overlapping without z-index
If we return to our example with items positioned by line number, we can change this to make two items overlap.
<div class="wrapper">

<div class="box box1">One</div>

<div class="box box2">Two</div>

<div class="box box3">Three</div>

<div class="box box4">Four</div>

<div class="box box5">Five</div>

</div>

.wrapper {

display: grid;

grid-template-columns: repeat(3, 1fr);

grid-auto-rows: 100px;

.box1 {

grid-column-start: 1;

grid-column-end: 4;

grid-row-start: 1;

grid-row-end: 3;

.box2 {

grid-column-start: 1;

grid-row-start: 2;

grid-row-end: 4;

One

Two

Three Four

Five

The item box2 is now overlapping box1 , it displays on top as it comes later in the source order.
Controlling the order
We can control the order in which items stack up by using the z-index property - just like positioned items. If we give box2 a
lower z-index than box1 it wil display below box1 in the stack.
.wrapper {

display: grid;

grid-template-columns: repeat(3, 1fr);

grid-auto-rows: 100px;

.box1 {

grid-column-start: 1;

grid-column-end: 4;

grid-row-start: 1;

grid-row-end: 3;

z-index: 2;

.box2 {

grid-column-start: 1;

grid-row-start: 2;

grid-row-end: 4;

z-index: 1;

One

Two

Three Four

Five

Next Steps
In this article we have had a very quick look through the Grid Layout Specification. Have a play with the code examples, and
then move onto the next part of this guide where we wil really start to dig into the detail of CSS Grid Layout.

Last modified: Jun 18, 2022, by MDN contributors


MDN Plus now available in your country! Support MDN and make it your own. Learn more ✨

Subgrid
Level 2 of the CSS Grid Layout specification includes a subgrid value for grid-template-columns and grid-template-rows . This guide details what subgrid does, and gives some use
cases and design patterns that are solved by the feature.

Introduction to subgrid
When you add display: grid to a grid container, only the direct children become grid items and can then be placed on the grid that you have created. The children of these items display
in normal flow.
You can "nest" grids by making a grid item a grid container. These grids however are independent of the parent grid and of each other, meaning that they do not take their track sizing from
the parent grid. This makes it difficult to line nested grid items up with the main grid.
If you set the value subgrid on grid-template-columns , grid-template-rows or both, instead of creating a new track listing the nested grid uses the tracks defined on the parent.
For example, if you use grid-template-columns: subgrid and the nested grid spans three column tracks of the parent, the nested grid wil have three column tracks of the same size as
the parent grid. Gaps are inherited but can also be overridden with a different gap value. Line names can be passed from the parent into the subgrid, and the subgrid can also declare its own
line names.

Subgrid for columns


In the example below I have a grid layout with nine 1fr column tracks and four rows that are a minimum of 100px tall.
I place .item from column line 2 to 7, and row 2 to 4. I then make this grid item into a grid, giving it column tracks that are a subgrid and defining rows as normal. As the item spans five
column tracks, this means that the subgrid has five column tracks. I can then place .subitem on this grid.
The rows in this example are not a subgrid and so behave as a nested grid does normally. The grid area on the parent expands to be large enough for this nested grid.
.grid {

display: grid;

grid-template-columns: repeat(9, 1fr);

grid-template-rows: repeat(4, minmax(100px, auto));

.item {

display: grid;

grid-column: 2 / 7;

grid-row: 2 / 4;

grid-template-columns: subgrid;

grid-template-rows: repeat(3, 80px);

.subitem {

grid-column: 3 / 6;

grid-row: 1 / 3;

<div class="grid">

<div class="item">

<div class="subitem"></div>

</div>

</div>

Reset
Note that line numbering restarts inside the subgrid — column line 1, when inside the subgrid, is the first line of the subgrid. The subgridded element doesn't inherit the line numbers of the
parent grid. This means that you can safely lay out a component that may be placed in different positions on the main grid, knowing that the line numbers on the component wil always be
the same.

Subgrid for rows


The next example is the same setup, however we are using subgrid as the value of grid-template-rows and defining explicit column tracks. So the column tracks behave as a regular
nested grid, but the rows are tied to the two tracks that the child spans.

.grid {

display: grid;

grid-template-columns: repeat(9, 1fr);

grid-template-rows: repeat(4, minmax(100px, auto));

.item {

display: grid;

grid-column: 2 / 7;

grid-row: 2 / 4;

grid-template-columns: repeat(3, 1fr);

grid-template-rows: subgrid;

.subitem {

grid-column: 2 / 4;

grid-row: 1 / 3;

<div class="grid">

<div class="item">

<div class="subitem"></div>

</div>

</div>

Reset

A subgrid in both dimensions


You can of course define both rows and columns as a subgrid, as in the example below. This means that your subgrid is tied in both dimensions to the number of tracks on the parent.

.grid {

display: grid;

grid-template-columns: repeat(9, 1fr);

grid-template-rows: repeat(4, minmax(100px, auto));

.item {

display: grid;

grid-column: 2 / 7;

grid-row: 2 / 4;

id t l t l b id
grid-template-columns: subgrid;

grid-template-rows: subgrid;

.subitem {

grid-column: 3 / 6;

grid-row: 1 / 3;

<div class="grid">

<div class="item">

<div class="subitem"></div>

</div>

</div>

Reset

No implicit grid in a subgridded dimension


If you need to autoplace items, and do not know how many items you wil have, take care when creating a subgrid, as it wil prevent additional rows being created to hold those items.
Take a look at the next example — it uses the same parent and child grid as in the example above, however inside the subgrid I have twelve items trying to autoplace into ten grid cells. As
the subgrid is on both dimensions there is nowhere for the extra two items to go and so they go into the last track of the grid, as defined in the specification.

1
2
3
4
5
6
7
7
8
9
10
11
12

.grid {

display: grid;

grid-template-columns: repeat(9, 1fr);

grid-template-rows: repeat(4, minmax(100px, auto));

.item {

display: grid;

grid-column: 2 / 7;

grid-row: 2 / 4;

grid-template-columns: subgrid;

grid-template-rows: subgrid;

<div class="grid">

<div class="item">

<div class="subitem">1</div>

<div class="subitem">2</div>

<div class="subitem">3</div>

<div class="subitem">4</div>

<div class="subitem">5</div>

<div class="subitem">6</div>

<div class="subitem">7</div>

<div class="subitem">8</div>

<div class="subitem">9</div>

Reset

If we remove the grid-template-rows value we enable regular creation of implicit tracks and, although these won't line up with the tracks of the parent, as many as are required wil be
created.
1

10

11
The gap properties and subgrid
If you have a gap , column-gap , or row-gap specified on the parent, this wil be passed into the subgrid, so it wil have the same spacing between tracks as the parent. In some situations
however you may wish the subgrid tracks to have a different gap or no gap. This can be achieved by using the gap-* properties on the grid container of the subgrid.
You can see this in the example below. The parent grid has a gap of 20px for rows and columns. The subgrid has row-gap set to 0 .

.grid {

display: grid;

grid-template-columns: repeat(9, 1fr);

grid-template-rows: repeat(4, minmax(100px, auto));

gap: 20px;

.item {

display: grid;

grid-column: 2 / 7;

grid-row: 2 / 4;

grid-template-columns: subgrid;

grid-template-rows: subgrid;

row-gap: 0;

.subitem {

grid-column: 3 / 6;

grid-row: 1 / 3;

<div class="grid">
<div class grid >

<div class="item">

<div class="subitem"></div>

<div class="subitem2"></div>

</div>

</div>

Reset

If you inspect this in the Firefox Grid Inspector you can see how the line of the grid is in the correct place down the center of the gap, so when we set the gap to 0, it acts in a similar way to
applying a negative margin to an element, giving the space from the gap back to the item.
Named grid lines
When using CSS Grid you can name lines on your grid and then position items based on those names rather than the line number. The line names on the parent grid are passed into the
subgrid, and you can place items using them. In the below example I have named lines on the parent col-start and col-end and then used those to place the subitem.
.grid {

display: grid;

grid-template-columns: 1fr 1fr 1fr [col-start] 1fr 1fr 1fr [col-


end] 1fr 1fr 1fr;

grid-template-rows: repeat(4, minmax(100px, auto));

gap: 20px;

.item {

display: grid;

grid-column: 2 / 7;

grid-row: 2 / 4;

grid-template-columns: subgrid;

grid-template-rows: subgrid;

.subitem {

grid-column: col-start / col-end;

grid-row: 1 / 3;

<div class="grid">

<div class="item">

<div class="subitem"></div>

</div>

</div>

Reset
You can also specify line names on the subgrid. This is achieved by adding a list of line names enclosed in square brackets after the subgrid keyword. If you have four lines in your subgrid,
to name them all you could use the syntax grid-template-columns: subgrid [line1] [line2] [line3] [line4]
Lines specified on the subgrid are added to any lines specified on the parent so you can use either or both. To demonstrate this, I have positioned one item in the example below using the
parent lines, and one using the subgrid lines.

.grid {

display: grid;

grid-template-columns: 1fr 1fr 1fr [col-start] 1fr 1fr 1fr [col-


end] 1fr 1fr 1fr;

grid-template-rows: repeat(4, minmax(100px, auto));

gap: 20px;

.item {

display: grid;

grid-column: 2 / 7;

grid-row: 2 / 4;

grid-template-columns: subgrid [sub-a] [sub-b] [sub-c] [sub-d]


[sub-e] [sub-f];

grid-template-rows: subgrid;

.subitem {

grid-column: col-start / col-end;

grid-row: 1 / 3;

<div class="grid">

<div class="item">

<div class="subitem"></div>

<div class="subitem2"></div>

</div>

</div>

Reset

Using subgrids
Other than needing to take care of items that do not fit in your subgrid, a subgrid acts very similarly to any nested grid; the only difference is that the track sizing of the subgrid is set on the
parent grid. As with any nested grid however, the size of content in the subgrid can change the track sizing, assuming a track sizing method is used that allows content to affect the size. In
such a case, auto-sized row tracks for example wil grow to fit content in the main grid and content in the subgrid.
As the subgrid value acts in much the same way as a regular nested grid, it is easy to switch between the two. For example, if you realize that you need an implicit grid for rows, all you would
need to do is remove the subgrid value of grid-template-rows and perhaps give a value for grid-auto-rows to control the implicit track sizing.

Specifications
Specification
CSS Grid Layout Module Level 3
# subgrids

Browser compatibility
Report problems with this compatibility data on GitHub
diordn A rof xoferiF
rerolpxE tenretnI

diordn A emorhC

diordn A arepO

SOi no irafaS
emorhC

xoferiF

arepO

irafaS
e gd E
Chrome No Edge No Firefox 71 Internet No Opera No Safari No Chrome No Firefox No Opera No Safari No
subgrid Explorer Android for Android on
Android iOS
Full support No support See implementation notes. User must explicitly enable this feature.

See also
On the Mozil a Developer YouTube Channel, see the videos Laying out forms using subgrid and Don't Wait To Use Subgrid For Better Card Layouts
Hello Subgrid! A presentation from CSSConf.eu

Last modified: Jun 1, 2022, by MDN contributors


MDN Plus now available in your country! Support MDN and make it your own. Learn more ✨

Realizing common layouts using CSS Grid Layout


To round off this set of guides to CSS Grid Layout, I am going to walk through a few different layouts, which demonstrate some
of the different techniques you can use when designing with grid layout. We wil look at an example using grid-template-areas, a
typical 12-column flexible grid system, and also a product listing using auto-placement. As you can see from this set of
examples, there is often more than one way to achieve the result you want with grid layout. Choose the method you find most
helpful for the problems that you are solving and the designs that you need to implement.

A responsive layout with 1 to 3 fluid columns using grid-template-areas


Many websites are a variation of this type of layout, with content, sidebars, a header and a footer. In a responsive design, you
may want to display the layout as a single column, adding a sidebar at a certain breakpoint and then bring in a three-column
layout for wider screens.
I am going to create this layout using the named template areas that we learned about in the guide Grid template areas.
My mark-up is a container with elements inside for a header, footer, main content, navigation, sidebar, and a block into which I
am intending to place advertising.
<div class="wrapper">

<header class="main-head">The header</header>

<nav class="main-nav">

<ul>

<li><a href="">Nav 1</a></li>

<li><a href="">Nav 2</a></li>

<li><a href="">Nav 3</a></li>

</ul>

</nav>

<article class="content">

<h1>Main article area</h1>

<p>In this layout, we display the areas in source order for any screen less that 500 pixels wide. We
go to a two column layout, and then to a three column layout by redefining the grid, and the placement of
items on the grid.</p>

</article>

<aside class="side">Sidebar</aside>

<div class="ad">Advertising</div>

<footer class="main-footer">The footer</footer>

</div>

As we are using grid-template-areas to create the layout. Outside of any media queries I need to name the areas. We name
areas using the grid-area property.
.main-head {

grid-area: header;

.content {

grid-area: content;

.main-nav {

grid-area: nav;

.side {

grid-area: sidebar;

.ad {

grid-area: ad;

.main-footer {

grid-area: footer;

This wil not create any layout, however our items now have names we can use to do so. Staying outside of any media queries I
am now going to set up the layout for the mobile width. Here I am keeping everything in source order, trying to avoid any
disconnect between the source and display as described in the guide Grid layout and accessibility. I have not defined any
column or row tracks but this layout dictates a single column, and rows wil be created as needed for each of the items in the
implicit grid.
.wrapper {

display: grid;

gap: 20px;

grid-template-areas:

"header"

"nav"

"content"

"sidebar"

"ad"

"footer";

With our mobile layout in place, we can now proceed to add a media query to adapt this layout for bigger screens with enough
real estate to display two columns.
@media (min-width: 500px) {

.wrapper {

grid-template-columns: 1fr 3fr;

grid-template-areas:

"header header"

"nav nav"

"sidebar content"

"ad footer";

nav ul {

display: flex;

justify-content: space-between;

You can see the layout taking shape in the value of grid-template-areas . The header spans over two column tracks, as
does the nav . In the third row track we have the sidebar alongside the content . In the fourth row track I have chosen to
place my ad content – so it appears under the sidebar, then the footer next to it under the content. I'm using a flexbox on
the navigation to display it in a row spaced out.
I can now add a final breakpoint to move to a three-column layout.
@media (min-width: 700px) {

.wrapper {

grid-template-columns: 1fr 4fr 1fr;

grid-template-areas:

"header header header"

"nav content sidebar"

"nav content ad"

"footer footer footer"

nav ul {

flex-direction: column;

The three-column layout has two 1fr unit side columns and a middle column that has 4fr as the track size. This means that
the available space in the container is split into 6 and assigned in proportion to our three tracks – one part each to the side
columns and 4 parts to the center.
In this layout I am displaying the nav in the left column, alongside the content . In the right column we have the sidebar and
underneath it the advertisements ( ad ). The footer now spans right across the bottom of the layout. I then use a flexbox to
display the navigation as a column.

The header

Nav 1 Nav 2 Nav 3

Sidebar
Main article area
In this layout, we display the areas in source
order for any screen less that 500 pixels wide. We
go to a two column layout, and then to a three
column layout by redefining the grid, and the
placement of items on the grid.

Advertising The footer

This is a simple example but demonstrates how we can use a grid layout to rearrange our layout for different breakpoints. In
particular I am changing the location of that ad block, as appropriate in my different column setups. I find this named areas
method very helpful at a prototyping stage, it is easy to play around with the location of elements. You could always begin to
use grid in this way for prototyping, even if you can't rely on it fully in production due to the browsers that visit your site.

A flexible 12-column layout


If you have been working with one of the many frameworks or grid systems you may be accustomed to laying out your site on
a 12- or 16-column flexible grid. We can create this type of system using CSS Grid Layout. As a simple example, I am creating a
12-column flexible grid that has 12 1fr -unit column tracks, they all have a start line named col-start . This means that we wil
have twelve grid lines named col-start .
.wrapper {

display: grid;

grid-template-columns: repeat(12, [col-start] 1fr);

gap: 20px;

To demonstrate how this grid system works I have four child elements inside my wrapper.
<div class="wrapper">

<div class="item1">Start column line 1, span 3 column tracks.</div>

<div class="item2">Start column line 6, span 4 column tracks. 2 row tracks.</div>

<div class="item3">Start row 2 column line 2, span 2 column tracks.</div>

<div class="item4">Start at column line 3, span to the end of the grid (-1).</div>

</div>

I can then place these on the grid using the named lines, and also the span keyword.
.item1 {

grid-column: col-start / span 3;

.item2 {

grid-column: col-start 6 / span 4 ;

grid-row: 1 / 3;

.item3 {

grid-column: col-start 2 / span 2;

grid-row: 2;

.item4 {

grid-column: col-start 3 / -1;

grid-row: 3;

Start column Start column line 6,


line 1, span 3 span 4 column
column tracks. 2 row
tracks. tracks.

Start
row 2
column
line 2,
span 2
column
tracks.

Start at column line 3, span to the end of the grid (-1).

As described in the guide to named lines, we are using the named line to place our item. As we have 12 lines all with the same
name we use the name, and then the index of the line. You could also use the line index itself if you prefer and avoid using
named lines at all.
Rather than setting the end line number, I have chosen to say how many tracks this element should span, using the span
keyword. I like this approach as when working with a multiple-column layout system we usually think of blocks in terms of the
number of tracks of the grid they span, and adjust that for different breakpoints. To see how the blocks align themselves to the
tracks, use the Firefox Grid Inspector . It clearly demonstrates how our items are placed.
There are some key differences with how a grid layout works over the grid systems you may have used previously. As you can
see, we do not need to add any markup to create a row, grid systems need to do this to stop elements popping up into the row
above. With CSS Grid Layout, we can place things into rows, with no danger of them rising up into the row above if it is left
empty. Due to this strict column and row placement we can also easily leave white space in our layout. We also don't need
special classes to pull or push things, to indent them into the grid. All we need to do is specify the start and end line for the
item.

Building a layout using the 12-column system


To see how this layout method works in practice, we can create the same layout that we created with grid-template-areas ,
this time using the 12-column grid system. I am starting with the same markup as used for the grid template areas example.
<div class="wrapper">

<header class="main-head">The header</header>

<nav class="main-nav">

<ul>

<li><a href="">Nav 1</a></li>

<li><a href="">Nav 2</a></li>

<li><a href="">Nav 3</a></li>

</ul>

</nav>

<article class="content">

<h1>Main article area</h1>

<p>In this layout, we display the areas in source order for any screen less that 500 pixels wide. We
go to a two column layout, and then to a three column layout by redefining the grid, and the placement of
items on the grid.</p>

</article>

<aside class="side">Sidebar</aside>

<div class="ad">Advertising</div>

<footer class="main-footer">The footer</footer>

</div>

I can then set up our grid, as for the example 12-column layout above.
.wrapper {

display: grid;

grid-template-columns: repeat(12, [col-start] 1fr);

gap: 20px;

We are once again going to make this a responsive layout, this time however using named lines. Every breakpoint wil use a 12-
column grid, however the number of tracks that items wil span changes depending on the size of the screen.
We start mobile first, and all we want for the narrowest screens is for the items to remain in source order, and all span right
across the grid.
.wrapper > * {

grid-column: col-start / span 12;

At the next breakpoint we want to move to a two-column layout. Our header and navigation stil span the full grid, so we do not
need to specify any positioning for them. The sidebar is starting on the first column line named col-start, spanning 3 lines. It
goes after row line 3, as the header and navigation are in the first two row tracks.
The ad panel is below the sidebar, so starts at grid row line 4. Then we have the content and footer starting at col-start 4 and
spanning 9 tracks taking them to the end of the grid.
@media (min-width: 500px) {

.side {

grid-column: col-start / span 3;

grid-row: 3;

.ad {

grid-column: col-start / span 3;

grid-row: 4;

.content, .main-footer {

grid-column: col-start 4 / span 9;

nav ul {

display: flex;

justify-content: space-between;

Finally we go to the three-column version of this layout. The header continues to span right across the grid, but now the
navigation moves down to become the first sidebar, with the content and then the sidebar next to it. The footer now also
spans across the full layout.
@media (min-width: 700px) {

.main-nav {

grid-column: col-start / span 2;

grid-row: 2 / 4;

.content {

grid-column: col-start 3 / span 8;

grid-row: 2 / 4;

.side {

grid-column: col-start 11 / span 2;

grid-row: 2;

.ad {

grid-column: col-start 11 / span 2;

grid-row: 3;

.main-footer {

grid-column: col-start / span 12;

nav ul {

flex-direction: column;

The header

Nav 1 Nav 2 Nav 3

Sidebar
Main article area
In this layout, we display the areas in source order
for any screen less that 500 pixels wide. We go to
a two column layout, and then to a three column
layout by redefining the grid, and the placement of
items on the grid.

Advertising The footer

Once again the Grid Inspector is useful to help us see how our layout has taken shape.
Something to note as we create this layout is that we haven't needed to explicitly position every element on the grid at each
breakpoint. We have been able to inherit the placement set up for earlier breakpoints – an advantage of working "mobile first".
We are also able to take advantage of grid auto-placement. By keeping elements in a logical order, auto-placement does quite a
lot of work for us in placing items onto the grid. In the final example in this guide we wil create a layout that entirely relies on
auto-placement.

A product listing with auto-placement


Many layouts are essential y sets of "cards" – product listings, image galleries, and so on. A grid can make it very easy to create
these listings in a way that is responsive without needing to add media queries to make it so. In this next example I'm combining
CSS Grid and Flexbox Layouts to make a simple product listing layout.
The markup for my listing is an unordered list of items. Each item contains a heading, some text of varying height, and a call to
action link.
<ul class="listing">

<li>

<h2>Item One</h2>

<div class="body">

<p>The content of this listing item goes here.</p>

</div>

<div class="cta">

<a href="">Call to action!</a>

</div>

</li>

<li>

<h2>Item Two</h2>

<div class="body">

<p>The content of this listing item goes here.</p>

</div>

<div class="cta">

<a href="">Call to action!</a>

</div>

</li>

<li class="wide">

<h2>Item Three</h2>

<div class="body">

<p>The content of this listing item goes here.</p>

<p>This one has more text than the other items.</p>

<p>Quite a lot more</p>

<p>Perhaps we could do something different with it?</p>

</div>

<div class="cta">

<a href="">Call to action!</a>

</div>

</li>

<li>

<h2>Item Four</h2>

<div class="body">

<p>The content of this listing item goes here.</p>

</div>

<div class="cta">

<a href="">Call to action!</a>

</div>

</li>

<li>

<h2>Item Five</h2>

<div class="body">

<p>The content of this listing item goes here.</p>

</div>

<div class="cta">

<a href="">Call to action!</a>

</div>

</li>

</ul>

We are going to create a grid with a flexible number of flexible columns. I want them never to become smaller than 200 pixels,
and then to share any available remaining space equally – so we always get equal width column tracks. We achieve this with the
minmax() function in our repeat notation for track sizing.

.listing {

list-style: none;

margin: 2em;

display: grid;

gap: 20px;

grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));

As soon as I add this CSS, the items start to lay out as a grid. If I make the window smaller or wider the number of column
tracks changes – without me needing to add breakpoints using media queries and redefine the grid.
I can then tidy up the internals of the boxes using a little touch of flexbox. I set the list item to display: flex and the flex-
direction to column . I can then use an auto margin on the .cta to push this bar down to the bottom of the box.

.listing li {

border: 1px solid #ffe066;

border-radius: 5px;

display: flex;

flex-direction: column;

.listing .cta {

margin-top: auto;

border-top: 1px solid #ffe066;

padding: 10px;

text-align: center;

.listing .body {

padding: 10px;

This is really one of the key reasons I would use flexbox rather than grid, if I am just aligning or distributing something in a single
dimension, that's a flexbox use case.

Item One Item Two

The content of this The content of this


listing item goes here. listing item goes here.

Call to action! Call to action!

Item Three Item Four

The content of this The content of this


The content of this The content of this
listing item goes here. listing item goes here.

This one has more text


than the other items.

Quite a lot more

Perhaps we could do
something different with
it?

Call to action! Call to action!

Item Five

The content of this


listing item goes here.

Preventing gaps with the dense keyword


This is all looking fairly complete now, however we sometimes have these cards which contain far more content than the
others. It might be nice to cause those to span two tracks, and then they won't be so tall. I have a class of wide on my larger
item, and I add a rule grid-column-end with a value of span 2 . Now when grid encounters this item, it wil assign it two
tracks. At some breakpoints, this means that we'l get a gap in the grid – where there isn't space to lay out a two-track item.
I can cause a grid to backfil those gaps by setting grid-auto-flow : dense on the grid container. Take care when doing this
however as it does take items away from their logical source order. You should only do this if your items do not have a set
order – and be aware of the issues of the tab order following the source and not your reordered display.
.listing {

list-style: none;

margin: 2em;

display: grid;

gap: 20px;

grid-auto-flow: dense;

grid-template-columns: repeat(auto-fill,minmax(200px, 1fr));

.listing .wide {

grid-column-end: span 2;

Item One Item Two

The content of this listing The content of this listing


item goes here. item goes here.

Call to action! Call to action!

Item Three

The content of this listing item goes here.

This one has more text than the other items.

Quite a lot more

Perhaps we could do something different with it?

Call to action!

Item Four Item Five

The content of this listing The content of this listing


item goes here. item goes here.
item goes here. item goes here.

Call to action! Call to action!

This technique of using auto-placement with some rules applied to certain items is very useful, and can help you to deal with
content that is being output by a CMS for example, where you have repeated items and can perhaps add a class to certain
ones as they are rendered into the HTML.

Further exploration
The best way to learn to use grid layout is to continue to build examples like the ones we have covered here. Pick something
that you normally build using your framework of choice, or using floats, and see if you can build it using grid. Don't forget to find
examples that are impossible to build with current methods. That might mean taking inspiration from magazines or other non-
web sources. Grid Layout opens up possibilities that we have not had before, we don't need to be tied to the same old layouts
to use it.
For inspiration see the Layout Labs from Jen Simmons , she has been creating layouts based on a range of sources.
For additional common layout patterns see Grid by Example from Rachel Andrew , where she provides many smaller
examples of grid layout and also some larger UI patterns and full page layouts.

Last modified: Apr 14, 2022, by MDN contributors


MDN Plus now available in your country! Support MDN and make it your own. Learn more ✨

Auto-placement in CSS Grid Layout


In addition to the ability to place items accurately onto a created grid, the CSS Grid Layout specification contains rules that
control what happens when you create a grid and do not place some or all of the child items. You can see auto-placement in
action in the simplest of ways by creating a grid on a set of items.

Default placement
If you give the items no placement information they wil position themselves on the grid, one in each grid cell.
.wrapper {

display: grid;

grid-template-columns: repeat(3, 1fr);

gap: 10px;

<div class="wrapper">

<div>One</div>

<div>Two</div>

<div>Three</div>

<div>Four</div>

<div>Five</div>

</div>

One Two Three

Four Five

Default rules for auto-placement


As you can see with the above example, if you create a grid all child items wil lay themselves out one into each grid cell. The
default flow is to arrange items by row. Grid wil lay an item out into each cell of row 1. If you have created additional rows using
the grid-template-rows property then grid wil continue placing items in these rows. If the grid does not have enough rows in
the explicit grid to place all of the items new implicit rows wil be created.
Sizing rows in the implicit grid
The default for automatically created rows in the implicit grid is for them to be auto-sized. This means that they wil contain the
content added to them without causing an overflow.
You can however control the size of these rows with the property grid-auto-rows . To cause all created rows to be 100 pixels
tall for example you would use:
<div class="wrapper">

<div>One</div>

<div>Two</div>

<div>Three</div>

<div>Four</div>

<div>Five</div>

</div>

.wrapper {

display: grid;

grid-template-columns: repeat(3, 1fr);

gap: 10px;

grid-auto-rows: 100px;

One Two Three

Four Five

Sizing rows using minmax()


You can use minmax() in your value for grid-auto-rows enabling the creation of rows that are a minimum size but then grow
to fit content if it is taller.
<div class="wrapper">

<div>One</div>

<div>Two</div>

<div>Three</div>

<div>Four

<br>This cell

<br>Has extra

<br>content.

<br>Max is auto

<br>so the row expands.

</div>

<div>Five</div>

</div>

.wrapper {

display: grid;

grid-template-columns: repeat(3, 1fr);

gap: 10px;

grid-auto-rows: minmax(100px, auto);

One Two Three

Four
Five
This cell

Has extra

content.

Max is auto

so the row expands.


Sizing rows using a track listing
You can also pass in a track listing, this wil repeat. The following track listing wil create an initial implicit row track as 100 pixels
and a second as 200px . This wil continue for as long as content is added to the implicit grid.
<div class="wrapper">

<div>One</div>

<div>Two</div>

<div>Three</div>

<div>Four</div>

<div>Five</div>

<div>Six</div>

<div>Seven</div>

<div>Eight</div>

</div>

.wrapper {

display: grid;

grid-template-columns: repeat(3, 1fr);

gap: 10px;

grid-auto-rows: 100px 200px;

One Two Three

Four Five Six

Seven Eight

Auto-placement by column
You can also ask grid to auto-place items by column. Using the property grid-auto-flow with a value of column . In this case
grid wil add items in rows that you have defined using grid-template-rows . When it fil s up a column it wil move onto the
next explicit column, or create a new column track in the implicit grid. As with implicit row tracks, these column tracks wil be
auto sized. You can control the size of implicit column tracks with grid-auto-columns , this works in the same way as grid-
auto-rows .
In this next example I have created a grid with three row tracks of 200 pixels height. I am auto-placing by column and the
columns created wil be a column width of 300 pixels, then a column width of 100 pixels until there are enough column tracks to
hold all of the items.
.wrapper {

display: grid;

grid-template-rows: repeat(3, 200px);

gap: 10px;

grid-auto-flow: column;

grid-auto-columns: 300px 100px;

<div class="wrapper">

<div>One</div>

<div>Two</div>

<div>Three</div>

<div>Four</div>

<div>Five</div>

<div>Six</div>

<div>Seven</div>

<div>Eight</div>

</div>

One Four Seven

Two Five Eight

Three Six
The order of auto placed items
A grid can contain a mixture of items. Some of the items may have a position on the grid, but others may be auto-placed. This
can be helpful, if you have a document order that reflects the order in which items sit on the grid you may not need to write
CSS rules to place absolutely everything. The specification contains a long section detailing the Grid item placement algorithm ,
however for most of us we just need to remember a few simple rules for our items.
Order modified document order
Grid places items that have not been given a grid position in what is described in the specification as "order modified document
order". This means that if you have used the order property at all, the items wil be placed by that order, not their DOM order.
Otherwise they wil stay by default in the order that they are entered in the document source.
Items with placement properties
The first thing grid wil do is place any items that have a position. In the example below I have 12 grid items. Item 2 and item 5
have been placed using line based placement on the grid. You can see how those items are placed and the other items then
auto-place in the spaces. The auto-placed items wil place themselves before the placed items in DOM order, they don't start
after the position of a placed item that comes before them.
<div class="wrapper">

<div>One</div>

<div>Two</div>

<div>Three</div>

<div>Four</div>

<div>Five</div>

<div>Six</div>

<div>Seven</div>

<div>Eight</div>

<div>Nine</div>

<div>Ten</div>

<div>Eleven</div>

<div>Twelve</div>

</div>

.wrapper {

display: grid;

grid-template-columns: repeat(4, 1fr);

grid-auto-rows: 100px;

gap: 10px;

.wrapper div:nth-child(2) {

grid-column: 3;

grid-row: 2 / 4;

.wrapper div:nth-child(5) {

grid-column: 1 / 3;

grid-row: 1 / 3;

Five One Three

Two Four

Six Seven Eight

Nine Ten Eleven Twelve

Deal with items that span tracks


You can use placement properties while stil taking advantage of auto-placement. In this next example I have added to the
layout by setting odd items to span two tracks both for rows and columns. I do this with the grid-column-end and grid-
row-end properties and setting the value of this to span 2 . What this means is that the start line of the item wil be set by
auto-placement, and the end line wil span two tracks.
You can see how this then leaves gaps in the grid, as for the auto-placed items if grid comes across an item that doesn't fit into
a track, it wil move to the next row until it finds a space the item can fit in.
<div class="wrapper">

<div>One</div>

<div>Two</div>

<div>Three</div>

<div>Four</div>

<div>Five</div>

<div>Six</div>

<div>Seven</div>

<div>Eight</div>

<div>Nine</div>

<div>Ten</div>

<div>Eleven</div>

<div>Twelve</div>

</div>

.wrapper {

display: grid;

grid-template-columns: repeat(4, 1fr);

grid-auto-rows: 100px;

gap: 10px;

.wrapper div:nth-child(4n+1) {

grid-column-end: span 2;

grid-row-end: span 2;

background-color: #ffa94d;

.wrapper div:nth-child(2) {

grid-column: 3;

grid-row: 2 / 4;

.wrapper div:nth-child(5) {

grid-column: 1 / 3;

grid-row: 1 / 3;

Five

Two

One Three

Four Six
Seven Eight Nine

Ten Eleven

Twelve

Filling in the gaps


So far, other than items we have specifically placed, grid is always progressing forward and keeping items in DOM order. This is
generally what you want, if you are laying out a form for example you wouldn't want the labels and fields to become jumbled up
in order to fil in some gap. However sometimes, we are laying things out that don't have a logical order and we would like to
create a layout that doesn't have gaps in it.
To do this, add the property grid-auto-flow with a value of dense to the container. This is the same property you use to
change the flow order to column , so if you were working in columns you would add both values grid-auto-flow: column
dense .
Having done this, grid wil now backfil the gaps, as it moves through the grid it leaves gaps as before, but then if it finds an item
that wil fit in a previous gap it wil pick it up and take it out of DOM order to place it in the gap. As with any other reordering in
grid this does not change the logical order. Tab order for example, wil stil follow the document order. We wil take a look at the
potential accessibility issues of Grid Layout in a later guide, but you should take care when creating this disconnect between the
visual order and display order.
<div class="wrapper">

<div>One</div>

<div>Two</div>

<div>Three</div>

<div>Four</div>

<div>Five</div>

<div>Six</div>

<div>Seven</div>

<div>Eight</div>

<div>Nine</div>

<div>Ten</div>

<div>Eleven</div>

<div>Twelve</div>

</div>

.wrapper div:nth-child(4n+1) {

grid-column-end: span 2;

grid-row-end: span 2;

background-color: #ffa94d;

.wrapper div:nth-child(2) {

grid-column: 3;

grid-row: 2 / 4;

.wrapper div:nth-child(5) {

grid-column: 1 / 3;

grid-row: 1 / 3;

.wrapper {

display: grid;

grid-template-columns: repeat(4, 1fr);

grid-auto-rows: 100px;

gap: 10px;

grid-auto-flow: dense;

Five Three Four

Two Six

One Seven

Eight Ten

Nine Eleven Twelve


Anonymous grid items
There is a mention in the specification of anonymous grid items. These are created if you have a string of text inside your grid
container, that is not wrapped in any other element. In the example below we have three grid items, assuming you had set the
parent with a class of grid to display: grid . The first is an anonymous item as it has no enclosing markup, this item wil
always be dealt with via the auto-placement rules. The other two are grid items enclosed in a div, they might be auto-placed or
you could place these with a positioning method onto your grid.
<div class="grid">

I am a string and will become an anonymous item

<div>A grid item</div>

<div>A grid item</div>

</div>

Anonymous items are always auto-placed because there is no way to target them. Therefore if you have some unwrapped text
for some reason in your grid, be aware that it might show up somewhere unexpected as it wil be auto-placed according to the
auto-placement rules.
Use cases for auto-placement
Auto-placement is useful whenever you have a collection of items. That could be items that do not have a logical order such as
a gallery of photos, or product listing. In that case you might choose to use the dense packing mode to fil in any holes in your
grid. In my image gallery example I have some landscape and some portrait images. I have set landscape images – with a class
of landscape to span two column tracks. I then use grid-auto-flow: dense to create a densely packed grid.
Try removing the line grid-auto-flow: dense to see the content reflow to leave gaps in the layout.
.wrapper {

display: grid;

grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));

gap: 10px;

grid-auto-flow: dense;

.wrapper li.landscape {

grid-column-end: span 2;

<ul class="wrapper">

<li><img src="./portrait.jpg" alt="placeholder"></li>

<li class="landscape"><img src="landscape.jpg" alt="placeholder"></li>

<li><img src="portrait.jpg" alt="placeholder"></li>

<li class="landscape"><img src="landscape.jpg" alt="placeholder"></li>

<li class="landscape"><img src="landscape.jpg" alt="placeholder"></li>

<li><img src="portrait.jpg" alt="placeholder"></li>

<li><img src="portrait.jpg" alt="placeholder"></li>

<li class="landscape"><img src="landscape.jpg" alt="placeholder"></li>

<li><img src="portrait.jpg" alt="placeholder"></li>

<li><img src="portrait.jpg" alt="placeholder"></li>

<li><img src="portrait.jpg" alt="placeholder"></li>

</ul>

Reset

Auto-placement can also help you lay out interface items which do have logical order. An example is the definition list in this
next example. Definition lists are an interesting challenge to style as they are flat, there is nothing wrapping the groups of dt
and dd items. In my example I am allowing auto-placement to place the items, however I have classes that start a dt in
column 1, and dd in column 2, this ensure that terms go on one side and definitions on the other - no matter how many of each
we have.
<div class="wrapper">

<dl>

<dt>Mammals</dt>

<dd>Cat</dd>

<dd>Dog</dd>

<dd>Mouse</dd>

<dt>Fish</dt>

<dd>Guppy</dd>

<dt>Birds</dt>

<dd>Pied Wagtail</dd>

<dd>Owl</dd>

</dl>

</div>

dl {

display: grid;

grid-template-columns: auto 1fr;

max-width: 300px;

margin: 1em;

line-height: 1.4;

dt {

grid-column: 1;

font-weight: bold;

dd {

grid-column: 2;

Mammals Cat
Dog
Mouse
Fish Guppy
Birds Pied Wagtail
Owl

What can't we do with auto-placement (yet)?


There are a couple of things that often come up as questions. Currently we can't do things like target every other cell of the grid
with our items. A related issue may have already come to mind if you followed the last guide about named lines on the grid. It
would be to define a rule that said "auto-place items against the next line named "n", and grid would then skip other lines. There
is an issue raised about this on the CSSWG GitHub repository, and you would be welcome to add your own use cases to this.
It may be that you come up with your own use cases for auto-placement or any other part of grid layout. If you do, raise them
as issues or add to an existing issue that could solve your use case. This wil help to make future versions of the specification
better.

Last modified: Mar 18, 2022, by MDN contributors


MDN Plus now available in your country! Support MDN and make it your own. Learn more ✨

Box alignment in CSS Grid Layout


CSS Grid Layout implements the specification Box Alignment Level 3 which is the same standard flexbox uses for aligning
items in its flex container. This specification details how alignment should work in all the different layout methods. Layout
methods wil conform to the specification where possible and implement individual behavior based on their differences (features
and constraints). While the specification currently specifies alignment details for all layout methods, browsers have not fully
implemented all of the specification; however, the CSS Grid Layout method has been widely adopted.
This guide presents demonstrations of how box alignment in grid layout works. You wil see many similarities in how these
properties and values work in flexbox. Due to grid being two-dimensional and flexbox one-dimensional there are some small
differences that you should watch out for. So we wil start by looking at the two axes that we deal with when aligning things in
a grid.

The two axes of a grid layout


When working with grid layout you have two axes available to align things against – the block axis and the inline axis. The
block axis is the axis upon which blocks are laid out in block layout. If you have two paragraphs on your page they display one
below the other, so it is this direction we describe as the block axis.
The inline axis runs across the block axis, it is the direction in which text in regular inline flow runs.
We are able to align the content inside grid areas, and the grid tracks themselves on these two axes.

Aligning items on the Block Axis


The align-self and align-items properties control alignment on the block axis. When we use these properties, we are
changing the alignment of the item within the grid area you have placed it.
Using align-items
In the following example, I have four grid areas within my grid. I can use the align-items property on the grid container, to
align the items using one of the following values:
auto

normal

start

end

center

stretch

baseline

first baseline

last baseline
.wrapper {

display: grid;

grid-template-columns: repeat(8, 1fr);

gap: 10px;

grid-auto-rows: 100px;

grid-template-areas:

"a a a a b b b b"

"a a a a b b b b"

"c c c c d d d d"

"c c c c d d d d";

align-items: start;

.item1 {

grid-area: a;

.item2 {

grid-area: b;

.item3 {

grid-area: c;

.item4 {

grid-area: d;

<div class="wrapper">

<div class="item1">Item 1</div>

<div class="item2">Item 2</div>

<div class="item3">Item 3</div>

<div class="item4">Item 4</div>

</div>

Item 1 Item 2

Item 3 Item 4
Keep in mind that once you set align-items: start , the height of each child <div> wil be determined by the contents of
the <div> . This is in contrast to omitting align-items completely, in which case the height of each <div> stretches to fil its
grid area.
The align-items property sets the align-self property for all of the child grid items. This means that you can set the
property individually, by using align-self on a grid item.
Using align-self
In this next example, I am using the align-self property, to demonstrate the different alignment values. The first area, is
showing the default behavior of align-self , which is to stretch. The second item, has an align-self value of start , the
third end and the fourth center .
.wrapper {

display: grid;

grid-template-columns: repeat(8, 1fr);

gap: 10px;

grid-auto-rows: 100px;

grid-template-areas:

"a a a a b b b b"

"a a a a b b b b"

"c c c c d d d d"

"c c c c d d d d";

.item1 {

grid-area: a;

.item2 {

grid-area: b;

align-self: start;

.item3 {

grid-area: c;

align-self: end;

.item4 {

grid-area: d;

align-self: center;

<div class="wrapper">

<div class="item1">Item 1</div>

<div class="item2">Item 2</div>

<div class="item3">Item 3</div>

<div class="item4">Item 4</div>

</div>

Item 1 Item 2

Item 4

Item 3

Items with an intrinsic aspect ratio


The specification details that the default behavior in align-self is to stretch, except for items which have an intrinsic aspect
ratio, in this case they behave as start . The reason for this, is that if items with an aspect ratio are set to stretch, this default
would distort them.
This behavior has now been clarified in the specification, with browsers yet to implement the correct behavior. Until that
happens, you can ensure that items do not stretch, such as images, which are direct children of the grid, by setting align-
self and justify-self to start. This wil mimic the correct behavior once implemented.

Justifying Items on the Inline Axis


As align-items and align-self deal with the alignment of items on the block axis, justify-items and justify-self do
the same job on the inline axis. The values you can choose from are the same as for align-self .
auto

normal

start

end

center

stretch

baseline

first baseline

last baseline

You can see the same example as used for align-items , below. This time we are applying the justify-self property.
Once again the default is stretch , other than for items with an intrinsic aspect ratio. This means that by default, grid items wil
cover their grid area, unless you change that by setting alignment. The first item in the example demonstrates this default
alignment:
.wrapper {

display: grid;

grid-template-columns: repeat(8, 1fr);

gap: 10px;

grid-auto-rows: 100px;

grid-template-areas:

"a a a a b b b b"

"a a a a b b b b"

"c c c c d d d d"

"c c c c d d d d";

.item1 {

grid-area: a;

.item2 {

grid-area: b;

justify-self: start;

.item3 {

grid-area: c;

justify-self: end;

.item4 {

grid-area: d;

justify-self: center;

<div class="wrapper">

<div class="item1">Item 1</div>

<div class="item2">Item 2</div>

<div class="item3">Item 3</div>

<div class="item4">Item 4</div>

</div>

Item 1 Item 2

Item 3 Item 4

As with align-self and align-items , you can apply justify-items to the grid container, to set the justify-self value
for all items.
The justify-self and justify-items properties are not implemented in flexbox. This is due to the one-dimensional nature
of flexbox, and that there may be multiple items along the axis, making it impossible to justify a single item. To align items along
the main, inline axis in flexbox you use the justify-content property.
Shorthand properties
The place-items property is shorthand for align-items and justify-items .
The place-self property is shorthand for align-self and justify-self .

Center an item in the area


By combining the align and justify properties we can easily center an item inside a grid area.
.wrapper {

display: grid;

grid-template-columns: repeat(4, 1fr);

gap: 10px;

grid-auto-rows: 200px;

grid-template-areas:

". a a ."

". a a .";

.item1 {

grid-area: a;

align-self: center;

justify-self: center;

<div class="wrapper">

<div class="item1">Item 1</div>

</div>

Item 1

Aligning the grid tracks on the block axis


If you have a situation where your grid tracks use an area that is smaller than the grid container, then you can align the grid
tracks themselves, inside that container. Once again, this operates on the block and inline axes, with align-content aligning
tracks on the block axis, and justify-content performing alignment on the inline axis. The place-content property is
shorthand for align-content and justify-content . The values for align-content , justify-content and place-
content are:

normal

start

end

center

stretch

space-around

space-between

space-evenly

baseline

first baseline

last baseline

In the below example I have a grid container of 500 pixels by 500 pixels. I have defined 3 row and column tracks each of 100
pixels with a 10 pixel gutter. This means that there is space inside the grid container both in the block and inline directions.
The align-content property is applied to the grid container as it works on the entire grid.
Default alignment
The default behavior in grid layout is start , which is why our grid tracks are in the top left corner of the grid, aligned against
the start grid lines:
* {box-sizing: border-box;}

.wrapper {

border: 2px solid #f76707;

border-radius: 5px;

background-color: #fff4e6;

.wrapper > div {

border: 2px solid #ffa94d;

border-radius: 5px;

background-color: #ffd8a8;

padding: 1em;

color: #d9480f;

.wrapper {

display: grid;

grid-template-columns: repeat(3, 100px);

grid-template-rows: repeat(3, 100px);

height: 500px;

width: 500px;

gap: 10px;

grid-template-areas:

"a a b"

"a a b"

"c d d";

.item1 {

grid-area: a;

.item2 {

grid-area: b;

.item3 {

grid-area: c;

.item4 {

grid-area: d;

<div class="wrapper">

<div class="item1">Item 1</div>

<div class="item2">Item 2</div>

<div class="item3">Item 3</div>

<div class="item4">Item 4</div>

</div>

Item 1 Item 2

Item 3 Item 4

Setting align-content: end


If I add align-content to my container, with a value of end , the tracks all move to the end line of the grid container in the
block dimension:
.wrapper {

display: grid;

grid-template-columns: repeat(3, 100px);

grid-template-rows: repeat(3, 100px);

height: 500px;

width: 500px;

gap: 10px;

grid-template-areas:

"a a b"

"a a b"

"c d d";

align-content: end;

.item1 {

grid-area: a;

.item2 {

grid-area: b;

.item3 {

grid-area: c;

.item4 {

grid-area: d;

<div class="wrapper">

<div class="item1">Item 1</div>

<div class="item2">Item 2</div>

<div class="item3">Item 3</div>

<div class="item4">Item 4</div>

</div>

Item 1 Item 2

Item 3 Item 4

Setting align-content: space-between


We can also use values for this property that you may be familiar with from flexbox; the space distribution values of space-
between , space-around and space-evenly . If we update align-content to space-between , you can see how the
elements on our grid space out:
.wrapper {

display: grid;

grid-template-columns: repeat(3, 100px);

grid-template-rows: repeat(3, 100px);

height: 500px;

width: 500px;

gap: 10px;

grid-template-areas:

"a a b"

"a a b"

"c d d";

align-content: space-between;

.item1 {

grid-area: a;

.item2 {

grid-area: b;

.item3 {

grid-area: c;

.item4 {

grid-area: d;

<div class="wrapper">

<div class="item1">Item 1</div>

<div class="item2">Item 2</div>

<div class="item3">Item 3</div>

<div class="item4">Item 4</div>

</div>

Item 1 Item 2

Item 3 Item 4

It is worth noting, that using these space distribution values may cause items on your grid to become larger. If an item spans
more than one grid track, as further space is added between the tracks, that item needs to become large to absorb the space.
We're always working in a strict grid. Therefore, if you decide to use these values, ensure that the content of your tracks can
cope with the extra space, or that you have used alignment properties on the items, to cause them to move to the start rather
than stretch.
In the below image I have placed the grid with align-content , with a value of start alongside the grid when align-
content has a value of space-between . You can see how items 1 and 2, which span two row tracks have taken on extra
height as they gain the additional space added to the gap between those two tracks:
Justifying the grid tracks on the inline axis
On the inline axis, we can use justify-content to perform the same type of alignment that we used align-content for in
the block axis.
Using the same example, I am setting justify-content to space-around . This once again causes tracks which span more
than one column track to gain extra space:
.wrapper {

display: grid;

grid-template-columns: repeat(3, 100px);

grid-template-rows: repeat(3, 100px);

height: 500px;

width: 500px;

gap: 10px;

grid-template-areas:

"a a b"

"a a b"

"c d d";

align-content: space-between;

justify-content: space-around;

.item1 {

grid-area: a;

.item2 {

grid-area: b;

.item3 {

grid-area: c;

.item4 {

grid-area: d;

<div class="wrapper">

<div class="item1">Item 1</div>

<div class="item2">Item 2</div>

<div class="item3">Item 3</div>

<div class="item4">Item 4</div>

</div>

Item 1 Item 2

Item 3 Item 4

Alignment and auto margins


Another way to align items inside their area is to use auto margins. If you have ever centered your layout in the viewport, by
setting the right and left margin of the container block to auto , you know that an auto margin absorbs all of the available
space. By setting the margin to auto on both sides, it pushes the block into the middle as both margins attempt to take all of
the space.
In this next example, I have given item 1 a left margin of auto . You can see how the content is now pushed over to the right
side of the area, as the auto margin takes up remaining space, after room for the content of that item has been assigned:
.wrapper {

display: grid;

grid-template-columns: repeat(3, 100px);

grid-template-rows: repeat(3, 100px);

height: 500px;

width: 500px;

gap: 10px;

grid-template-areas:

"a a b"

"a a b"

"c d d";

.item1 {

grid-area: a;

margin-left: auto;

.item2 {

grid-area: b;

.item3 {

grid-area: c;

.item4 {

grid-area: d;

<div class="wrapper">

<div class="item1">Item 1</div>

<div class="item2">Item 2</div>

<div class="item3">Item 3</div>

<div class="item4">Item 4</div>

</div>

Item 1 Item 2

Item 3 Item 4

You can see how the item is aligned by using the Firefox Grid Highlighter :
Alignment and Writing Modes
In all of these examples I have been working in English, which is a left-to-right language. This means that our start lines are top
and left of our grid when thinking in physical directions.
CSS Grid Layout, and the Box Alignment specification are designed to work with writing modes in CSS. This means that if you
are working in a right to left language, such as Arabic, the start of the grid would be the top and right, so the default of
justify-content: start would be for grid tracks to start on the right-hand side of the grid.

Setting auto margins, using margin-right or margin-left however, or absolutely positioning items using the top , right ,
bottom and left offsets would not honor writing modes. In the next guide, we wil look further into this interaction between
CSS grid layout, box alignment and writing modes. This wil be important to understand, if you develop sites that are then
displayed in multiple languages, or if you want to mix languages or writing modes in a design.

Last modified: Jun 3, 2022, by MDN contributors


MDN Plus now available in your country! Support MDN and make it your own. Learn more ✨

CSS grids, logical values, and writing modes


In these guides, I have already touched on an important feature of grid layout: the support for different writing modes that is
built into the specification. For this guide, we wil look at this feature of grid and other modern layout methods, learning a little
about writing modes and logical vs. physical properties as we do so.

Logical and physical properties and values


CSS is full of physical positioning keywords – left and right, top and bottom. If we position an item using absolute positioning,
we use these physical keywords as offset values to push the item around. In the code snippet below, the item is placed 20
pixels from the top, and 30 pixels from the left of the container:
.container {

position: relative;

.item {

position: absolute;

top: 20px;

left: 30px;

<div class="container">

<div class="item">Item</div>

</div>

Another place you might see physical keywords in use, is when using text-align: right to align text to the right. There are
also physical properties in CSS. We add margins, padding, and borders using these physical properties of margin-left ,
padding-left , and so on.

We call these keywords and properties physical because they relate to the screen you are looking at. Left is always left, no
matter what direction your text is running.
This can become an issue when developing a site that has to work in multiple languages, including languages that have text
starting on the right, rather than the left. Browsers are pretty good at dealing with text direction, and you don't even need to be
working in a rtl language to take a look. In the example below, I have two paragraphs. The first paragraph has text-align set
to left , the second has no text-align property set. I have added dir="rtl" to the html element, which switches the
writing mode from the default for an English language document of ltr . You can see that the first paragraph remains left to
right, due to the text-align value being left . The second however, switches direction and the text runs from right to left .
This is a very simple example of the problem with physical values and properties being used in CSS. They prevent the browser
being able to do the work to switch writing mode, as they make the assumption that the text is flowing left to right and top to
bottom.
Logical properties and values
Logical properties and values do not make an assumption about text direction. Which is why in Grid Layout we use the keyword
start when aligning something to the start of the container. For me, working in English, start may well be on the left,
however it doesn't have to be, and the word start infers no physical location.

Block and Inline


Once we begin dealing with logical, rather than physical properties, we stop seeing the world as left to right, and top to bottom.
We need a new reference point, and this is where understanding the block and inline axes, that we met previously in the guide
to alignment, becomes very useful. If you can start to see layout in terms of block and inline, the way things work in grid start
to make a lot more sense.

CSS writing modes


I'm going to introduce another specification here, that I wil be using in my examples: the CSS Writing Modes specification. This
spec details how we can use these different writing modes in CSS, not just for the support of languages that have a different
writing mode to English, but also for creative purposes. I'l be using the writing-mode property to make changes to the writing
mode applied to our grid, in order to demonstrate how the logical values work. If you want to dig into writing modes further,
however, then I would recommend that you read Jen Simmons excellent article on CSS Writing Modes . This goes into more
depth on that specification than we wil touch upon here.
writing-mode
Writing Modes are more than just left to right and right to left text, and the writing-mode property helps us display text
running in other directions. The writing-mode property can have values of:
horizontal-tb

vertical-rl

vertical-lr

sideways-rl

sideways-lr

The value horizontal-tb is the default for text on the web. It is the direction in which you are reading this guide. The other
properties wil change the way that text flows in our document, matching the different writing modes found around the world.
Again, for full details of these see Jen's article . As a simple example, I have two paragraphs below. The first uses the default
horizontal-tb , and the second uses vertical-rl . In the mode text stil runs left to right, however the direction of the text
is vertical - inline text now runs down the page, from top to bottom.
<div class="wrapper">

<p style="writing-mode: horizontal-tb">I have writing mode set to the default <code>horizontal-
tb</code></p>

<p style="writing-mode: vertical-rl">I have writing mode set to <code>vertical-rl</code></p>

</div>

I have writing mode set to the default


horizontal-tb
I have writing mode set to vertical-rl

Writing modes in grid layouts


If we now take a look at a grid layout example, we can see how changing the writing mode means changing our idea of where
the Block and Inline Axis are.
Default writing mode
The grid in this example has three columns and two row tracks. This means there are three tracks running down the block axis.
In default writing mode, grid auto-places items starting at the top left, moving along to the right, fil ing up the three cells on the
inline axis. It then moves onto the next line, creating a new Row track, and fil s in more items:
.wrapper {

display: grid;

grid-template-columns: repeat(3, 100px);

grid-template-rows: repeat(2, 100px);

gap: 10px;

<div class="wrapper">

<div class="item1">Item 1</div>

<div class="item2">Item 2</div>

<div class="item3">Item 3</div>

<div class="item4">Item 4</div>

<div class="item5">Item 5</div>

</div>

Item 1 Item 2 Item 3

Item 4 Item 5

Setting writing mode


If we add writing-mode: vertical-lr to the grid container, we can see that the block and inline Axis are now running in a
different direction. The block or column axis now runs across the page from left to right, Inline runs down the page, creating
rows from top to bottom.
.wrapper {

writing-mode: vertical-lr;

display: grid;

grid-template-columns: repeat(3, 100px);

grid-template-rows: repeat(2, 100px);

gap: 10px;

<div class="wrapper">

<div class="item1">Item 1</div>

<div class="item2">Item 2</div>

<div class="item3">Item 3</div>

<div class="item4">Item 4</div>

<div class="item5">Item 5</div>

</div>

Item 1

Item 4
Item 2

Item 5
Item 3
Logical values for alignment
With the block and inline axis able to change direction, the logical values for the alignment properties start to make more sense.
In this next example, I am using alignment to align items inside a grid that is set to writing-mode: vertical-lr . The start
and end properties work in exactly the same way that they do in the default writing mode, and remain logical in a way that
using left and right, top and bottom to align items would not do. This occurs once we've flipped the grid onto the side, like this:
.wrapper {

writing-mode: vertical-lr;

display: grid;

grid-template-columns: repeat(3, 1fr);

grid-template-rows: repeat(3, 100px);

gap: 10px;

.item1 {

grid-column: 1 / 4;

align-self: start;

.item2 {

grid-column: 1 / 3;

grid-row: 2 / 4;

align-self: start;

.item3 {

grid-column: 3;

grid-row: 2 / 4;

align-self: end;

justify-self: end;

<div class="wrapper">

<div class="item1">Item 1</div>

<div class="item2">Item 2</div>

<div class="item3">Item 3</div>

</div>

Item 1

Item 2

Item 3

If you want to see how these work, with a right to left as well as top to bottom writing mode, switch vertical-lr to
vertical-rl , which is a vertical writing mode running from right to left.

Auto-placement and Writing Modes


In the example already shown, you can see how writing mode changes the direction in which items place themselves onto the
grid. Items wil , by default, place themselves along the Inline axis then move onto a new row. However, that inline axis may not
always run from left to right.

Line-based placement and Writing Modes


The key thing to remember when placing items by line number, is that line 1 is the start line, no matter which writing mode you
are in. Line -1 is the end line, no matter which writing mode you are in.
Line-based placement with left to right text
In this next example, I have a grid which is in the default ltr direction. I have positioned three items using line-based
placement.
Item 1 starts at column line 1, spanning one track.
Item 2 starts at column line -1, spanning to -3.
Item 3 starts at column line 1, spanning to column line 3.
.wrapper {

display: grid;

grid-template-columns: repeat(3, 1fr);

grid-template-rows: repeat(2, 100px);

gap: 10px;

.item1 {

grid-column: 1 ;

.item2 {

grid-column: -1 / -3;

.item3 {

grid-column: 1 / 3;

grid-row: 2;

<div class="wrapper">

<div class="item1">Item 1</div>

<div class="item2">Item 2</div>

<div class="item3">Item 3</div>

</div>

Item 1 Item 2

Item 3

Line-based placement with right to left text


If I now add the direction property with a value of rtl to the grid container, line 1 becomes the right-hand side of the grid,
and line -1 on the left.
.wrapper {

direction: rtl;

display: grid;

grid-template-columns: repeat(3, 1fr);

grid-template-rows: repeat(2, 100px);

gap: 10px;

.item1 {

grid-column: 1 ;

.item2 {

grid-column: -1 / -3;

.item3 {

grid-column: 1 / 3;

grid-row: 2;

<div class="wrapper">

<div class="item1">Item 1</div>

<div class="item2">Item 2</div>

<div class="item3">Item 3</div>

</div>

Item 2 Item 1

Item 3

What this demonstrates, is that if you are switching the direction of your text, either for entire pages or for parts of pages, and
are using lines: you may want to name your lines, if you do not want the layout to completely switch direction. For some things,
for example, where a grid contains text content, this switching may be exactly what you want. For other usage it may not.
The strange order of values in the grid-area property
You can use the grid-area property to specify all four lines of a grid area as one value. When people first encounter this, they
are often surprised that the values do not follow the same order as the shorthand for margin – which runs clockwise: top, right,
bottom, left.
The order of grid-area values is:
grid-row-start

grid-column-start

grid-row-end

grid-column-end

Which for English, in left-to-right means the order is:


top

left

bottom

right

This is anti-clockwise! So the reverse of what we do for margins and padding. Once you realize that grid-area sees the world
as "block and inline", you can remember that we are setting the two starts, then the two ends. It becomes much more logical
once you know!

Mixed writing modes and grid layout


In addition to displaying documents, using the correct writing mode for the language, writing modes can be used creatively
within documents that are otherwise ltr . In this next example I have a grid layout with a set of links down one side. I've used
writing modes to turn these on their side in the column track:
.wrapper {

display: grid;

grid-gap: 20px;

grid-template-columns: 1fr auto;

font: 1em Helvetica, Arial, sans-serif;

.wrapper nav {

writing-mode: vertical-lr;

.wrapper ul {

list-style: none;

margin: 0;

padding: 1em;

display: flex;

justify-content: space-between;

.wrapper a {

text-decoration: none;

<div class="wrapper">

<div class="content">

<p>Turnip greens yarrow ricebean rutabaga endive cauliflower sea lettuce kohlrabi amaranth
water spinach avocado daikon napa cabbage asparagus winter purslane kale. Celery potato scallion desert
raisin horseradish spinach carrot soko. Lotus root water spinach fennel kombu maize bamboo shoot green
bean swiss chard seakale pumpkin onion chickpea gram corn pea. Brussels sprout coriander water chestnut
gourd swiss chard wakame kohlrabi beetroot carrot watercress. Corn amaranth salsify bunya nuts nori azuki
bean chickweed potato bell pepper artichoke.</p>

<p>Nori grape silver beet broccoli kombu beet greens fava bean potato quandong celery. Bunya
nuts black-eyed pea prairie turnip leek lentil turnip greens parsnip. Sea lettuce lettuce water chestnut
eggplant winter purslane fennel azuki bean earthnut pea sierra leone bologi leek soko chicory celtuce
parsley jícama salsify.</p>

</div>

<nav>

<ul>

<li><a href="">Link 1</a></li>

<li><a href="">Link 2</a></li>

<li><a href="">Link 3</a></li>

</ul>

</nav>

</div>

Turnip greens yarrow ricebean rutabaga endive cauliflower sea lettuce kohlrabi amaranth water spinach avocado daikon

Link 1 Link 2 Link 3


napa cabbage asparagus winter purslane kale. Celery potato scallion desert raisin horseradish spinach carrot soko. Lotus
root water spinach fennel kombu maize bamboo shoot green bean swiss chard seakale pumpkin onion chickpea gram corn
pea. Brussels sprout coriander water chestnut gourd swiss chard wakame kohlrabi beetroot carrot watercress. Corn
amaranth salsify bunya nuts nori azuki bean chickweed potato bell pepper artichoke.

Nori grape silver beet broccoli kombu beet greens fava bean potato quandong celery. Bunya nuts black-eyed pea prairie
turnip leek lentil turnip greens parsnip. Sea lettuce lettuce water chestnut eggplant winter purslane fennel azuki bean
earthnut pea sierra leone bologi leek soko chicory celtuce parsley jícama salsify.

Physical values and grid layout


We encounter physical properties frequently when building websites, and while the grid placement and alignment properties and
values respect writing modes, there are things you may want to do with Grid that force you to use physical properties and
values. In the guide to Box alignment and grids, I demonstrated how auto margins work in a grid area. Using an auto margin to
push one item away from the others is a common flexbox trick too, however this also ties the layout to the physical space.
If you use absolute positioning within a grid area, then you wil again be using physical offsets to push the item around inside the
grid area. The key thing is to be aware of, is the tension between physical and logical properties and values. For example, be
aware that you may need to make changes to your CSS to cope with a switch from ltr to rtl .
Logical properties for everything!
Our new layout methods give us the ability to use these logical values to place items, however, as soon as we start to combine
them with the physical properties used for margins and padding, we need to remember that those physical properties wil not
change according to writing mode.
The CSS Logical Properties specification means that you can use the logical equivalents for properties, such as margin-left
and margin-right , in your CSS. These properties and values have good support in modern browsers. Your understanding of
block and inline through grid wil help you to understand how to use these too.

Last modified: Jun 3, 2022, by MDN contributors


MDN Plus now available in your country! Support MDN and make it your own. Learn more ✨

CSS Grid Layout


CSS Grid Layout excels at dividing a page into major regions or defining the relationship in terms of size, position, and layer,
between parts of a control built from HTML primitives.
Like tables, grid layout enables an author to align elements into columns and rows. However, many more layouts are either
possible or easier with CSS grid than they were with tables. For example, a grid container's child elements could position
themselves so they actually overlap and layer, similar to CSS positioned elements.

Basic example
The example below shows a three-column track grid with new rows created at a minimum of 100 pixels and a maximum of auto.
Items have been placed onto the grid using line-based placement.
HTML
<div class="wrapper">

<div class="one">One</div>

<div class="two">Two</div>

<div class="three">Three</div>

<div class="four">Four</div>

<div class="five">Five</div>

<div class="six">Six</div>

</div>

CSS
.wrapper {

display: grid;

grid-template-columns: repeat(3, 1fr);

gap: 10px;

grid-auto-rows: minmax(100px, auto);

.one {

grid-column: 1 / 3;

grid-row: 1;

.two {

grid-column: 2 / 4;

grid-row: 1 / 3;

.three {

grid-column: 1;

grid-row: 2 / 5;

.four {

grid-column: 3;

grid-row: 3;

.five {

grid-column: 2;

grid-row: 4;

.six {

grid-column: 3;

grid-row: 4;

One Two

Three

Four

Five Six

Reference
CSS properties
display

grid-template-columns

grid-template-rows
grid-template-areas

grid-template

grid-auto-columns

grid-auto-rows

grid-auto-flow

grid

grid-row-start

grid-column-start

grid-row-end

grid-column-end

grid-row

grid-column

grid-area

row-gap

column-gap

gap

masonry-auto-flow

align-tracks

justify-tracks
CSS functions
repeat()

minmax()

fit-content()

CSS data types


<flex>

Glossary entries
Grid
Grid lines
Grid tracks
Grid cell
Grid area
Gutters
Grid axis
Grid row
Grid column

Guides
Basic concepts of Grid Layout
Relationship of Grid Layout to other layout methods
Layout using line-based placement
Grid template areas
Layout using named grid lines
Auto-placement in CSS Grid Layout
Box alignment in CSS Grid Layout
CSS Grid, Logical Values and Writing Modes
CSS Grid Layout and accessibility
Realizing common layouts using CSS Grid Layout
Subgrid
Masonry Layout

External resources
Grid by Example - A collection of usage examples and video tutorials
CSS Grid Reference - Codrops
CSS Grid Inspector - Firefox DevTools
CSS Grid Playground
CSS Grid Garden - A game for learning CSS grid

Specifications
Specification
CSS Grid Layout Module Level 3

Last modified: May 20, 2022, by MDN contributors

You might also like