Grid Item Placement and Alignment

Module 6: Modern CSS & Layouts - Tuesday (Lecture 3)

Introduction to Grid Item Properties

In our previous lectures, we explored how to create grid containers and control their structure. Now, we'll focus on the other side of the Grid layout system—grid items and the properties that control their placement and behavior within the grid.

Grid item properties give you precise control over where individual elements appear in your layout, how much space they occupy, and how they align within their designated grid cells.

graph TD A[Grid Item Properties] --> B[Placement Properties] A --> C[Spanning Properties] A --> D[Alignment Properties] A --> E[Order and Layering] B --> B1[grid-column/grid-row] B --> B2[grid-column-start/grid-column-end] B --> B3[grid-row-start/grid-row-end] B --> B4[grid-area] C --> C1[span keyword] D --> D1[justify-self] D --> D2[align-self] D --> D3[place-self] E --> E1[order] E --> E2[z-index]

These properties, when combined with the container properties we've already learned, provide a complete toolkit for creating sophisticated layouts.

Understanding Grid Lines and Grid Areas

Before diving into grid item placement, it's essential to understand how grid lines and grid areas work in CSS Grid.

Grid Lines

Grid lines are the horizontal and vertical dividing lines that define the grid structure. They are numbered starting from 1, with separate numbering for rows and columns.

You can also number grid lines from the end using negative values, where -1 refers to the last line, -2 to the second-to-last line, and so on.

1 2 3 4 5 1 2 3 -5 -4 -3 -2 -1 -3 -2 -1 [header-start] [header-end]

As we learned in the previous lecture, grid lines can also have names assigned through the grid-template-columns and grid-template-rows properties or implicitly through grid-template-areas.

Grid Areas

A grid area is a rectangular space in the grid, defined by four grid lines (start and end lines for both rows and columns). Grid areas can be:

Think of grid areas like rooms in a house—each has defined boundaries, and some rooms might be larger than others, spanning more space.

Placement Properties: Grid Lines

Grid items can be precisely positioned using grid line-based placement properties. These properties define which grid lines the item should start and end at.

Basic Line-Based Placement

There are four primary properties for line-based placement:

/* Long-form properties */
.item {
  grid-row-start: 1;     /* Start at the first row line */
  grid-row-end: 3;       /* End at the third row line (spanning two rows) */
  grid-column-start: 2;  /* Start at the second column line */
  grid-column-end: 4;    /* End at the fourth column line (spanning two columns) */
}

/* Shorthand properties */
.item {
  grid-row: 1 / 3;       /* Start at row line 1, end at row line 3 */
  grid-column: 2 / 4;    /* Start at column line 2, end at column line 4 */
}

These properties place the item in the grid based on the grid line numbers or names. The item will occupy the cells between the specified lines.

Using Negative Line Numbers

Negative line numbers count from the end of the grid, which can be useful for positioning elements relative to the end:

/* Position an item in the bottom-right corner */
.item {
  grid-row: -2 / -1;     /* Second-to-last row to last row */
  grid-column: -2 / -1;  /* Second-to-last column to last column */
}

/* Span the entire last row */
.item {
  grid-row: -1;          /* Just the last row */
  grid-column: 1 / -1;   /* From first to last column */
}

Negative line numbers are particularly useful when you don't know exactly how many rows or columns your grid will have, perhaps due to responsive design or dynamic content.

Using Named Lines

If you've defined named grid lines in your container, you can use those names for more semantic item placement:

/* Container with named lines */
.container {
  display: grid;
  grid-template-columns: 
    [sidebar-start] 250px 
    [sidebar-end content-start] 1fr 
    [content-end];
  grid-template-rows: 
    [header-start] 100px 
    [header-end main-start] 1fr 
    [main-end footer-start] auto 
    [footer-end];
}

/* Placing items using named lines */
.header {
  grid-column: sidebar-start / content-end;
  grid-row: header-start / header-end;
}

.sidebar {
  grid-column: sidebar-start / sidebar-end;
  grid-row: main-start / footer-end;
}

Named lines make your CSS more readable and maintainable, as they express the logical structure of your layout rather than relying on abstract line numbers.

The span Keyword

The span keyword allows you to specify how many tracks an item should span, rather than providing an explicit end line:

/* Span 2 rows and 3 columns from a starting position */
.item {
  grid-row: 2 / span 2;      /* Start at line 2, span 2 rows */
  grid-column: 1 / span 3;   /* Start at line 1, span 3 columns */
}

/* Span 2 columns from the end */
.item {
  grid-column: span 2 / -1;  /* End at the last line, span 2 columns backwards */
}

The span keyword is helpful when you know how many tracks you want an item to occupy, but don't necessarily know (or care about) the specific ending line.

