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.
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.
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:
- A single grid cell
- Multiple adjacent grid cells (spanning multiple rows, columns, or both)
- Named areas defined with
grid-template-areas
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:
- To assign an item to a named grid area defined in
grid-template-areas - 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:
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:
- Auto placement: Items are automatically positioned according to the grid's flow and any available space
- Explicit placement: Items are explicitly positioned using the properties we've covered
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.
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:
- Use
orderfor minor rearrangements rather than wholesale reorganization - Ensure that the document still makes logical sense when read in source order
- Test keyboard navigation to ensure a good experience for users who don't use pointing devices
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
- Use line-based placement for simple patterns, named areas for complex layouts
- Prefer spanning multiple cells over creating very large cells
- Consider source order when arranging items for accessibility
- Use alignment properties to fine-tune positioning within cells
- Combine auto and explicit placement for flexible layouts that still maintain control over key elements
- Test grid layouts at various viewport sizes to ensure they behave as expected
- Use responsive placement to optimize layouts for different devices
Common Pitfalls to Avoid
- Overlapping items unintentionally - Always check that your placement properties don't create accidental overlaps
- Overusing the order property - It can make the code harder to maintain and may create accessibility issues
- Creating empty rows or columns - This can cause unexpected spacing in your layout
- Forgetting that grid-area order is row-start/column-start/row-end/column-end - The clockwise pattern can be unintuitive
- Ignoring implicit grid behavior - If items are placed outside the explicit grid, understand how the implicit grid will form
- Using complex span calculations - Explicit line numbers are often clearer than complex span calculations
Performance Considerations
Grid layout is generally performant, but there are some considerations for optimal performance:
- Limit the number of grid items - Very large numbers (thousands) of grid items can impact performance
- Be cautious with complex layering - Heavily overlapping items with complex z-index values may cause rendering inefficiencies
- Use explicit sizing - When possible, provide explicit grid track sizes rather than relying on auto-sizing for better layout stability
- Consider using
will-change: transformfor grid items that will be animated
Practice Exercises
Exercise 1: Product Card Layout
Create a product card with the following requirements:
- The card contains a product image, title, price, description, and "Add to Cart" button
- Use Grid to position these elements in a visually appealing layout
- The title should span the full width of the card
- The image should be on the left with the description on the right
- The price should appear prominently
- The "Add to Cart" button should be at the bottom right
- The card should collapse to a vertical layout on mobile devices
Exercise 2: Portfolio Grid
Create a portfolio grid with the following requirements:
- The grid contains various project thumbnails
- Some projects are featured and should span 2×2 cells
- Other projects should be standard size (1×1 cells)
- The layout should be responsive, adjusting the number of columns based on viewport width
- Use a combination of auto-placement and explicit placement for featured items
Exercise 3: News Homepage Layout
Create a news homepage layout with:
- A header spanning the full width
- A hero article with a large image and headline (spanning multiple columns)
- Secondary news items in a grid below the hero
- A sidebar with trending topics
- A footer with multiple columns of links
- The layout should adapt to different screen sizes
Challenge Exercise: Interactive Dashboard
Create an interactive dashboard layout that:
- Contains various widgets of different sizes
- Allows widgets to be reordered using the order property (simulate this with buttons that change CSS order values)
- Includes a collapsed/expanded sidebar that changes the overall grid layout
- Is fully responsive across device sizes
Summary and Next Steps
In this lecture, we've covered the key properties and techniques for placing, sizing, and aligning grid items:
- Line-based placement with
grid-row,grid-column, and their component properties - The
grid-areaproperty for both named area assignment and shorthand placement - Item spanning with the
spankeyword - Alignment properties:
justify-self,align-self, andplace-self - Visual reordering with the
orderproperty - Layering items with
z-index - Advanced techniques for responsive and complex layouts
- Real-world examples and best practices
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: