Mastering CSS Grid: Grid Areas, Item Alignment, and Spanning

Stylized 2D illustration visualizing advanced CSS Grid techniques like alignment, named grid areas, and spanning elements across rows and columns.
Stylized 2D illustration visualizing advanced CSS Grid techniques like alignment, named grid areas, and spanning elements across rows and columns.

Introduction#

Welcome to Part 2 of the CSS Grid Fundamentals Series!

In Part 1, you laid the groundwork — learning how to define grid containers, set up tracks, and build basic layouts.

Now, it’s time to go beyond the basics.

Think of CSS Grid as your layout canvas — and in this part, you’ll pick up new tools like a ruler, compass, and highlighter to draw structure, alignment, and flow with precision.

We’ll cover:

  • grid-template-areas for clean, visual layout structure
  • Alignment techniques using place-items and place-self
  • Spanning elements across rows and columns
  • The hidden mechanics of explicit and implicit grids

These are the techniques that elevate your layouts from functional to flexible and scalable — especially in real-world, component-based frontend projects.

Grid Template Areas#

The grid-template-areas property allows you to define your layout using named areas, making the grid structure more readable and easier to maintain—especially for complex page layouts. It acts as a visual blueprint of your design and simplifies the placement of grid items.

Code language: CSS
1
2
3
4
5
6
7
8
9
10
11
.grid {
  display: grid;
  grid-template-areas:
    "header header header"
    "sidebar main main"
    "footer footer footer";
  grid-template-columns: 1fr 2fr 2fr;
  grid-template-rows: auto 1fr auto;
  padding: 1rem;
  gap: 1rem;
}

Each quoted line defines a row in the grid. The repeated area names indicate how many columns that area spans. You can then assign elements to these areas using the grid-area property:

Code language: CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.header {
  grid-area: header;
  background: #f8b400;
  padding: 1rem;
}

.main {
  grid-area: main;
  background: #4caf50;
  padding: 1rem;
}

.sidebar {
  grid-area: sidebar;
  background: #2196f3;
  padding: 1rem;
}

.footer {
  grid-area: footer;
  background: #9c27b0;
  padding: 1rem;
}

Here’s the HTML structure:

Code language: HTML
1
2
3
4
5
6
<div class="grid">
  <header class="header">Header</header>
  <aside class="sidebar">Sidebar</aside>
  <main class="main">Main Content</main>
  <footer class="footer">Footer</footer>
</div>

Explanation:

  • The layout is visually defined using grid-template-areas, making it easier to understand and modify.
  • The grid has 3 columns and 3 rows.
  • Named areas like "header", "sidebar", "main", and "footer" are assigned using grid-area, allowing semantic HTML elements to be positioned without relying on source order.
  • The column layout uses 1fr 2fr 2fr, giving the sidebar less space than the main content.
  • This is a clean, semantic approach to building responsive page sections—no floats or nested containers needed.

👉 Try this on CodePen

Aligning Grid Items#

CSS Grid not only lets you organize content into rows and columns—it also gives you precise control over how items are aligned within their grid cells.

Alignment can be applied at two levels:

Container-Level Alignment#

These properties are applied to the grid container and affect all items inside the grid:

  • justify-items — Aligns items horizontally (inline axis) within each cell.
  • align-items — Aligns items vertically (block axis) within each cell.
  • place-items — A shorthand for combining both align-items and justify-items.
Code language: CSS
1
2
3
4
5
.grid {
  display: grid;
  justify-items: center; /* Horizontally center all grid items within their cells */
  align-items: center;   /* Vertically center all grid items within their cells */
}

Visual Reference (Centered Items)

+-------------+-------------+-------------+
|             |             |             |
|     [ ]     |     [ ]     |     [ ]     |  ← centered in both directions
|             |             |             |
+-------------+-------------+-------------+
|             |             |             |
|     [ ]     |     [ ]     |     [ ]     |
|             |             |             |
+-------------+-------------+-------------+

You can also use place-items as a shorthand:

Code language: CSS
1
2
3
4
.grid {
  display: grid;
  place-items: end start; /* Aligns all grid items to the bottom (block-end) and left (inline-start) */
}

Visual Reference (Bottom-Left Aligned)