Think of it like asking for a table that seats four people at a restaurant, rather than requesting a specific table number. You're specifying the size requirement, not the exact location.

The grid-area Property

The grid-area property is a powerful shorthand that can be used in two ways:

  1. To assign an item to a named grid area defined in grid-template-areas
  2. As a shorthand for all four grid-row-start, grid-column-start, grid-row-end, grid-column-end properties

Using Named Grid Areas

When used with named areas, the syntax is straightforward:

/* Container with named areas */
.container {
  display: grid;
  grid-template-areas:
    "header header header"
    "sidebar content content"
    "footer footer footer";
}

/* Assigning items to areas */
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.footer { grid-area: footer; }

This approach creates a clear, visual mapping between your HTML elements and your grid layout. It's particularly useful for larger layouts where the relationship between items and grid cells would be complex to express with line numbers.

Grid-area as a Four-Value Shorthand

When used as a shorthand for the four placement properties, the syntax follows this pattern:

/* grid-area: row-start / column-start / row-end / column-end */
.item {
  grid-area: 1 / 2 / 3 / 4;
}

This places the item from row line 1 to row line 3 (spanning 2 rows) and from column line 2 to column line 4 (spanning 2 columns).

The order of values in this shorthand is important and follows a clockwise pattern:

row-start (1) column-start (2) row-end (3) column-end (4)

If you find this order hard to remember, think of it as "tracing the path around an item" - you start at the top (row-start), move to the right (column-start), then to the bottom (row-end), and finally to the left (column-end).

This shorthand format is more concise but less readable than using separate properties. It's best used for simpler placement or in situations where space efficiency in your CSS is a priority.

Auto Placement vs. Explicit Placement

Grid items can be placed in two ways:

Both approaches can be used together in the same grid—some items can be explicitly placed while others are allowed to flow naturally.

/* Container */
.gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 200px;
  gap: 20px;
}

/* Explicitly placed featured item */
.featured {
  grid-column: 1 / 3;    /* Spans the first two columns */
  grid-row: 1 / 3;       /* Spans the first two rows */
}

/* All other items are auto-placed */
.gallery-item {
  /* No placement properties - will flow automatically */
}

This creates a gallery where the featured item takes up a 2×2 area in the top-left, while other items flow around it according to the grid's auto-placement algorithm.

It's like having a reserved table at a restaurant (explicit placement) while other diners are seated wherever there's available space (auto placement).

Understanding Grid Auto-Placement

When items don't have explicit placement, they follow the auto-placement algorithm, which is controlled by the grid-auto-flow property on the container:

/* Items fill rows first (default) */
grid-auto-flow: row;

/* Items fill columns first */
grid-auto-flow: column;

/* Attempt to fill in holes in the grid */
grid-auto-flow: dense;

Understanding how auto-placement works helps you create more efficient layouts, especially when combining explicitly placed items with auto-placed ones.

Alignment Properties for Grid Items

Grid items can be individually aligned within their grid cells using the following properties:

justify-self

The justify-self property aligns an item along the inline (row) axis:

/* Default - item fills the cell horizontally */
justify-self: stretch;

/* Align item to the start of the cell */
justify-self: start;

/* Center item horizontally in the cell */
justify-self: center;

/* Align item to the end of the cell */
justify-self: end;

align-self

The align-self property aligns an item along the block (column) axis:

/* Default - item fills the cell vertically */
align-self: stretch;

/* Align item to the top of the cell */
align-self: start;

/* Center item vertically in the cell */
align-self: center;

/* Align item to the bottom of the cell */
align-self: end;

place-self

The place-self property is a shorthand for both justify-self and align-self:

/* Same value for both axes */
place-self: center;

/* Different values for each axis */
place-self: start end;  /* align-self: start; justify-self: end; */

These properties override the default alignment set by the container's justify-items and align-items properties.

stretch start center end justify-self start center end stretch align-self start center end stretch place-self start start center end end stretch

These alignment properties give you fine-grained control over how each item sits within its allocated grid cells, similar to how you might position a picture within a frame—centered, flush with one edge, or stretching to fill the entire frame.

The order Property

The order property controls the visual order of grid items, regardless of their source order in the HTML:

/* Default value - items appear in source order */
.item {
  order: 0;
}

/* This item will appear before items with higher order values */
.first-visual-item {
  order: -1;
}

/* This item will appear after items with lower order values */
.last-visual-item {
  order: 1;
}

All grid items have a default order value of 0. Items with the same order value are displayed in the order they appear in the source HTML.

The order property is powerful for rearranging content visually without changing the HTML structure. For example, in a responsive design, you might want to show a sidebar after the main content on mobile but beside it on desktop:

