Grid Item Properties: Precise Control Over Every Layout Element â
Imagine you're playing a puzzle game where the game board provides you with a grid structure (this is the Grid container), and each puzzle piece (Grid item) can occupy one or more cells and be placed anywhere. Grid item properties are your tools that allow you to precisely tell each puzzle piece: "You should start from row 2, column 3, and occupy 2 rows and 3 columns of space."
In the previous chapter, we learned how to define the overall grid structure using container properties. Now, let's learn how to control the position and behavior of individual items within this structure.
Line-Based Positioning â
One of Grid's most powerful features is the ability to precisely specify which cells an item should occupy. This is achieved through grid line numbering.
grid-column: Controlling Column Position â
The grid-column property specifies the starting and ending positions of an item in the column direction.
Basic Usage â
.item {
grid-column-start: 1; /* Start from the first vertical line */
grid-column-end: 3; /* End at the third vertical line */
/* Equivalent to occupying columns 1 and 2 */
}The more common shorthand form is:
.item {
grid-column: 1 / 3; /* From line 1 to line 3 */
}Let's look at a complete example:
<div class="grid">
<div class="item item-1">Item 1</div>
<div class="item item-2">Item 2</div>
<div class="item item-3">Item 3</div>
</div>.grid {
display: grid;
grid-template-columns: repeat(4, 1fr); /* 4 columns, creating 5 vertical lines */
grid-auto-rows: 100px;
gap: 10px;
background-color: #f5f5f5;
padding: 10px;
}
.item {
background-color: #2196f3;
color: white;
display: flex;
align-items: center;
justify-content: center;
border-radius: 4px;
}
.item-1 {
grid-column: 1 / 3; /* Occupies columns 1-2 */
background-color: #f44336;
}
.item-2 {
grid-column: 3 / 5; /* Occupies columns 3-4 */
background-color: #4caf50;
}
.item-3 {
grid-column: 1 / 5; /* Occupies all 4 columns */
background-color: #ff9800;
}In this example:
- Item 1 spans 2 columns (from line 1 to line 3)
- Item 2 also spans 2 columns (from line 3 to line 5)
- Item 3 spans all 4 columns (from line 1 to line 5)
Using the span Keyword â
Sometimes you don't care about the specific starting line and just want an item to span a certain number of columns. You can use the span keyword:
.item {
grid-column: span 2; /* Span 2 columns, position determined by auto-placement */
}You can also specify the starting line and then use span to indicate how many columns to span:
.item {
grid-column: 2 / span 3; /* Start from line 2, span 3 columns, ending at line 5 */
}Or vice versa, specify the ending line and the number of columns to span:
.item {
grid-column: span 2 / 5; /* Span 2 columns, ending at line 5, starting from line 3 */
}Practical Application: Creating Featured Items
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
}
.card {
background-color: white;
border: 1px solid #ddd;
padding: 20px;
border-radius: 8px;
}
.card-featured {
grid-column: span 2; /* Featured card spans 2 columns */
background-color: #2196f3;
color: white;
font-size: 20px;
}Negative Indexing â
Grid supports negative indexing for counting from the end. -1 represents the last line, -2 represents the second-to-last line, and so on.
.item {
grid-column: 1 / -1; /* From the first line to the last line, occupying all columns */
}This is particularly useful when you're unsure how many columns the grid has:
.header {
grid-column: 1 / -1; /* Occupy all columns regardless of how many there are */
}grid-row: Controlling Row Position â
grid-row works exactly the same way as grid-column, but it controls rows instead of columns.
.item {
grid-row: 1 / 3; /* From row 1 to row 3, spanning 2 rows */
}Complete Example: Creating Complex Layouts
<div class="grid">
<div class="item header">Header</div>
<div class="item sidebar">Sidebar</div>
<div class="item main">Main Content</div>
<div class="item aside">Aside</div>
<div class="item footer">Footer</div>
</div>.grid {
display: grid;
grid-template-columns: 200px 1fr 300px; /* 3 columns */
grid-template-rows: auto 1fr auto; /* 3 rows */
min-height: 100vh;
gap: 10px;
}
.item {
background-color: #2196f3;
color: white;
padding: 20px;
display: flex;
align-items: center;
justify-content: center;
}
.header {
grid-column: 1 / -1; /* Span all columns */
grid-row: 1; /* First row */
background-color: #333;
}
.sidebar {
grid-column: 1; /* First column */
grid-row: 2; /* Second row */
background-color: #4caf50;
}
.main {
grid-column: 2; /* Second column */
grid-row: 2; /* Second row */
background-color: white;
color: #333;
}
.aside {
grid-column: 3; /* Third column */
grid-row: 2; /* Second row */
background-color: #ff9800;
}
.footer {
grid-column: 1 / -1; /* Span all columns */
grid-row: 3; /* Third row */
background-color: #333;
}This creates a classic page layout: a header that spans all columns at the top, three columns in the middle, and a footer that spans all columns at the bottom.
Using span to Span Multiple Rows â
Just like grid-column, grid-row can also use span:
.sidebar {
grid-column: 1;
grid-row: 2 / span 2; /* Start from row 2, span 2 rows */
}Practical Application: Image Gallery
<div class="gallery">
<div class="photo photo-1">Photo 1</div>
<div class="photo photo-2">Photo 2</div>
<div class="photo photo-3">Photo 3</div>
<div class="photo photo-4">Photo 4</div>
<div class="photo photo-5">Photo 5</div>
<div class="photo photo-6">Photo 6</div>
</div>.gallery {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 200px;
gap: 15px;
}
.photo {
background-size: cover;
background-position: center;
border-radius: 8px;
overflow: hidden;
}
/* Create photos of different sizes */
.photo-1 {
grid-column: span 2;
grid-row: span 2;
}
.photo-3 {
grid-column: span 2;
}
.photo-5 {
grid-row: span 2;
}This creates a dynamic gallery layout where some photos are larger (occupying more space) and others are normal size.
grid-area: Position Shorthand â
grid-area is a super shorthand property that can specify both row and column start and end positions simultaneously:
.item {
grid-area: row-start / column-start / row-end / column-end;
}For example:
.item {
grid-area: 1 / 2 / 3 / 4;
/* Equivalent to: */
/* grid-row: 1 / 3; */
/* grid-column: 2 / 4; */
/* From row 1, column 2 to row 3, column 4 */
}While this is concise, the order can be hard to remember. I personally prefer using grid-row and grid-column separately for clearer code.
grid-area has another use: working with named grid areas, which we'll cover in the next section.
Alignment Control â
Grid containers can set default alignment for all items, but individual items can override these defaults.
justify-self: Horizontal Alignment of Individual Items â
justify-self controls the horizontal alignment of an individual item within its cell, overriding the container's justify-items setting.
.grid {
display: grid;
grid-template-columns: repeat(3, 200px);
justify-items: start; /* Default all items to start */
}
.item {
width: 100px;
background-color: #2196f3;
}
.item-centered {
justify-self: center; /* This item is centered, others start */
}
.item-right {
justify-self: end; /* This item ends, others start */
}Possible values:
start: Left-alignedend: Right-alignedcenter: Horizontally centeredstretch: Stretch to fill cell width
Practical Application: Button Alignment
<div class="card">
<h3>Premium Plan</h3>
<p>$29/month</p>
<ul>
<li>Feature 1</li>
<li>Feature 2</li>
<li>Feature 3</li>
</ul>
<button class="btn-choose">Choose Plan</button>
</div>.card {
display: grid;
grid-template-rows: auto auto 1fr auto;
/* Title, price, feature list, button */
gap: 15px;
padding: 30px;
background-color: white;
border: 1px solid #ddd;
border-radius: 8px;
}
.btn-choose {
justify-self: stretch; /* Button stretches to full width */
padding: 12px;
background-color: #2196f3;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}align-self: Vertical Alignment of Individual Items â
align-self controls the vertical alignment of an individual item within its cell, overriding the container's align-items setting.
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 150px;
align-items: start; /* Default all items to start */
}
.item {
background-color: #2196f3;
padding: 10px;
}
.item-centered {
align-self: center; /* This item is vertically centered */
}
.item-bottom {
align-self: end; /* This item aligns to bottom */
}
.item-stretched {
align-self: stretch; /* This item stretches to full cell height */
}Possible values:
start: Top-alignedend: Bottom-alignedcenter: Vertically centeredstretch: Stretch to fill cell height
place-self: Alignment Shorthand â
place-self is shorthand for align-self and justify-self:
.item {
place-self: center center;
/* Equivalent to: */
/* align-self: center; */
/* justify-self: center; */
/* Item is perfectly centered in cell */
}If you write only one value, both directions use this value:
.item {
place-self: center;
/* Both horizontal and vertical centering */
}Stacking Order â
When multiple items occupy the same cell, they overlap. By default, later items will cover earlier items.
z-index: Controlling Stacking Order â
You can use z-index to control the stacking order of overlapping items:
<div class="grid">
<div class="item item-1">Item 1</div>
<div class="item item-2">Item 2</div>
<div class="item item-3">Item 3</div>
</div>.grid {
display: grid;
grid-template-columns: repeat(3, 150px);
grid-auto-rows: 150px;
gap: 10px;
}
.item {
background-color: #2196f3;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
border-radius: 8px;
border: 3px solid white;
}
.item-1 {
grid-column: 1 / 3;
grid-row: 1 / 3;
background-color: #f44336;
z-index: 1; /* Top layer */
}
.item-2 {
grid-column: 2 / 4;
grid-row: 1 / 2;
background-color: #4caf50;
z-index: 2; /* Middle layer */
}
.item-3 {
grid-column: 2 / 4;
grid-row: 2 / 3;
background-color: #ff9800;
z-index: 3; /* Topmost layer */
}In this example, three items have overlapping parts, and the item with the higher z-index value displays on the upper layer.
Practical Application: Card Stack Effect
.card-stack {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
width: 300px;
height: 200px;
}
.card {
grid-column: 1;
grid-row: 1;
background-color: white;
border: 1px solid #ddd;
border-radius: 8px;
padding: 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
transition: transform 0.3s, z-index 0s;
}
.card:nth-child(1) {
transform: rotate(-5deg);
z-index: 1;
}
.card:nth-child(2) {
transform: rotate(0deg);
z-index: 2;
}
.card:nth-child(3) {
transform: rotate(5deg);
z-index: 3;
}
.card:hover {
z-index: 10;
transform: scale(1.05) rotate(0deg);
}This creates a card stack effect where cards float to the top and scale up on hover.
Practical Application Examples â
Let's combine these properties to create some practical layouts.
Magazine-Style Article Layout â
<article class="magazine-article">
<h1 class="title">Breaking: Major Discovery in Science</h1>
<img class="hero-image" src="hero.jpg" alt="Hero" />
<p class="intro">This is the introduction paragraph...</p>
<p class="content">Main content goes here...</p>
<aside class="pullquote">"This is a pull quote"</aside>
<p class="content">More content...</p>
<figure class="side-image">
<img src="side.jpg" alt="Side" />
<figcaption>Image caption</figcaption>
</figure>
<p class="content">Even more content...</p>
</article>.magazine-article {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr; /* 6 columns */
gap: 20px;
max-width: 1200px;
margin: 0 auto;
padding: 40px 20px;
}
.title {
grid-column: 1 / -1; /* Span all columns */
font-size: 48px;
margin: 0 0 30px 0;
}
.hero-image {
grid-column: 1 / -1; /* Span all columns */
width: 100%;
height: 400px;
object-fit: cover;
border-radius: 8px;
}
.intro {
grid-column: 1 / 5; /* Span left 4 columns */
font-size: 20px;
font-weight: 500;
color: #666;
}
.content {
grid-column: 1 / 5; /* Main content spans left 4 columns */
line-height: 1.8;
}
.pullquote {
grid-column: 5 / -1; /* Quote spans right 2 columns */
grid-row: 4 / 6; /* Span 2 rows */
align-self: start;
background-color: #f5f5f5;
padding: 30px;
border-left: 4px solid #2196f3;
font-size: 24px;
font-style: italic;
color: #333;
}
.side-image {
grid-column: 5 / -1; /* Side image spans right 2 columns */
align-self: start;
margin: 0;
}
.side-image img {
width: 100%;
border-radius: 8px;
}
.side-image figcaption {
margin-top: 10px;
font-size: 14px;
color: #666;
text-align: center;
}This creates a professional magazine layout with main content in the wide left column and quotes and images in the narrow right column.
Product Showcase Grid â
<div class="product-showcase">
<div class="product featured">
<h2>Featured Product</h2>
<p>Our best seller</p>
</div>
<div class="product">Product 2</div>
<div class="product">Product 3</div>
<div class="product">Product 4</div>
<div class="product">Product 5</div>
<div class="product">Product 6</div>
<div class="product">Product 7</div>
<div class="product">Product 8</div>
</div>.product-showcase {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-auto-rows: 200px;
gap: 15px;
padding: 20px;
}
.product {
background-color: white;
border: 1px solid #ddd;
border-radius: 8px;
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
transition: transform 0.3s, box-shadow 0.3s;
}
.product:hover {
transform: translateY(-5px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.product.featured {
grid-column: span 2; /* Span 2 columns */
grid-row: span 2; /* Span 2 rows */
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
font-size: 24px;
}
.product.featured h2 {
margin: 0 0 10px 0;
font-size: 32px;
}Dashboard Widgets â
<div class="dashboard">
<div class="widget stats">
<h3>Statistics</h3>
<p>1,234 users</p>
</div>
<div class="widget chart">
<h3>Sales Chart</h3>
<div class="chart-area">Chart goes here</div>
</div>
<div class="widget activity">
<h3>Recent Activity</h3>
<ul>
<li>User logged in</li>
<li>Order placed</li>
<li>Payment received</li>
</ul>
</div>
<div class="widget notifications">
<h3>Notifications</h3>
<p>3 new messages</p>
</div>
</div>.dashboard {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
grid-auto-rows: minmax(150px, auto);
gap: 20px;
padding: 20px;
background-color: #f5f5f5;
}
.widget {
background-color: white;
border-radius: 8px;
padding: 20px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.widget h3 {
margin: 0 0 15px 0;
color: #333;
font-size: 18px;
border-bottom: 2px solid #2196f3;
padding-bottom: 10px;
}
/* Make the chart widget larger */
.chart {
grid-column: span 2; /* Span 2 columns */
grid-row: span 2; /* Span 2 rows */
}
.chart-area {
height: 200px;
background-color: #f5f5f5;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
color: #999;
}
/* Make the activity list slightly taller */
.activity {
grid-row: span 2;
}
.activity ul {
list-style: none;
padding: 0;
margin: 0;
}
.activity li {
padding: 10px 0;
border-bottom: 1px solid #eee;
}
.activity li:last-child {
border-bottom: none;
}Common Issues and Tips â
Handling Overlapping Items â
When items overlap, remember these points:
- Default stacking order: Later items cover earlier items
- Use z-index: Explicitly control stacking order
- Consider transparency: Use
opacityorrgbacolors to make overlaps visible - Add interactions: Use
:hoverstates to changez-index
Responsive Adjustments â
Individual items can occupy different spaces on different screen sizes:
.featured-item {
grid-column: span 2;
grid-row: span 2;
}
@media (max-width: 768px) {
.featured-item {
grid-column: span 1; /* On small screens, only span 1 column */
grid-row: span 1; /* Only span 1 row */
}
}Named Grid Lines â
You can name grid lines to make code more semantic:
.grid {
display: grid;
grid-template-columns: [sidebar-start] 200px [sidebar-end main-start] 1fr [main-end];
}
.sidebar {
grid-column: sidebar-start / sidebar-end;
}
.main {
grid-column: main-start / main-end;
}This makes code more self-explanatory and easier to maintain.
Summary â
Grid item properties give you precise control over every element. Let's review the core concepts:
Positioning Properties:
grid-column: Controls column position (shorthand forgrid-column-start/grid-column-end)grid-row: Controls row position (shorthand forgrid-row-start/grid-row-end)grid-area: Controls both rows and columns simultaneously (or named areas)
Alignment Properties:
justify-self: Horizontal alignment of individual itemsalign-self: Vertical alignment of individual itemsplace-self: Alignment shorthand
Other:
z-index: Controls stacking order of overlapping items
Key Techniques:
- Use grid line numbers for precise positioning
- Use
spankeyword to specify spanning rows/columns - Use negative indexing to count from the end
- Mix auto-placement with manual positioning
- Use
-selfproperties to override container default alignment
Remember:
- Container properties define overall layout rules
- Item properties make individual elements stand out
- Combine both to create complex and flexible layouts
In the next section, we'll learn about Grid Template Areas, which is a more intuitive and semantic way to define layouts.