+-------------+-------------+-------------+
|             |             |             |
|             |             |             |
| [ ]         | [ ]         | [ ]         |  ← bottom-left alignment
+-------------+-------------+-------------+
|             |             |             |
|             |             |             |
| [ ]         | [ ]         | [ ]         |
+-------------+-------------+-------------+

Item-Level Alignment#

While container-level alignment applies to all grid items, item-level alignment lets you override alignment per individual item. These properties are set directly on the grid items themselves:

  • justify-self — Aligns an item horizontally (inline axis) within its grid cell.
  • align-self — Aligns an item vertically (block axis) within its grid cell.
  • place-self — A shorthand for combining align-self and justify-self.
Code language: CSS
1
2
3
4
.item {
  justify-self: end; /* Aligns this item to the right (inline-end) of its cell */
  align-self: start; /* Aligns this item to the top (block-start) of its cell */
}

Visual Reference (Top-Right Alignment)

+-------------+
|         [ ] |  ← aligned to top-right
|             |
|             |
+-------------+

You can also achieve the same alignment with place-self:

Code language: CSS
1
2
3
.item {
  place-self: end start; /* Aligns this item to the bottom (block-end) and left (inline-start) */
}

Visual Reference (Bottom-Left Alignment)

+-------------+
|             |
|             |
| [ ]         |  ← aligned to bottom-left
+-------------+

👉 Try these alignments on CodePen

Spanning Grid Items#

CSS Grid allows items to span across multiple columns or rows using grid-column and grid-row. These properties let you define where an item starts and ends in the grid layout.

Imagine a 3×3 grid:

Code language: HTML
1
2
3
4
5
6
<div class="grid">
  <div class="item">Spanning</div>
  <div>Item 2</div>
  <div>Item 3</div>
  <div>Item 4</div>
</div>
Code language: CSS
1
2
3
4
5
6
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr); /* 3 equal columns */
  grid-template-rows: repeat(3, 100px);   /* 3 equal rows */
  gap: 0.5rem;
}

And you apply:

Code language: CSS
1
2
3
4
.item {
  grid-column: 1 / 3; /* Spans from column line 1 to 3 → covers columns 1 and 2 */
  grid-row: 2 / 4;    /* Spans from row line 2 to 4 → covers rows 2 and 3 */
}

Visual Reference (Lines Shown)

+------------+------------+------------+
|            |            |            |
|   Item 2   |   Item 3   |   Item 4   |
|            |            |            |
+------------+------------+------------+
|            |            |            |
|            |            |            |
|            |            |            |
+         Spanning        +------------+
|            |            |            |
|            |            |            |
|            |            |            |
+------------+------------+------------+

👉 Try this on CodePen

Shorthand vs Longhand#

The grid-column and grid-row properties are shorthands for their respective start and end lines:

Code language: CSS
1
2
3
4
.item {
  grid-column: 2 / 4;
  grid-row: 1 / 3;
}

This is functionally the same as:

Code language: CSS
1
2
3
4
5
6
7
.item {
  grid-column-start: 2;
  grid-column-end: 4;

  grid-row-start: 1;
  grid-row-end: 3;
}

Shorthand with span#

Instead of specifying start and end lines manually, you can use the span keyword to make your code simpler and more flexible:

Code language: CSS
1
2
3
4
.item {
  grid-column: span 2; /* Span 2 columns from auto-start */
  grid-row: span 2;    /* Span 2 rows from auto-start */
}

This tells the grid item to span 2 columns and 2 rows starting from its auto-determined position (i.e. where the browser places it in the flow).

👉 Try this on CodePen

When to use it?
  • You don’t need to control exact start/end line numbers.
  • You want the browser to determine the position automatically.
  • You're working with auto-placed items in a dynamic or responsive layout.

Grid Types#

In CSS Grid, it’s important to understand the two types of grids: explicit and implicit. These define how grid tracks (rows and columns) are created—either by the developer or automatically by the browser.

Explicit Grids#

An explicit grid is one that you define yourself using properties like grid-template-columns and grid-template-rows.

Code language: CSS
1
2
3
4
5
6
.grid {
  display: grid;
  grid-template-columns: 1fr 1fr;   /* Two equal-width columns */
  grid-template-rows: 100px 100px;  /* Two fixed-height rows */
  gap: 1rem;
}
Code language: HTML
1
2
3
4
5
6
<div class="grid">
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
  <div>Item 4</div>
</div>

