- First: What is CSS Grid?
If Flexbox is mainly for arranging things in one direction:
A → B → C
Grid is designed for arranging things in two dimensions:
columns
↓ ↓ ↓
┌─────┬─────┬─────┐
│ A │ B │ C │
├─────┼─────┼─────┤
│ D │ E │ F │
└─────┴─────┴─────┘
↑
rows
So:
Flexbox = one-dimensional layout
Grid = two-dimensional layout
Grid lets you control:
rows
columns
their sizes
where items are placed
how much space each area occupies
- Creating a Grid
HTML:
A
B
C
D
CSS:
.container {
display: grid;
}
That's enough to turn it into a grid container.
But we haven't told the browser how many columns or rows we want.
So we can say:
.container {
display: grid;
grid-template-columns: 200px 200px 200px;
}
Now we have:
┌────────┬────────┬────────┐
│ A │ B │ C │
├────────┼────────┼────────┤
│ D │ │ │
└────────┴────────┴────────┘
Three columns.
- What is a Grid Track? ⭐
This is one of the terms you should know.
A track is basically a row or column in a grid.
So:
grid-template-columns: 200px 300px 100px;
creates 3 column tracks:
Track 1 Track 2 Track 3
↓ ↓ ↓
┌────────┬──────────┬──────┐
│ │ │ │
│ │ │ │
└────────┴──────────┴──────┘
200px 300px 100px
Similarly:
grid-template-rows: 100px 200px;
creates two row tracks:
┌──────────────────────────────┐
│ Row 1 │ 100px
├──────────────────────────────┤
│ Row 2 │ 200px
└──────────────────────────────┘
So remember:
Track = one row OR one column.
- Grid Lines vs Grid Tracks
There's another concept you'll encounter.
Suppose:
grid-template-columns: 200px 200px 200px;
You have:
Line 1 Line 2 Line 3 Line 4
↓ ↓ ↓ ↓
│ 200px │ 200px │ 200px │
│───────────│────────────│─────────────│
There are:
3 column tracks
4 grid lines
Why?
Because lines exist at the edges and between tracks.
This becomes important when you position items.
- grid-template-columns
This controls the columns.
Example:
.container {
display: grid;
grid-template-columns: 200px 300px 100px;
}
Means:
Column 1 = 200px
Column 2 = 300px
Column 3 = 100px
You can also use percentages:
grid-template-columns: 30% 40% 30%;
Or:
grid-template-columns: 1fr 2fr 1fr;
And this brings us to the fr unit.
- What is fr? ⭐⭐⭐
You asked about this earlier too, so let's make it crystal clear.
fr means:
fraction of the available space
Suppose:
grid-template-columns: 1fr 1fr 1fr;
There are 3 equal fractions.
┌──────────┬──────────┬──────────┐
│ │ │ │
│ 1fr │ 1fr │ 1fr │
│ │ │ │
└──────────┴──────────┴──────────┘
So each gets approximately one-third of the available space.
- 1fr 2fr 1fr
This is where fr becomes really useful.
grid-template-columns: 1fr 2fr 1fr;
Total fractions:
1 + 2 + 1 = 4
So:
Column 1 → 1/4
Column 2 → 2/4
Column 3 → 1/4
Visually:
┌────────┬────────────────┬────────┐
│ │ │ │
│ 1fr │ 2fr │ 1fr │
│ │ │ │
└────────┴────────────────┴────────┘
The middle column is twice as wide.
- fr vs % vs px
This is important.
Suppose:
grid-template-columns: 200px 1fr;
This means:
First column gets 200px, second column gets whatever space remains.
Example:
Container = 1000px
┌────────────────────┬─────────────────────────────┐
│ 200px │ 800px │
└────────────────────┴─────────────────────────────┘
This pattern is extremely common.
For example:
.sidebar {
width: 200px;
}
.content {
flex: 1;
}
in Flexbox is conceptually similar to:
grid-template-columns: 200px 1fr;
in Grid.
- fr with gaps
Here's a subtle but useful point.
Suppose:
grid-template-columns: 1fr 1fr 1fr;
gap: 20px;
The browser doesn't give each column one-third of the entire container including the gaps.
The gaps are accounted for first, then the remaining space is divided into fractions.
Conceptually:
Container
│
├── column
├── 20px gap
├── column
├── 20px gap
└── column
So fr is best thought of as:
A share of the remaining available space.
- Grid Rows
You can control rows too:
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 100px 200px;
}
Now:
C1 C2 C3
┌────────┬────────┬────────┐
100px │ │ │ │
├────────┼────────┼────────┤
200px │ │ │ │
└────────┴────────┴────────┘
That's a true 2D layout.
- Grid Areas ⭐⭐⭐
This is one of the coolest parts of Grid.
Suppose you're building a webpage:
┌──────────────────────────────┐
│ Header │
├──────────┬───────────────────┤
│ │ │
│ Sidebar │ Main │
│ │ │
├──────────┴───────────────────┤
│ Footer │
└──────────────────────────────┘
You can name these areas.
.container {
display: grid;
grid-template-columns: 200px 1fr;
grid-template-rows: 80px 1fr 60px;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
Now assign each element:
.header {
grid-area: header;
}
.sidebar {
grid-area: sidebar;
}
.main {
grid-area: main;
}
.footer {
grid-area: footer;
}
That's incredibly readable.
- Understanding grid-template-areas
Look at:
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
Think of it as drawing the page.
┌─────────┬─────────┐
│ header │ header │
├─────────┼─────────┤
│ sidebar │ main │
├─────────┴─────────┤
│ footer │ footer │
└───────────────────┘
Each word represents a named area.
Repeated names mean:
This area spans multiple cells.
For example:
"header header"
means the header occupies two columns.
- Grid Area vs Grid Cell
These terms are easy to confuse.
Grid cell
One individual box.
┌───────┬───────┐
│ cell │ cell │
├───────┼───────┤
│ cell │ cell │
└───────┴───────┘
Grid area
Can contain one or multiple cells.
Example:
┌─────────────────┐
│ HEADER │
└─────────────────┘
The header might span two cells.
So:
Cell = one grid box
Area = one or more cells grouped together
- Explicit Grid vs Implicit Grid ⭐⭐⭐
This sounds scary, but it's actually simple.
Explicit Grid
The grid you explicitly define.
For example:
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 100px 100px;
}
You explicitly created:
3 columns
2 rows
That's your explicit grid.
- What is an implicit grid?
Suppose you say:
grid-template-columns: 1fr 1fr 1fr;
That's 3 columns.
But then you put 10 items inside.
A
B
C
D
E
F
G
H
I
J
You didn't explicitly define enough rows.
The browser says:
"Okay, I'll create more rows automatically."
Those automatically created rows are part of the implicit grid.
Example:
Explicitly defined:
┌─────┬─────┬─────┐
│ A │ B │ C │
├─────┼─────┼─────┤
│ D │ E │ F │
└─────┴─────┴─────┘
Browser automatically adds:
┌─────┬─────┬─────┐
│ G │ H │ I │
├─────┼─────┼─────┤
│ J │ │ │
└─────┴─────┴─────┘
Those additional rows are implicit.
- Controlling implicit rows
You can tell the browser how automatically created rows should behave.
.container {
grid-auto-rows: 100px;
}
Now automatically created rows will be 100px tall.
Similarly:
grid-auto-columns: 200px;
controls automatically generated columns.
- Explicit vs implicit — simple memory
Think:
Explicit
"I told CSS to create this."
grid-template-columns
grid-template-rows
Implicit
"CSS had to create this automatically because my content needed more space."
grid-auto-rows
grid-auto-columns
That's it.
- Another powerful Grid feature: repeat()
Instead of:
grid-template-columns: 1fr 1fr 1fr 1fr;
write:
grid-template-columns: repeat(4, 1fr);
Meaning:
Create 4 columns, each 1fr.
Very common.
- Responsive Grid ⭐
You'll frequently see:
grid-template-columns: repeat(3, 1fr);
But for responsive designs, you'll often see:
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
This basically says:
Create as many columns as can reasonably fit, with each column at least 200px and able to grow up to 1fr.
For example, on a large screen:
┌──────┬──────┬──────┬──────┐
│ Card │ Card │ Card │ Card │
└──────┴──────┴──────┴──────┘
On a smaller screen:
┌──────┬──────┐
│ Card │ Card │
├──────┼──────┤
│ Card │ Card │
└──────┴──────┘
And eventually:
┌──────────┐
│ Card │
├──────────┤
│ Card │
├──────────┤
│ Card │
└──────────┘
This is a very useful modern CSS pattern.
- Grid alignment
Just like Flexbox, Grid has alignment properties.
You'll encounter:
justify-items
align-items
place-items
and:
justify-content
align-content
place-content
Don't worry if this looks confusing initially.
The important distinction is:
*-items
Controls the items inside their grid cells.
*-content
Controls the whole grid inside its container when there is extra space.
For example:
.container {
display: grid;
place-items: center;
}
This is basically:
align-items: center;
justify-items: center;
So each item gets centered inside its grid cell.
- Now the BIG question: Flexbox vs Grid? ⭐⭐⭐⭐⭐
This is what you actually need as a developer.
Don't think:
"Which one is better?"
Neither is better.
Think:
What kind of layout am I building?
- Use Flexbox when layout is primarily ONE-dimensional
Example:
Navbar
Logo Home About Projects Contact
That's basically one row.
Use:
.navbar {
display: flex;
align-items: center;
}
Button content
[ 🔍 Search ]
Flexbox.
Card content
┌─────────────────────┐
│ Title │
│ │
│ Description │
│ │
│ [Button] │
└─────────────────────┘
Flexbox can be great for arranging the content inside the card.
Sidebar + content
┌─────────┬────────────────────┐
│ Sidebar │ Main content │
└─────────┴────────────────────┘
Flexbox works very well.
.layout {
display: flex;
}
- Use Grid when layout is TWO-dimensional
For example:
┌──────────┬──────────┬──────────┐
│ │ │ │
│ A │ B │ C │
├──────────┼──────────┼──────────┤
│ │ │ │
│ D │ E │ F │
└──────────┴──────────┴──────────┘
You care about:
rows
columns
exact placement
Grid is ideal.
- Example: Dashboard
Imagine:
┌──────────────────────────────┐
│ Header │
├───────────┬──────────────────┤
│ Sidebar │ Statistics │
│ ├──────────┬───────┤
│ │ Chart │ Chat │
│ └──────────┴───────┤
│ │
└──────────────────────────────┘
This is a Grid-type layout.
Why?
Because you're thinking in:
rows + columns
rather than simply:
A → B → C
- The easiest comparison Flexbox Grid One-dimensional Two-dimensional Row OR column Rows AND columns Content-focused Layout-focused Great for components Great for page layouts Navigation bars Dashboards Buttons Card grids Toolbars Complex page structures Small UI arrangements Large layout structures
- BUT here's the secret experienced developers know
You don't have to choose only one.
You can use:
Grid for the page + Flexbox inside components.
This is extremely common.
For example:
GRID
┌─────────────────────────────┐
│ Header │
├─────────┬───────────────────┤
│ Sidebar │ Main │
│ │ │
│ │ ┌─────┐ ┌─────┐ │
│ │ │Card │ │Card │ │
│ │ └─────┘ └─────┘ │
└─────────┴───────────────────┘
The outer page:
.page {
display: grid;
}
Then inside each card:
.card {
display: flex;
flex-direction: column;
}
Grid and Flexbox work together beautifully.
- A real developer example
Suppose you're building your portfolio.
You might have:
GRID
┌──────────────────────────────────┐
│ Header │
├─────────┬────────────────────────┤
│ Sidebar │ Hero │
│ ├────────────────────────┤
│ │ Projects │
│ │ │
│ │ ┌────┐ ┌────┐ ┌────┐ │
│ │ │ P1 │ │ P2 │ │ P3 │ │
│ │ └────┘ └────┘ └────┘ │
└─────────┴────────────────────────┘
Grid controls the page structure.
Then each project card:
FLEXBOX
┌─────────────────┐
│ Project title │
│ │
│ Description │
│ │
│ [GitHub] [Demo] │
└─────────────────┘
Flexbox controls the content inside the card.
That's real-world CSS.
- One very important difference
Flexbox asks:
"How should these items distribute themselves?"
Grid asks:
"Where should these items go in this row/column structure?"
For example:
Flexbox
.container {
display: flex;
justify-content: space-between;
}
You're basically saying:
"Here are my items. Distribute them."
Grid
.container {
display: grid;
grid-template-columns: 200px 1fr 200px;
}
You're saying:
"I want this specific column structure."
That's the mental difference.
- Your final mental map 🧠
When you see Grid, think:
GRID
│
├── Rows
│ └── tracks
│
├── Columns
│ └── tracks
│
├── fr
│ └── fraction of available space
│
├── Areas
│ └── named layout regions
│
├── Explicit grid
│ └── grid I define
│
└── Implicit grid
└── grid browser creates automatically
And when choosing:
WHAT AM I LAYOUTING?
│
┌───────────┴───────────┐
│ │
ONE DIRECTION TWO DIMENSIONS
│ │
↓ ↓
FLEXBOX GRID
│ │
navbar / toolbar page / dashboard
button / card rows + columns
small component complex layout
⭐ The rule as a developer is:
Use Flexbox when you're mainly arranging things along one axis.
Use Grid when you're controlling rows and columns together.
And in real projects, use both: Grid for the larger layout, Flexbox for the components inside it.
That is the cleanest way to think about Flexbox vs Grid.
Top comments (0)