Learn
04.2 | CSS GRID AND PAGE LAYOUTS
01 | CONTROL ROWS AND COLUMNS TOGETHER
Flexbox helps you arrange items along a main axis. But a project gallery may need consistent columns across several rows, or a page may need a header, main content, sidebar and footer.
CSS Grid is a two-dimensional layout system. It lets you define rows and columns, place items and control the gaps between them.
Grid and Flexbox work well together. You might use Grid for the page regions and Flexbox for navigation inside the header.
02 | CONTAINER, ITEMS AND TRACKS
<div class="project-grid">
<article>Delivery robot</article>
<article>Robot hand</article>
<article>Sensor station</article>
<article>Weather monitor</article>
</div>.project-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
}display: grid creates a grid container. Its direct child articles become grid items. A track is the space between adjacent grid lines, such as one column or row.
This example creates two columns. Items normally fill cells in source order, moving through a row before starting the next. More rows are created as needed.
gap sets gutters between tracks. Use container padding if you also need space around the outside.
03 | FRACTIONAL UNITS AND REPEAT
.project-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}fr represents a share of the available space allocated to flexible tracks. repeat(3, 1fr) is a compact way to write three 1fr columns.
.page-layout {
display: grid;
grid-template-columns: 2fr 1fr;
gap: 24px;
}When content minimums and other constraints do not interfere, 2fr and 1fr divide the flexible space in a two-to-one ratio after accounting for gaps and any non-flexible tracks. fr is not simply a percentage of the entire container.
Long unbreakable content can affect minimum sizes. For tracks that should be able to shrink, minmax(0, 1fr) removes the automatic minimum on that track.
04 | EXPLICIT AND IMPLICIT ROWS
.project-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
grid-template-rows: auto auto;
grid-auto-rows: auto;
gap: 16px;
}grid-template-columns and grid-template-rows define the explicit grid. If more tracks are needed for additional items, the browser creates an implicit grid.
grid-auto-rows controls the size of implicitly created rows. auto allows content to contribute to their size.
Fixed row heights can be useful for specific components, but avoid clipping text when content changes or is enlarged. Natural row sizing is often appropriate for learning content.
05 | PLACE ITEMS USING GRID LINES
.featured {
grid-column: 1 / 3;
}Two columns have three boundary lines. grid-column: 1 / 3 places the item from line 1 to line 3, spanning both columns.
.featured {
grid-column: span 2;
}span 2 requests a two-column span without naming the starting line. Ensure the intended grid has room for that span; inappropriate placement can create unwanted implicit tracks.
.page-header {
grid-column: 1 / -1;
}The negative line number -1 refers to the end of the explicit grid on that axis. This is useful for spanning all explicitly defined columns.
06 | NAME THE PAGE REGIONS
<div class="page-layout">
<header class="page-header">Club header and navigation</header>
<main class="page-main">Main learning content</main>
<aside class="page-sidebar">Related resources</aside>
<footer class="page-footer">Contact information</footer>
</div>.page-layout {
display: grid;
grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
grid-template-areas:
"header header"
"main sidebar"
"footer footer";
gap: 24px;
}
.page-header { grid-area: header; }
.page-main { grid-area: main; }
.page-sidebar { grid-area: sidebar; }
.page-footer { grid-area: footer; }Each quoted string describes a row of named cells. Repeating a name lets an area span cells. Every row must have the same number of cells, and each named area must form a rectangle.
A dot represents an unnamed cell. The area names are CSS labels; they do not create HTML landmarks. Keep header, main, aside and footer meaningful in the markup.
This two-column example will need a narrower-screen arrangement. The next lesson teaches media queries to switch the page regions into one column.
07 | BUILD A FLEXIBLE CARD GRID
.project-grid {
display: grid;
grid-template-columns:
repeat(auto-fit, minmax(min(100%, 220px), 1fr));
gap: 16px;
}
.project-card {
min-width: 0;
overflow-wrap: anywhere;
}
.project-card img {
display: block;
max-width: 100%;
height: auto;
}auto-fit creates as many suitable columns as fit and collapses empty tracks, allowing occupied columns to expand. minmax sets a minimum and maximum track size. The inner min prevents the minimum from exceeding the container’s width when it is narrower than 220px.
The simpler minmax(220px, 1fr) pattern is useful too, but its fixed minimum can overflow a container narrower than 220px.
Grid keeps shared column tracks across rows, unlike independently sized wrapped Flexbox lines. Still test long text, images and actual content: layout rules are not a guarantee against every overflow.
08 | ALIGN ITEMS AND TRACKS
justify-items aligns items within their grid areas on the inline axis. align-items aligns them on the block axis. In typical English horizontal writing, those are horizontal and vertical respectively.
.project-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
justify-items: stretch;
align-items: start;
}justify-self and align-self can change the alignment of one item. A grid item’s definite size or other constraints can affect stretching.
justify-content and align-content align the grid tracks as a group when spare space is available. They are different from aligning an item inside its own area. Flexible columns that consume the available width can leave no spare horizontal space to distribute.
09 | TRY IT: CHANGE THE GRID
Choose a column pattern and gap, then optionally let the first card span the entire explicit grid. The numbers preserve the source order.
10 | PRESERVE LOGICAL CONTENT ORDER
Grid placement can change where content appears without changing its source order. Reading and sequential keyboard navigation generally still follow that source order.
Write a logical sequence in HTML first. Do not place content visually in a confusing order or use dense packing without considering its effect on the reading experience.
- Identify the container and direct child items.
- Check explicit tracks and any unexpected implicit tracks.
- Check item spans and named-area rectangles.
- Test narrow screens, enlarged text and long content.
- Check that keyboard focus moves through the page sensibly.