In this case, you’ve explicitly created a 2×2 grid, which gives you 4 cells. Each of the 4 items is placed within this defined layout.

Visual Illustration

This shows how the explicit grid looks like:

+---------+--------+    
| Item 1  | Item 2 |    
+---------+--------+    
| Item 3  | Item 4 |    
+---------+--------+   

👉 Try this on CodePen

If you place more items than your explicit tracks can hold, the grid will automatically generate new rows or columns to accommodate them — these are known as implicit tracks, which we’ll explore next.

Implicit Grids#

In CSS Grid, if the number of items exceeds the explicitly defined rows or columns, the browser automatically creates additional tracks — these form what’s known as the implicit grid.

You can control the size of these extra rows and columns using:

  • grid-auto-rows – defines height of implicit rows.
  • grid-auto-columns – defines width of implicit columns.

Example: Implicit Rows#

Let’s say you define only 2 rows, but add 5 items:

Code language: CSS
1
2
3
4
5
6
.grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 100px 100px; /* Explicit: only 2 rows defined */
  gap: 1rem;
}
Code language: HTML
1
2
3
4
5
6
7
<div class="grid">
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
  <div>Item 4</div>
  <div>Item 5</div> <!-- This item doesn't fit in the defined grid -->
</div>

What happens?

  • The first 4 items fill the 2×2 grid.
  • The 5th item overflows the defined rows.
  • So, the browser creates a 3rd row automatically — this is the implicit grid.

Visual Illustration

This shows what happens when items overflow the defined rows (and new implicit rows are added):

Explicit Grid:          Implicit Grid:

+---------+--------+    +---------+--------+
| Item 1  | Item 2 |    | Item 1  | Item 2 |
+---------+--------+    +---------+--------+
| Item 3  | Item 4 |    | Item 3  | Item 4 |
+---------+--------+    +---------+--------+
                        | Item 5  |   —    | ← auto-created implicit row
                        +---------+--------+

By default, the height of implicit rows is auto. You can control their size using grid-auto-rows:

Code language: CSS
1
2
3
.grid {
  grid-auto-rows: 100px; /* Applies height to all implicit rows */
}

👉 Try this on CodePen

Example: Implicit Columns#

Now let’s say you only define rows, and use manual placement or grid-auto-flow: column to push items into new columns:

Code language: CSS
1
2
3
4
5
6
.grid {
  display: grid;
  grid-template-rows: 100px 100px;
  grid-auto-flow: column; /* Place items column-wise */
  grid-auto-columns: 150px; /* Width for any implicitly created columns */
}
Code language: HTML
1
2
3
4
5
6
7
<div class="grid">
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
  <div>Item 4</div>
  <div>Item 5</div> <!-- This item doesn't fit in the defined grid -->
</div>

What happens?

  • Items will flow across columns, not rows.
  • Since no grid-template-columns is defined, the browser will generate columns implicitly.
  • Each column will now be 150px wide (because of grid-auto-columns).

Visual Illustration

This shows what happens when items overflow the defined columns (or grid-auto-flow: column creates new implicit columns):

Explicit Grid:          Implicit Grid:

+---------+--------+    +---------+--------+--------+
| Item 1  | Item 2 |    | Item 1  | Item 2 | Item 5 |
+---------+--------+    +---------+--------+--------+
| Item 3  | Item 4 |    | Item 3  | Item 4 |        |
+---------+--------+    +---------+--------+--------+
                                                ↑ implicit columns created dynamically

Use grid-auto-columns to control the width of these new columns.

👉 Try this on CodePen

Conclusion#

You’ve now mastered the core tools that bring power, readability, and precision to CSS Grid layouts:

  • Named areas help you design layouts visually and semantically.
  • Item alignment ensures pixel-perfect placement in every cell.
  • Spanning techniques let you control flow and sizing beyond automatic placement.
  • Explicit vs. implicit grids give you confidence when your layout grows unexpectedly.

Up next in Part 3 → Responsive CSS Grid Layouts: fr Units, minmax(), auto-fill, and auto-fit Explained, we’ll unlock how to:

  • Use fr, minmax(), auto-fit, and auto-fill for fluid responsive tracks
  • Pair grid with media and container queries
  • Build robust, flexible layouts that adapt to any screen — no media query soup needed!

I hope you’ve found this post informative and helpful. Thank you for reading!