/* Desktop layout */
@media (min-width: 768px) {
  .container {
    display: grid;
    grid-template-columns: 1fr 300px;
  }
  
  .main-content {
    grid-column: 1;
  }
  
  .sidebar {
    grid-column: 2;
  }
}

/* Mobile layout */
@media (max-width: 767px) {
  .container {
    display: grid;
    grid-template-columns: 1fr;
  }
  
  .main-content {
    grid-row: 1;
    /* or use order: -1; */
  }
  
  .sidebar {
    grid-row: 2;
    /* or use order: 1; */
  }
}

Accessibility Considerations

While the order property is useful for visual rearrangement, it's important to note that it only affects the visual order—it does not change the HTML structure or the tab order for keyboard navigation. This can create a disconnect between visual presentation and document structure, which might confuse some users.

For accessibility reasons, it's generally best to:

Layering Grid Items with z-index

Grid items can overlap if they occupy the same grid cells. When items overlap, you can control their stacking order using the z-index property:

/* Item will appear behind other overlapping items */
.background-item {
  grid-column: 1 / 4;
  grid-row: 1 / 4;
  z-index: 1;
}

/* Item will appear in front of items with lower z-index */
.foreground-item {
  grid-column: 2 / 3;
  grid-row: 2 / 3;
  z-index: 2;
}

Unlike with positioned elements, grid items don't need a specific position value (like position: relative) for z-index to take effect—it works automatically on overlapping grid items.

This capability allows for creative layouts with intentional overlapping elements, such as cards with overlapping headers, image galleries with hover effects, or layered UI components.

Example: Card with Overlapping Elements

/* CSS */
.card {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-template-rows: repeat(12, 1fr);
  height: 300px;
  position: relative;
}

.card-image {
  grid-column: 1 / 13;
  grid-row: 1 / 13;
  z-index: 1;
  object-fit: cover;
  width: 100%;
  height: 100%;
}

.card-overlay {
  grid-column: 1 / 13;
  grid-row: 8 / 13;
  z-index: 2;
  background: linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,0.8));
}

.card-content {
  grid-column: 2 / 12;
  grid-row: 9 / 12;
  z-index: 3;
  color: white;
}

This creates a card with an image that spans the entire area, a gradient overlay at the bottom, and content positioned on top of the overlay. The z-index values ensure the content appears above the overlay, which appears above the image.

Advanced Grid Item Techniques

Spanning Techniques

Grid items can span multiple rows or columns in various ways:

/* Spanning fixed number of tracks */
.item-1 {
  grid-column: span 2;  /* Spans 2 columns */
  grid-row: span 3;     /* Spans 3 rows */
}

/* Spanning from specific line to specific line */
.item-2 {
  grid-column: 2 / 5;   /* From line 2 to line 5 (spans 3 columns) */
  grid-row: 1 / 3;      /* From line 1 to line 3 (spans 2 rows) */
}

/* Spanning from specific line to end */
.item-3 {
  grid-column: 3 / -1;  /* From line 3 to the last line */
}

/* Mixing span with specific lines */
.item-4 {
  grid-column: 2 / span 3;  /* From line 2, spanning 3 columns */
  grid-row: span 2 / 5;     /* Spanning 2 rows, ending at line 5 */
}

These spanning techniques give you flexible ways to control how much space items occupy in the grid.

Responsive Grid Item Placement

Grid items can be repositioned based on screen size using media queries:

/* Base layout */
.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
}

.header {
  grid-column: 1 / -1;  /* Full width on all screens */
}

.sidebar {
  grid-column: 1;
  grid-row: 2;
}

.main {
  grid-column: 2 / -1;
  grid-row: 2;
}

.footer {
  grid-column: 1 / -1;
  grid-row: 3;
}

/* Tablet layout */
@media (max-width: 900px) {
  .container {
    grid-template-columns: repeat(2, 1fr);
  }
  
  .main {
    grid-column: 1 / -1;
    grid-row: 2;
  }
  
  .sidebar {
    grid-column: 1 / -1;
    grid-row: 3;
  }
  
  .footer {
    grid-row: 4;
  }
}

/* Mobile layout */
@media (max-width: 600px) {
  .container {
    grid-template-columns: 1fr;
  }
}

This approach allows for dramatic layout changes at different breakpoints without altering the HTML structure.

Area-Based Layout Patterns

For complex layouts, it's often cleaner to use named areas and reassign them at different breakpoints:

/* Base layout */
.container {
  display: grid;
  grid-template-columns: 250px 1fr 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header header header"
    "sidebar content content"
    "footer footer footer";
  min-height: 100vh;
}

.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.footer { grid-area: footer; }

