CSS Grid Collate 290622
CSS Grid Collate 290622
CSS Grid Collate 290622
Learn more ✨
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
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
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.
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!
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 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;
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;
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.
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.
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;
article
div button
div button
button
button
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;
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.
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
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>
.wrapper {
width: 500px;
display: flex;
flex-wrap: wrap;
flex: 1 1 150px;
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;
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
<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
<div>One</div>
<div>Two</div>
<div>Three</div>
</div>
.wrapper {
display: grid;
<div>One</div>
<div>Two</div>
<div>Three</div>
</div>
.wrapper {
display: grid;
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.
<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;
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);
color: #000;
padding: 10px;
Four
"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="nested">a</div>
<div class="nested">b</div>
<div class="nested">c</div>
</div>
</div>
.wrapper {
display: grid;
.box1 {
grid-column-start: 1;
grid-column-end: 4;
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="nested">a</div>
<div class="nested">b</div>
<div class="nested">c</div>
</div>
</div>
.wrapper {
display: grid;
.box1 {
grid-column-start: 1;
grid-column-end: 4;
display: contents;
a b c
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
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>
.wrapper {
width: 500px;
display: flex;
flex-wrap: wrap;
flex: 1 1 150px;
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;
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
<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
<div>One</div>
<div>Two</div>
<div>Three</div>
</div>
.wrapper {
display: grid;
<div>One</div>
<div>Two</div>
<div>Three</div>
</div>
.wrapper {
display: grid;
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.
<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;
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);
color: #000;
padding: 10px;
Four
"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="nested">a</div>
<div class="nested">b</div>
<div class="nested">c</div>
</div>
</div>
.wrapper {
display: grid;
.box1 {
grid-column-start: 1;
grid-column-end: 4;
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="nested">a</div>
<div class="nested">b</div>
<div class="nested">c</div>
</div>
</div>
.wrapper {
display: grid;
.box1 {
grid-column-start: 1;
grid-column-end: 4;
display: contents;
a b c
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
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.
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>
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;
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;
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;
Four Five
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>
.wrapper {
display: grid;
Four Five
display: grid;
display: grid;
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;
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;
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>
.wrapper {
display: grid;
grid-auto-rows: 200px;
Four Five
display: grid;
<div class="wrapper">
<div>One</div>
<div>Two
</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>
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-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
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-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;
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>
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;
* {box-sizing: border-box;}
.wrapper {
border-radius: 5px;
background-color: #fff4e6;
display: grid;
.box {
border-radius: 5px;
background-color: #ffd8a8;
padding: 1em;
color: #d9480f;
.box1 {
grid-column: 1 / 4;
.nested {
border-radius: 5px;
background-color: #fff9db;
padding: 1em;
a b c
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;
</div>
.wrapper {
display: grid;
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-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.
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.
display: grid;
.item {
display: grid;
grid-column: 2 / 7;
grid-row: 2 / 4;
grid-template-columns: subgrid;
.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.
.grid {
display: grid;
.item {
display: grid;
grid-column: 2 / 7;
grid-row: 2 / 4;
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
.grid {
display: grid;
.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
1
2
3
4
5
6
7
7
8
9
10
11
12
.grid {
display: grid;
.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;
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;
gap: 20px;
.item {
display: grid;
grid-column: 2 / 7;
grid-row: 2 / 4;
grid-template-columns: subgrid;
grid-template-rows: subgrid;
.subitem {
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;
gap: 20px;
.item {
display: grid;
grid-column: 2 / 7;
grid-row: 2 / 4;
grid-template-rows: subgrid;
.subitem {
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
<nav class="main-nav">
<ul>
</ul>
</nav>
<article class="content">
<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>
</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-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-areas:
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
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.
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.
display: grid;
gap: 20px;
To demonstrate how this grid system works I have four child elements inside my wrapper.
<div class="wrapper">
<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 {
.item2 {
grid-row: 1 / 3;
.item3 {
grid-row: 2;
.item4 {
grid-row: 3;
Start
row 2
column
line 2,
span 2
column
tracks.
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.
<nav class="main-nav">
<ul>
</ul>
</nav>
<article class="content">
<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>
</div>
I can then set up our grid, as for the example 12-column layout above.
.wrapper {
display: grid;
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 > * {
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-row: 3;
.ad {
grid-row: 4;
.content, .main-footer {
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-row: 2 / 4;
.content {
grid-row: 2 / 4;
.side {
grid-row: 2;
.ad {
grid-row: 3;
.main-footer {
nav ul {
flex-direction: column;
The header
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.
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.
<li>
<h2>Item One</h2>
<div class="body">
</div>
<div class="cta">
</div>
</li>
<li>
<h2>Item Two</h2>
<div class="body">
</div>
<div class="cta">
</div>
</li>
<li class="wide">
<h2>Item Three</h2>
<div class="body">
</div>
<div class="cta">
</div>
</li>
<li>
<h2>Item Four</h2>
<div class="body">
</div>
<div class="cta">
</div>
</li>
<li>
<h2>Item Five</h2>
<div class="body">
</div>
<div class="cta">
</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;
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-radius: 5px;
display: flex;
flex-direction: column;
.listing .cta {
margin-top: auto;
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.
Perhaps we could do
something different with
it?
Item Five
list-style: none;
margin: 2em;
display: grid;
gap: 20px;
grid-auto-flow: dense;
.listing .wide {
grid-column-end: span 2;
Item Three
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.
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;
gap: 10px;
<div class="wrapper">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>
Four Five
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>
.wrapper {
display: grid;
gap: 10px;
grid-auto-rows: 100px;
Four Five
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four
<br>This cell
<br>Has extra
<br>content.
<br>Max is auto
</div>
<div>Five</div>
</div>
.wrapper {
display: grid;
gap: 10px;
Four
Five
This cell
Has extra
content.
Max is auto
<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;
gap: 10px;
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;
gap: 10px;
grid-auto-flow: column;
<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>
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-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;
Two Four
<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-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
<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-auto-rows: 100px;
gap: 10px;
grid-auto-flow: dense;
Two Six
One Seven
Eight Ten
</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;
gap: 10px;
grid-auto-flow: dense;
.wrapper li.landscape {
grid-column-end: span 2;
<ul class="wrapper">
</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;
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
normal
start
end
center
stretch
baseline
first baseline
last baseline
.wrapper {
display: grid;
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>
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;
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>
Item 1 Item 2
Item 4
Item 3
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;
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>
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 .
display: grid;
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>
Item 1
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-radius: 5px;
background-color: #fff4e6;
border-radius: 5px;
background-color: #ffd8a8;
padding: 1em;
color: #d9480f;
.wrapper {
display: grid;
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>
Item 1 Item 2
Item 3 Item 4
display: grid;
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>
Item 1 Item 2
Item 3 Item 4
display: grid;
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>
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;
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>
Item 1 Item 2
Item 3 Item 4
display: grid;
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>
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.
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.
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>
</div>
display: grid;
gap: 10px;
<div class="wrapper">
</div>
Item 4 Item 5
writing-mode: vertical-lr;
display: grid;
gap: 10px;
<div class="wrapper">
</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;
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>
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.
display: grid;
gap: 10px;
.item1 {
grid-column: 1 ;
.item2 {
grid-column: -1 / -3;
.item3 {
grid-column: 1 / 3;
grid-row: 2;
<div class="wrapper">
</div>
Item 1 Item 2
Item 3
direction: rtl;
display: grid;
gap: 10px;
.item1 {
grid-column: 1 ;
.item2 {
grid-column: -1 / -3;
.item3 {
grid-column: 1 / 3;
grid-row: 2;
<div class="wrapper">
</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
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!
display: grid;
grid-gap: 20px;
.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>
</ul>
</nav>
</div>
Turnip greens yarrow ricebean rutabaga endive cauliflower sea lettuce kohlrabi amaranth water spinach avocado daikon
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.
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;
gap: 10px;
.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()
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