CSS Grid
A two-dimensional layout system for creating complex, responsive grid-based designs with precise control over rows, columns, and item placement.
CSS Grid
A two-dimensional layout system for creating complex, responsive grid-based designs with precise control over rows, columns, and item placement.
Overview
CSS Grid Layout provides a powerful way to create grid-based layouts directly in CSS without the need for floats, positioning hacks, or complex frameworks. It divides a container into rows and columns, allowing you to place and align items within the grid cells. Unlike Flexbox (which is one-dimensional), Grid handles both rows and columns simultaneously, making it ideal for complex page layouts.
flowchart TD
subgraph "Grid Container"
A[Define Grid<br/>display: grid] --> B[Set Columns<br/>grid-template-columns]
B --> C[Set Rows<br/>grid-template-rows]
C --> D[Add Gaps<br/>gap]
D --> E[Place Items<br/>grid-column/row]
E --> F[Align Content<br/>justify/align]
end
subgraph "Grid Structure"
G["Grid Line 1"] --- H["Grid Line 2"] --- I["Grid Line 3"]
J[Cell 1] --- K[Cell 2]
L[Track 1] --- M[Track 2]
end
Container Properties
The grid container is the parent element that holds all grid items and defines the overall grid structure.
Key Concepts
- Grid Container - Element with
display: gridthat establishes a grid formatting context - Grid Lines - Horizontal and vertical dividing lines that create the grid structure
- Grid Tracks - Rows and columns between adjacent grid lines
- Grid Cells - Single unit of the grid (intersection of row and column)
- Grid Areas - Rectangular spaces spanning one or more cells
flowchart LR
subgraph "Grid Layout Example"
direction TB
A[Header - spans 3 columns]
B[Sidebar] --- C[Main Content] --- D[Aside]
E[Footer - spans 3 columns]
end
Common Patterns
/* Basic grid container */
.container {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
}
/* Inline grid */
.inline-container {
display: inline-grid;
grid-template-columns: repeat(3, 100px);
}
/* Fixed-width columns */
.fixed-grid {
display: grid;
grid-template-columns: 100px 200px 100px;
}
/* Flexible columns with fr units */
.flex-grid {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
}
/* Mixed units */
.mixed-grid {
display: grid;
grid-template-columns: 200px 1fr 20%;
}
/* Repeat function */
.repeat-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 100px);
}
/* MinMax function */
.minmax-grid {
display: grid;
grid-template-columns: minmax(200px, 1fr) 2fr minmax(100px, 300px);
grid-template-rows: minmax(100px, auto);
}
/* Explicit rows */
.explicit-rows {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: 100px 200px 100px;
}
/* Auto rows for implicit grid */
.auto-rows {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: minmax(100px, auto);
}
/* Auto columns for implicit grid */
.auto-columns {
display: grid;
grid-template-rows: repeat(3, 100px);
grid-auto-columns: 200px;
}
/* Grid flow direction */
.column-flow {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-flow: column;
}
/* Dense packing */
.dense-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-flow: dense;
}
Examples
/* Holy Grail Layout */
.holy-grail {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
.header { grid-column: 1 / -1; }
.nav { grid-column: 1; }
.main { grid-column: 2; }
.aside { grid-column: 3; }
.footer { grid-column: 1 / -1; }
/* Card grid with consistent heights */
.card-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: minmax(200px, auto);
gap: 1.5rem;
}
/* Dashboard layout */
.dashboard {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: 60px 1fr;
height: 100vh;
}
Grid Gaps
Gaps define the spacing between grid tracks (rows and columns), creating gutters between items.
Key Concepts
- gap - Shorthand for setting both row-gap and column-gap
- row-gap - Space between rows
- column-gap - Space between columns
- Gutters only - Gaps only apply between items, not on outer edges
Common Patterns
/* Uniform gap */
.uniform-gap {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
/* Different row and column gaps */
.different-gaps {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px 30px; /* row-gap column-gap */
}
/* Separate gap properties */
.separate-gaps {
display: grid;
grid-template-columns: repeat(4, 1fr);
row-gap: 1rem;
column-gap: 2rem;
}
/* Percentage-based gaps */
.percent-gap {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 2%;
}
/* Responsive gaps with clamp */
.responsive-gap {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: clamp(1rem, 3vw, 2rem);
}
/* No gap (default) */
.no-gap {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 0;
}
Examples
/* Gallery with consistent spacing */
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 1rem;
padding: 1rem;
}
/* Form layout with gaps */
.form-grid {
display: grid;
grid-template-columns: auto 1fr;
gap: 0.75rem 1rem;
align-items: center;
}
/* Magazine-style layout */
.magazine {
display: grid;
grid-template-columns: repeat(6, 1fr);
gap: 1.5rem;
}
.magazine .featured {
grid-column: span 4;
grid-row: span 2;
}
.magazine .article {
grid-column: span 2;
}
Item Placement
Grid items can be placed explicitly using line numbers, names, or span values, giving precise control over their position.
Key Concepts
- grid-column - Shorthand for grid-column-start and grid-column-end
- grid-row - Shorthand for grid-row-start and grid-row-end
- grid-area - Shorthand for row-start, column-start, row-end, column-end
- Line numbers - Positive count from start, negative count from end
- span - Extend item across multiple tracks
flowchart TD
subgraph "Grid Line Numbering"
direction LR
A["Line 1"] --> B["Line 2"] --> C["Line 3"] --> D["Line 4/-1"]
end
subgraph "Item Placement"
E["grid-column: 1 / 3<br/>Spans columns 1-2"]
F["grid-column: span 2<br/>Spans 2 columns"]
G["grid-column: 2 / -1<br/>From line 2 to end"]
end
Common Patterns
/* Placement by line numbers */
.item-lines {
grid-column: 1 / 3; /* Start line 1, end line 3 */
grid-row: 2 / 4; /* Start line 2, end line 4 */
}
/* Placement using span */
.item-span {
grid-column: span 2; /* Span 2 columns */
grid-row: span 3; /* Span 3 rows */
}
/* Placement from end */
.item-from-end {
grid-column: 1 / -1; /* Full width (line 1 to last line) */
grid-row: -2 / -1; /* Last row */
}
/* Mixed start and span */
.item-mixed {
grid-column: 2 / span 2; /* Start at line 2, span 2 */
grid-row: 1 / span 3; /* Start at line 1, span 3 */
}
/* Using grid-area shorthand */
.item-area {
/* row-start / column-start / row-end / column-end */
grid-area: 1 / 2 / 3 / 4;
}
/* Auto-placement hints */
.item-auto {
grid-column: auto / span 2; /* Auto-place, span 2 columns */
}
/* Full-width item */
.full-width {
grid-column: 1 / -1;
}
/* Full-height item */
.full-height {
grid-row: 1 / -1;
}
/* Overlapping items */
.item-overlap-1 {
grid-column: 1 / 3;
grid-row: 1 / 3;
z-index: 1;
}
.item-overlap-2 {
grid-column: 2 / 4;
grid-row: 2 / 4;
z-index: 2;
}
Examples
/* Featured content layout */
.featured-layout {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 200px);
gap: 1rem;
}
.featured {
grid-column: 1 / 3;
grid-row: 1 / 3;
}
.secondary-1 {
grid-column: 3 / 4;
grid-row: 1 / 2;
}
.secondary-2 {
grid-column: 4 / 5;
grid-row: 1 / 2;
}
.tertiary {
grid-column: 3 / 5;
grid-row: 2 / 4;
}
/* Bento box layout */
.bento {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 100px;
gap: 0.5rem;
}
.bento .large {
grid-column: span 2;
grid-row: span 2;
}
.bento .tall {
grid-row: span 2;
}
.bento .wide {
grid-column: span 2;
}
Alignment
CSS Grid provides powerful alignment properties for both the grid container and individual items.
Key Concepts
- justify-items - Align items horizontally within their grid area
- align-items - Align items vertically within their grid area
- place-items - Shorthand for align-items and justify-items
- justify-content - Distribute grid within container horizontally
- align-content - Distribute grid within container vertically
- place-content - Shorthand for align-content and justify-content
- justify-self - Override justify-items for individual item
- align-self - Override align-items for individual item
- place-self - Shorthand for align-self and justify-self
Common Patterns
/* Container alignment - items within cells */
.align-items-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
justify-items: center; /* Horizontal alignment */
align-items: center; /* Vertical alignment */
}
/* Using place-items shorthand */
.centre-items {
display: grid;
grid-template-columns: repeat(3, 200px);
place-items: center; /* Both centre */
}
/* Different alignments */
.mixed-align {
display: grid;
grid-template-columns: repeat(3, 200px);
place-items: start end; /* align-items: start; justify-items: end */
}
/* Container content distribution */
.distribute-grid {
display: grid;
grid-template-columns: repeat(3, 200px);
height: 600px;
justify-content: space-between; /* Horizontal distribution */
align-content: space-around; /* Vertical distribution */
}
/* Using place-content shorthand */
.centre-grid {
display: grid;
grid-template-columns: repeat(3, 200px);
grid-template-rows: repeat(2, 100px);
height: 500px;
place-content: center; /* Centre the entire grid */
}
/* Individual item alignment */
.grid-item-aligned {
justify-self: end; /* Align this item to end horizontally */
align-self: start; /* Align this item to start vertically */
}
/* Shorthand for individual item */
.grid-item-placed {
place-self: center end; /* align-self: center; justify-self: end */
}
/* Stretch (default) */
.stretch-items {
display: grid;
grid-template-columns: repeat(3, 1fr);
align-items: stretch; /* Items fill cell height */
justify-items: stretch; /* Items fill cell width */
}
Examples
/* Centred card layout */
.centred-cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 300px));
gap: 2rem;
justify-content: center; /* Centre cards when they don't fill width */
padding: 2rem;
}
/* Navigation with aligned items */
.nav-grid {
display: grid;
grid-template-columns: auto 1fr auto;
align-items: center;
gap: 1rem;
padding: 1rem;
}
.nav-logo {
justify-self: start;
}
.nav-links {
justify-self: center;
}
.nav-actions {
justify-self: end;
}
/* Footer with distributed columns */
.footer-grid {
display: grid;
grid-template-columns: repeat(4, auto);
justify-content: space-between;
align-items: start;
padding: 3rem;
}
/* Full-page centred content */
.full-page-centre {
display: grid;
place-content: center;
min-height: 100vh;
}
Auto-fit and Auto-fill
These functions create responsive grids that automatically adjust the number of columns based on available space.
Key Concepts
- auto-fill - Creates as many tracks as will fit, even if empty
- auto-fit - Creates tracks to fit items, collapsing empty tracks
- Responsive without media queries - Grid automatically adjusts
- minmax() combination - Typically used with auto-fill/fit for flexible sizing
flowchart TD
subgraph "auto-fill vs auto-fit"
A["auto-fill:<br/>Creates empty tracks to fill space"]
B["auto-fit:<br/>Collapses empty tracks, items expand"]
end
Common Patterns
/* Auto-fill - keeps empty tracks */
.auto-fill-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 1rem;
}
/* Auto-fit - collapses empty tracks */
.auto-fit-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
}
/* Fixed minimum width */
.fixed-min {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
}
/* Flexible minimum with clamp */
.flex-min {
display: grid;
grid-template-columns: repeat(
auto-fit,
minmax(clamp(200px, 30%, 400px), 1fr)
);
gap: 1rem;
}
/* Auto-fill with fixed-size items */
.fixed-auto-fill {
display: grid;
grid-template-columns: repeat(auto-fill, 150px);
justify-content: center;
gap: 1rem;
}
/* Minimum columns with auto-fit */
.min-columns {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr));
gap: 1rem;
}
Examples
/* Responsive card grid */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 1.5rem;
padding: 1rem;
}
/* Image gallery */
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
grid-auto-rows: 150px;
gap: 0.5rem;
}
.gallery img {
width: 100%;
height: 100%;
object-fit: cover;
}
/* Product listing */
.products {
display: grid;
grid-template-columns: repeat(
auto-fit,
minmax(min(100%, 220px), 1fr)
);
gap: 2rem;
}
/* Feature comparison */
.comparison {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 350px));
justify-content: center;
gap: 1rem;
}
Fractional Units (fr)
The fr unit represents a fraction of the available space in the grid container.
Key Concepts
- fr unit - Distributes available space proportionally
- Calculated after fixed sizes - fr units divide remaining space
- Proportional distribution - 1fr 2fr gives 1:2 ratio
- Minimum size respect - Content can prevent tracks from shrinking
Common Patterns
/* Equal columns */
.equal-fr {
display: grid;
grid-template-columns: 1fr 1fr 1fr; /* Three equal columns */
}
/* Proportional columns */
.proportional-fr {
display: grid;
grid-template-columns: 1fr 2fr 1fr; /* 1:2:1 ratio */
}
/* Mixed with fixed values */
.mixed-fr {
display: grid;
grid-template-columns: 200px 1fr 1fr; /* Fixed + flexible */
}
/* Complex proportions */
.complex-fr {
display: grid;
grid-template-columns: 1fr 3fr 2fr; /* 1:3:2 ratio */
}
/* Fr with minmax */
.fr-minmax {
display: grid;
grid-template-columns: minmax(200px, 1fr) 2fr;
}
/* All fr rows */
.fr-rows {
display: grid;
grid-template-rows: 1fr 3fr 1fr;
height: 100vh;
}
/* Repeat with fr */
.repeat-fr {
display: grid;
grid-template-columns: repeat(4, 1fr);
}
Examples
/* Admin dashboard layout */
.admin-layout {
display: grid;
grid-template-columns: 250px 1fr; /* Fixed sidebar, flexible main */
grid-template-rows: auto 1fr auto;
height: 100vh;
}
.admin-header {
grid-column: 1 / -1;
}
.admin-sidebar {
grid-row: 2;
}
.admin-main {
grid-column: 2;
overflow-y: auto;
}
.admin-footer {
grid-column: 1 / -1;
}
/* Three-column article */
.article-layout {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
gap: 2rem;
max-width: 1200px;
margin: 0 auto;
}
.article-toc {
position: sticky;
top: 1rem;
}
.article-content {
/* Main content in middle */
}
.article-related {
/* Related articles on right */
}
/* Responsive sidebar */
.responsive-layout {
display: grid;
grid-template-columns: 1fr;
gap: 1rem;
}
@media (min-width: 768px) {
.responsive-layout {
grid-template-columns: 1fr 3fr;
}
}
Named Grid Lines and Areas
Named lines and areas make grid layouts more readable and maintainable.
Key Concepts
- Named lines - Custom names for grid lines in square brackets
- Named areas - Define layout visually using grid-template-areas
- Implicit line names - Areas create
-startand-endlines automatically - Readable layouts - Self-documenting grid structures
Common Patterns
/* Named grid lines */
.named-lines {
display: grid;
grid-template-columns:
[sidebar-start] 200px
[sidebar-end main-start] 1fr
[main-end aside-start] 200px
[aside-end];
grid-template-rows:
[header-start] auto
[header-end content-start] 1fr
[content-end footer-start] auto
[footer-end];
}
.header {
grid-column: sidebar-start / aside-end;
grid-row: header-start / header-end;
}
.sidebar {
grid-column: sidebar-start / sidebar-end;
grid-row: content-start / content-end;
}
.main {
grid-column: main-start / main-end;
grid-row: content-start / content-end;
}
/* Named grid areas */
.named-areas {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
min-height: 100vh;
}
.header { grid-area: header; }
.nav { grid-area: nav; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
/* Empty cells with dot notation */
.areas-with-gaps {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 100px);
grid-template-areas:
"header header header header"
"sidebar main main ."
"footer footer footer footer";
}
/* Repeated area names for spanning */
.spanning-areas {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-areas:
"featured featured sidebar"
"featured featured sidebar"
"article1 article2 article3";
}
/* Using implicit line names from areas */
.implicit-lines {
display: grid;
grid-template-areas:
"header"
"main"
"footer";
}
.overlay {
/* Areas create -start and -end lines */
grid-column: header-start / header-end;
grid-row: header-start / main-end;
}
Examples
/* Complete page layout with named areas */
.page-layout {
display: grid;
grid-template-columns: minmax(150px, 200px) 1fr minmax(150px, 250px);
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"nav content aside"
"nav footer footer";
min-height: 100vh;
gap: 1rem;
}
.site-header { grid-area: header; }
.site-nav { grid-area: nav; }
.site-content { grid-area: content; }
.site-aside { grid-area: aside; }
.site-footer { grid-area: footer; }
/* Responsive areas with media queries */
.responsive-areas {
display: grid;
grid-template-columns: 1fr;
grid-template-areas:
"header"
"nav"
"main"
"aside"
"footer";
gap: 1rem;
}
@media (min-width: 768px) {
.responsive-areas {
grid-template-columns: 200px 1fr;
grid-template-areas:
"header header"
"nav main"
"nav aside"
"footer footer";
}
}
@media (min-width: 1024px) {
.responsive-areas {
grid-template-columns: 200px 1fr 200px;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
}
}
/* Dashboard with named lines */
.dashboard {
display: grid;
grid-template-columns:
[full-start sidebar-start] minmax(200px, 250px)
[sidebar-end content-start] 1fr
[content-end full-end];
grid-template-rows:
[full-start header-start] 60px
[header-end main-start] 1fr
[main-end full-end];
}
.dashboard-header {
grid-column: full-start / full-end;
grid-row: header-start / header-end;
}
.dashboard-sidebar {
grid-column: sidebar-start / sidebar-end;
grid-row: main-start / main-end;
}
.dashboard-content {
grid-column: content-start / content-end;
grid-row: main-start / main-end;
}
Responsive Grid Patterns
Grid layouts that adapt to different screen sizes using various techniques.
Key Concepts
- Intrinsic responsiveness - auto-fit/fill with minmax
- Media queries - Change grid structure at breakpoints
- Container queries - Adapt based on container size
- Mobile-first - Start with single column, add complexity
Common Patterns
/* Intrinsically responsive - no media queries */
.intrinsic-responsive {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
gap: 1rem;
}
/* Mobile-first with breakpoints */
.mobile-first {
display: grid;
grid-template-columns: 1fr;
gap: 1rem;
}
@media (min-width: 640px) {
.mobile-first {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 1024px) {
.mobile-first {
grid-template-columns: repeat(4, 1fr);
}
}
/* Responsive sidebar layout */
.sidebar-layout {
display: grid;
grid-template-columns: 1fr;
gap: 1rem;
}
@media (min-width: 768px) {
.sidebar-layout {
grid-template-columns: 250px 1fr;
}
}
/* Collapsible columns */
.collapsible {
display: grid;
grid-template-columns: 1fr;
gap: 1rem;
}
@media (min-width: 600px) {
.collapsible {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 900px) {
.collapsible {
grid-template-columns: repeat(3, 1fr);
}
}
/* RAM technique (Repeat, Auto, Minmax) */
.ram-pattern {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1rem;
}
/* Responsive with container queries */
.container-query-grid {
container-type: inline-size;
}
.container-query-grid .items {
display: grid;
grid-template-columns: 1fr;
gap: 1rem;
}
@container (min-width: 400px) {
.container-query-grid .items {
grid-template-columns: repeat(2, 1fr);
}
}
@container (min-width: 700px) {
.container-query-grid .items {
grid-template-columns: repeat(3, 1fr);
}
}
Examples
/* Complete responsive page */
.responsive-page {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header"
"main"
"footer";
min-height: 100vh;
}
.page-header { grid-area: header; }
.page-main { grid-area: main; }
.page-footer { grid-area: footer; }
@media (min-width: 768px) {
.responsive-page {
grid-template-columns: 200px 1fr;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
}
@media (min-width: 1200px) {
.responsive-page {
grid-template-columns: 250px 1fr 250px;
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
}
}
/* Responsive masonry-like effect */
.masonry-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-auto-rows: 10px;
gap: 1rem;
}
.masonry-item {
/* Height set dynamically via JavaScript */
grid-row-end: span var(--row-span, 20);
}
/* E-commerce product grid */
.product-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 1.5rem;
padding: 1rem;
}
@media (min-width: 1200px) {
.product-grid {
grid-template-columns: repeat(4, 1fr);
}
}
/* Blog post layout */
.blog-layout {
display: grid;
grid-template-columns: 1fr;
gap: 2rem;
max-width: 1200px;
margin: 0 auto;
padding: 1rem;
}
@media (min-width: 900px) {
.blog-layout {
grid-template-columns: 1fr 300px;
}
}
.blog-content {
min-width: 0; /* Prevent overflow */
}
.blog-sidebar {
/* Sidebar content */
}
Quick Reference
Container Properties
| Property | Values | Description |
|---|---|---|
display |
grid, inline-grid |
Establishes grid container |
grid-template-columns |
lengths, %, fr, auto, minmax(), repeat() | Define column tracks |
grid-template-rows |
lengths, %, fr, auto, minmax(), repeat() | Define row tracks |
grid-template-areas |
named area strings | Define layout with names |
gap |
length | Space between tracks |
row-gap |
length | Space between rows |
column-gap |
length | Space between columns |
grid-auto-rows |
length, minmax() | Size of implicit rows |
grid-auto-columns |
length, minmax() | Size of implicit columns |
grid-auto-flow |
row, column, dense |
Auto-placement algorithm |
Item Properties
| Property | Values | Description |
|---|---|---|
grid-column |
line numbers, names, span | Column placement |
grid-row |
line numbers, names, span | Row placement |
grid-area |
area name or line values | Shorthand placement |
justify-self |
start, end, center, stretch |
Horizontal alignment |
align-self |
start, end, center, stretch |
Vertical alignment |
place-self |
align-self justify-self | Shorthand alignment |
Alignment Properties
| Property | Values | Description |
|---|---|---|
justify-items |
start, end, center, stretch |
Align all items horizontally |
align-items |
start, end, center, stretch |
Align all items vertically |
place-items |
align-items justify-items | Shorthand for both |
justify-content |
start, end, center, stretch, space-between, space-around, space-evenly |
Distribute grid horizontally |
align-content |
start, end, center, stretch, space-between, space-around, space-evenly |
Distribute grid vertically |
place-content |
align-content justify-content | Shorthand for both |
Functions
| Function | Example | Description |
|---|---|---|
repeat() |
repeat(3, 1fr) |
Repeat track pattern |
minmax() |
minmax(100px, 1fr) |
Set min and max size |
auto-fill |
repeat(auto-fill, 200px) |
Fill with tracks |
auto-fit |
repeat(auto-fit, 200px) |
Fit and collapse empty |
min() |
min(100%, 300px) |
Use smallest value |
max() |
max(200px, 50%) |
Use largest value |
clamp() |
clamp(200px, 50%, 400px) |
Constrain between values |
Common Issues and Solutions
| Issue | Cause | Solution |
|---|---|---|
| Items overflow container | Fixed track sizes exceed container | Use fr units, minmax(), or auto |
| Grid items not equal height | Default alignment is stretch | Ensure align-items: stretch (default) |
| Empty tracks taking space | Using auto-fill |
Switch to auto-fit to collapse empty tracks |
| Content overflows grid cell | Content wider than column | Add min-width: 0 or overflow: hidden to items |
1fr not working as expected |
Content establishes minimum | Use minmax(0, 1fr) instead of 1fr |
| Grid doesn't fill height | Container has no height | Set explicit height or min-height: 100vh |
| Items not aligning | Confusion between item and content alignment | Use justify-items/align-items for items within cells |
| Overlapping items | Items placed in same cells | Use z-index to control stacking order |
| Gap creates overflow | Gap added to total width | Gaps are included in track sizing; check container width |
| Named areas not working | Typo or mismatch | Ensure area names match exactly in template and items |
Debugging Tips
/* Visualise grid structure */
.debug-grid {
outline: 2px solid red;
}
.debug-grid > * {
outline: 1px solid blue;
}
/* Firefox DevTools */
/* Enable grid overlay in Inspector > Layout panel */
/* Chrome DevTools */
/* Click grid badge in Elements panel */
/* Show grid lines */
.grid-visualise {
background:
repeating-linear-gradient(
to right,
transparent,
transparent calc(100% / 3 - 10px),
rgba(0, 0, 255, 0.1) calc(100% / 3 - 10px),
rgba(0, 0, 255, 0.1) calc(100% / 3)
);
}
/* Common fix for content overflow */
.grid-item {
min-width: 0; /* Allow shrinking below content size */
overflow: hidden; /* Clip overflowing content */
}
/* Fix for image sizing in grid */
.grid-item img {
width: 100%;
height: 100%;
object-fit: cover;
}
/* Ensure fr units work correctly */
.container {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
}
Related Topics
The following topics would complement this CSS Grid cheatsheet:
- CSS Flexbox - One-dimensional layout system; use alongside Grid for component-level layouts within grid items
- CSS Container Queries - Style elements based on container size rather than viewport; works well with Grid for component-based responsive design
- CSS Custom Properties (Variables) - Define reusable values for grid tracks, gaps, and other properties; enable dynamic grid adjustments
- Responsive Design Patterns - Media queries, fluid typography, and other techniques that complement Grid-based layouts
- CSS Subgrid - Allow nested grids to participate in the parent grid's track sizing; useful for complex nested layouts
- CSS Aspect Ratio - Maintain proportions for grid items; particularly useful for image galleries and card layouts