/* Tablet layout */
@media (max-width: 900px) {
  .container {
    grid-template-columns: 1fr 1fr;
    grid-template-areas:
      "header header"
      "content content"
      "sidebar sidebar"
      "footer footer";
  }
}

/* Mobile layout */
@media (max-width: 600px) {
  .container {
    grid-template-columns: 1fr;
    grid-template-areas:
      "header"
      "content"
      "sidebar"
      "footer";
  }
}

This approach is particularly readable and maintainable, as the layout structure is visually represented in the CSS.

Real-World Examples

Image Gallery with Featured Images

This example creates a responsive image gallery with some featured images that span multiple cells:

/* CSS */
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  grid-auto-rows: 200px;
  gap: 20px;
}

.gallery-item {
  overflow: hidden;
  position: relative;
}

.gallery-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.gallery-item.featured-horizontal {
  grid-column: span 2;
}

.gallery-item.featured-vertical {
  grid-row: span 2;
}

.gallery-item.featured-large {
  grid-column: span 2;
  grid-row: span 2;
}

/* Caption overlay */
.caption {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(0, 0, 0, 0.7);
  color: white;
  padding: 10px;
  transform: translateY(100%);
  transition: transform 0.3s ease;
}

.gallery-item:hover .caption {
  transform: translateY(0);
}

/* HTML */
<div class="gallery">
  <div class="gallery-item featured-large">
    <img src="image1.jpg" alt="Featured image">
    <div class="caption">Featured Image</div>
  </div>
  <div class="gallery-item">
    <img src="image2.jpg" alt="Standard image">
    <div class="caption">Standard Image</div>
  </div>
  <div class="gallery-item featured-horizontal">
    <img src="image3.jpg" alt="Wide image">
    <div class="caption">Wide Image</div>
  </div>
  <!-- More items... -->
</div>

This gallery automatically adjusts to different screen sizes, with featured images maintaining their prominence by spanning multiple cells. The hover effect with the sliding caption adds interactivity without cluttering the layout.

Magazine-Style Article Layout

This example creates a magazine-style article layout with a headline, lead image, pull quotes, and body text:

/* CSS */
.article {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-auto-rows: minmax(min-content, auto);
  gap: 20px;
  padding: 30px;
}

.article-header {
  grid-column: 1 / -1;
  text-align: center;
}

.article-lead {
  grid-column: 3 / 11;
  font-size: 1.2em;
  line-height: 1.6;
}

.article-image {
  grid-column: 1 / -1;
  max-height: 500px;
  overflow: hidden;
}

.article-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.article-content {
  grid-column: 3 / 11;
  line-height: 1.6;
}

.article-pullquote {
  grid-column: 2 / 6;
  font-size: 1.5em;
  line-height: 1.4;
  font-style: italic;
  position: relative;
  padding: 20px;
  background-color: #f9f9f9;
  border-left: 5px solid #333;
  align-self: center;
}

.article-sidebar {
  grid-column: 8 / 12;
  grid-row: span 2;
  background-color: #f0f0f0;
  padding: 20px;
  align-self: start;
}

/* Mobile layout */
@media (max-width: 768px) {
  .article {
    grid-template-columns: 1fr;
    gap: 15px;
    padding: 15px;
  }
  
  .article-header,
  .article-lead,
  .article-image,
  .article-content,
  .article-pullquote,
  .article-sidebar {
    grid-column: 1;
  }
  
  .article-pullquote {
    margin: 20px 0;
  }
}

This layout creates a professional, magazine-style presentation for article content, with different elements given appropriate emphasis through their placement and sizing. On mobile, it gracefully collapses to a single column while preserving readability.

Best Practices for Grid Items

Guidelines for Effective Grid Item Usage

Common Pitfalls to Avoid

Performance Considerations

Grid layout is generally performant, but there are some considerations for optimal performance:

Practice Exercises

Exercise 1: Product Card Layout

Create a product card with the following requirements:

Exercise 2: Portfolio Grid

Create a portfolio grid with the following requirements:

Exercise 3: News Homepage Layout

Create a news homepage layout with:

Challenge Exercise: Interactive Dashboard

Create an interactive dashboard layout that:

Summary and Next Steps

In this lecture, we've covered the key properties and techniques for placing, sizing, and aligning grid items:

With these grid item properties, combined with the container properties we covered earlier, you now have a complete toolkit for creating sophisticated, responsive layouts using CSS Grid.

As you continue your journey with CSS Grid, consider experimenting with combinations of Grid and other layout techniques like Flexbox for even more powerful layouts. Also explore Grid's capabilities for creating dynamic layouts with CSS variables and calc() for truly flexible designs.

Additional resources to deepen your understanding: