46
loading...
This website collects cookies to deliver better user experience
The Grid layout is compatible with the vast majority of browsers, some like Opera Mini and IE do not support it, in Can I use you can see what properties are supported by which browsers.
<div class="parent grid">
<p class="child grid-item"></p>
<p class="child grid-item"></p>
<span class="child grid-item"></span>
</div>
The parent will be in charge of defining the grid and the children will be in charge of positioning or aligning themselves in specific places, if necessary.
display: grid;
grid-template: none|grid-template-rows / grid-template-columns|grid-template-areas grid-template-rows / grid-template-columns
grid-template-rows: none|[line-name] track-size [line-name-2];
grid-template-columns: none|[line-name] track-size [line-name-2];
A grid track is the space between any two lines on the grid. As we can see in the image below, between linename and linename2 we have defined a column track of 1fr in size.
The fr unit represents a fraction of the available space in the grid container.
By grid items content: min-content, minimum size of the content, max-content, maximum size of the content and auto, similar to minmax(min-content, max-content).
By functions:
/* Common units */
grid-template-columns: [linename] 1fr [linename2] 2fr [linename3] 1fr [linename4];
grid-template-rows: [linename] 1fr [linename2] 1fr [linename3] auto [linename4];
/* Grid items content */
grid-template-columns: 1fr max-content 2fr;
grid-template-rows: 1fr min-content max-content;
/* Functions (& combined) */
grid-template-columns: repeat(3, minmax(0, 1fr));
grid-template-rows: minmax(60px, 1fr) fit-content(75%);
grid-template-areas - specifies named grid areas by setting the grid cells and assigning names to them.
No grid item is associated to these areas, but any child element can reference any area with the grid placement properties (grid-row/grid-column, grid-area), which we will see below.
grid-template-areas: none|.|area-strings;
grid-template-columns: 300px repeat(3, 1fr);
grid-template-rows: minmax(60px, 1fr) 4fr minmax(60px, 1fr);
grid-template-areas: "sidebar header header header"
"sidebar content content content"
"sidebar footer footer footer";
By definition, if we haven't explicitly defined in grid-template-columns the size of a column track where a grid item has been positioned, implicit grid tracks are created to contain it.
grid-auto-columns: implicit-tracks-size;
grid-template-columns: 300px;
grid-auto-columns: 1fr;
grid-auto-rows: implicit-tracks-size;
grid-auto-rows: 6rem;
grid-auto-flow: row|column|dense|[row|column] dense;
WARNING - grid-auto-flow: dense; can cause items to appear visually out of order, causing accessibility problems.
gap: row-col-gap|row-gap column-gap;
(row-col-gap) As in padding, if we specify a single value it will be set for both row and column.
row-gap: 20px;
column-gap: 5%;
grid-row: grid-line|grid-row-start / grid-row-end;
grid-row-start: [number|name]|span [number|name]|auto;
grid-row-start: span 2; /* The item occupies 2 rows */
grid-row-end: number|name|span [number|name]|auto;
grid-row: span 2 / 5; /* Fit 2 rows and end in the numbered line 5 */
grid-column: grid-line|grid-column-start / grid-column-end;
grid-column-start: [number|name]|span [number|name]|auto;
grid-column-end: [number|name]|span [number|name]|auto;
grid-area: named-area|grid-row-start / grid-row-end / grid-column-start / grid-column-end;
/* Given grid-template-areas: "content content sidebar"; */
grid-area: content;
/* Specifying line numbers:
grid-row-start: 1
grid-column-start: 1
grid-row-end: auto
grid-column-end: 3
*/
grid-area: 1 / 1 / auto / 3; /* OR grid-area: 1 / span 2; */
A grid cell is the smallest unit on a grid. Once a grid is defined as a parent, the child items will lay themselves out in one cell each of the defined grid.
place-items: align-items justify-items;
align-items: normal|center|start|end|stretch;
justify-items: normal|center|start|end|stretch;
place-content: align-content justify-content;
align-content: normal|center|start|end|space-around|space-between|space-evenly|stretch;
justify-content: normal|center|start|end|space-around|space-between|space-evenly|stretch;
place-self: align-self justify-self;
align-self: center|start|end|stretch;
justify-self: center|start|end|stretch;
BONUS - Masonry Layout is an experimental feature, a layout method where 1 axis uses common values (usually columns), and the other the masonry value. In the axis of the masonry (usually the row), instead of leaving gaps after the small elements, the elements of the next row move up to fill the gaps. (AWESOME, isn't it?)
<div class="grid grid-cols-[300px,minmax(0,1fr)] grid-rows-[60px,1fr] min-h-screen">
<aside id="sidebar" class="sticky top-0 h-screen">Sidebar</aside>
<header class="row-span-1 col-start-2">Header</header>
<section role="main" class="col-start-2">Content</section>
<footer class="col-start-2">Footer</footer>
</div>
.grid {
display: grid;
}
.grid-cols-[300px,minmax(0,1fr)] {
/* 2 column tracks, 1st 300px, 2nd max the space available */
grid-template-columns: 300px minmax(0, 1fr);
}
.grid-rows-[60px,1fr] {
/* 2 row tracks, 1st 60px, 2nd the space available */
grid-template-rows: 60px 1fr;
}
.min-h-screen {
min-height: 100vh; /* Fill the full screen */
}
Why is it important to define minmax(0, 1fr) instead of 1fr? Because by defining minmax and adding the possibility to have a smaller size than 1fr, the content does not overflow. This way, elements like a slider can be added to that responsive column without any problem.
/**
* Aside - Sidebar
*/
.sticky {
position: sticky; /* Follow you when scrolling */
}
.top-0 {
top: 0px;
}
.h-screen {
height: 100vh; /* Fill the screen vertically */
}
/**
* Header
*/
.row-span-1 {
grid-row: span 1 / span 1; /* Position: first row track */
}
.col-start-2 {
grid-column-start: 2; /* Position: second column track */
}
/**
* Content & Footer
*/
.col-start-2 {
grid-column-start: 2; /* Position: second column track (original position for the row) */
}
Note: The examples will be styled with TailwindCSS using JIT mode, but I'm still going to add the generated CSS for those who don't use it.
<article class="grid grid-cols-[120px,minmax(0,1fr),64px] grid-rows-1 gap-4">
<!-- Figure: By default will be added in the first column of 120px -->
<figure>
<img src="image_url" alt="image_alt" width="120" height="120" />
</figure>
<!-- Header (Title, excerpt and date): By default will be added in the second (available space) column -->
<header class="py-4">
<h2>Heading</h2>
<p class="pb-8">Description or excerpt</p>
<p>Date</p>
</header>
<!-- Like button: By default will be added in the last column of 64px -->
<button class="w-8 h-8 p-4">
<svg width="32" height="32">Like Icon</svg>
</button>
</article>
.grid {
display: grid;
}
.grid-cols-[120px,minmax(0,1fr),64px] {
/* 3 column tracks, 1st fixed of 120px, 2nd responsive from 0 to 1fr, and 3rd fixed of 64px */
grid-template-columns: 120px minmax(0, 1fr) 64px;
}
.grid-rows-1 {
/* 1 row track responsive from 0 to 1fr */
grid-template-rows: repeat(1, minmax(0, 1fr));
}
.gap-4 {
gap: 1rem; /* gap between row and column tracks of 1rem (16px) */
}
/**
* Header: Internal padding
*/
.py-4 {
padding-top: 1rem;
padding-bottom: 1rem;
}
/**
* Button: Size and internal padding
*/
.w-8 {
width: 2rem; /* (32px) */
}
.h-8 {
height: 2rem; /* (32px) */
}
.p-4 {
padding: 1rem;
}
<div class="grid grid-cols-[repeat(auto-fit, 150px)] gap-8">
<article>Item 1</article>
<article>Item 2</article>
<article>Item 3</article>
<article>Item 4</article>
<article>Item 5</article>
</div>
.grid {
display: grid;
}
.grid-cols-[repeat(auto-fit, 150px)] {
grid-template-columns: repeat(auto-fit, 150px);
}
.gap-8 {
gap: 2rem; /* (32px) */
}