Flexbox and Grid are both modern CSS layout systems, both are supported in every current browser, and both can often produce the same result. So why do we have two? Because they think about layout differently. Once you understand that difference, choosing between them takes a few seconds.
This post on Flexbox vs Grid assumes you know the basics of each. If not, start with the CSS Flexbox and CSS Grid lessons and come back.
The one-line difference
Flexbox is one-dimensional, content-first. It arranges items along a single line (a row or a column) and lets the size of the content decide how space is shared.
Grid is two-dimensional, layout-first. You define rows and columns on the parent, and items are placed into that structure. The container decides the sizes; content fits into them.
Flexbox can wrap onto multiple lines, but each line is laid out on its own – items in line two do not line up with items in line one. Grid keeps columns aligned across every row. That single fact explains most of the “which one?” decisions.
Flexbox vs Grid: comparison table
| Question | Flexbox | Grid |
|---|---|---|
| Dimensions | One axis at a time | Rows and columns together |
| Who controls size? | Mostly the items (content-out) | Mostly the container (layout-in) |
| Alignment across wrapped lines | No – each line is independent | Yes – columns stay aligned |
| Overlapping items | Needs positioning tricks | Easy – place items in the same cell |
| Typical uses | Navbars, button groups, centring, media objects | Page layouts, card galleries, dashboards, forms |
| Spacing between items | gap | gap |
See the difference with one demo
The demo below shows the same six cards twice. The top version uses Flexbox with wrapping; the bottom uses Grid. Resize the preview and watch the last row. With Flexbox, leftover cards stretch to fill the line. With Grid, they keep the column width.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Flexbox vs Grid demo</title>
<style>
body { font-family: system-ui, sans-serif; margin: 16px; background: #f6f7fb; }
h2 { font-size: 1rem; margin: 20px 0 8px; }
.card { background: #fff; border: 1px solid #d6d9e4; border-radius: 8px; padding: 16px; }
.flex { display: flex; flex-wrap: wrap; gap: 12px; }
.flex .card { flex: 1 1 180px; }
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 12px; }
</style>
</head>
<body>
<h2>Flexbox (flex-wrap)</h2>
<div class="flex">
<div class="card">Chennai</div><div class="card">Madurai</div><div class="card">Coimbatore</div>
<div class="card">Kochi</div><div class="card">Mysuru</div><div class="card">Puducherry</div>
</div>
<h2>Grid (auto-fill + minmax)</h2>
<div class="grid">
<div class="card">Chennai</div><div class="card">Madurai</div><div class="card">Coimbatore</div>
<div class="card">Kochi</div><div class="card">Mysuru</div><div class="card">Puducherry</div>
</div>
</body>
</html>Neither result is “wrong”. If you want the last items to grow and fill the row (tags, chips, filter buttons), Flexbox is right. If you want a tidy gallery where every card is the same width, Grid is right.
When Flexbox is the better choice
1. Navigation bars and toolbars
A header with a logo on the left and links on the right is a single row whose items have different natural widths. Flexbox handles it in three lines.
.site-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
}2. Centring something
display: flex; justify-content: center; align-items: center; centres a child both ways. Grid can do it too with place-items: center, so use whichever reads better to you.
3. Components whose size depends on content
Button groups, tag lists, a profile photo next to some text, an input with a button attached – these are content-driven. Flexbox lets each item take the space it needs and share the rest with flex-grow.
When Grid is the better choice
1. Whole page layouts
Header, sidebar, main content and footer form a two-dimensional structure. grid-template-areas makes the layout readable, and changing it for mobile is a single media query.
.page {
display: grid;
grid-template-columns: 1fr;
grid-template-areas:
"header"
"main"
"sidebar"
"footer";
gap: 1rem;
}
@media (min-width: 768px) {
.page {
grid-template-columns: 240px 1fr;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
}
.page > header { grid-area: header; }
.page > main { grid-area: main; }
.page > aside { grid-area: sidebar; }
.page > footer { grid-area: footer; }2. Card galleries and product listings
repeat(auto-fill, minmax(180px, 1fr)) creates as many equal columns as fit, with no media queries at all. This is one of the most useful single lines in modern CSS.
3. Forms with labels and fields in columns
A two-column form where every label lines up with every input is a grid problem. Flexbox would align each row separately, and long labels would push fields out of line.
4. Overlapping elements
Text on top of an image, a badge on a card corner – put both items in the same grid cell with grid-area: 1 / 1 instead of using absolute positioning.
Use both together – that is normal
Real interfaces mix the two. A common pattern: Grid for the page and the card gallery, Flexbox inside each card to push the “Add to cart” button to the bottom.
.products {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: 1.5rem;
}
.product {
display: flex;
flex-direction: column;
}
.product .buy {
margin-top: auto; /* pushes the button to the bottom of every card */
}Also look at subgrid, now supported in all major browsers. It lets a child grid reuse its parent’s tracks, so headings, text and buttons inside separate cards can line up with each other.
Alignment works the same way in both
A nice side effect of learning one system is that you have half-learned the other. Both use the Box Alignment properties. justify-content and align-items behave the same way in principle; the difference is what they align against. In Flexbox, justify-content works along the main axis (the direction of flex-direction). In Grid, it works along the inline axis – normally horizontal for English text – and moves the whole set of tracks when they are smaller than the container.
| Property | In Flexbox | In Grid |
|---|---|---|
justify-content | Spreads items along the main axis | Positions the column tracks inside the container |
align-items | Aligns items on the cross axis | Aligns items inside their row track |
justify-items | Ignored | Aligns items inside their column track |
align-self | Overrides one item | Overrides one item |
place-items | Not useful | Shorthand for align-items and justify-items |
Common layout jobs and the usual choice
Here is how the Flexbox vs Grid decision plays out on a typical Indian business website, such as a hotel booking site or a college homepage. These are starting points, not rules.
- Top header with logo, menu and a “Book now” button – Flexbox.
- Hero section with text left, image right – either; Grid if you want the columns to be exact fractions, Flexbox if the image should keep its natural width.
- Room or course cards – Grid with
auto-fillandminmax(). - Price, rating and button inside a card – Flexbox.
- Footer with four link columns – Grid, collapsing to one or two columns on phones.
- Filter chips such as “AC”, “Sea view”, “Breakfast” – Flexbox with
flex-wrap. - Admin dashboard with widgets of different sizes – Grid, using
grid-column: span 2for wide widgets.
A quick decision checklist
- Do I need items to line up in both rows and columns? → Grid.
- Is it a single row or column where content size should drive the layout? → Flexbox.
- Am I defining the overall page structure? → Grid.
- Am I arranging a few items inside a component? → Usually Flexbox.
- Do items need to overlap? → Grid.
- Still unsure? Build it with one; if you start adding fixed widths to force alignment, switch to the other.
Watch out: A common mistake is using Flexbox with width: 33.33% and negative margins to fake a grid. That was necessary years ago. Today display: grid plus gap is shorter and handles spacing correctly.
Accessibility note
Both Flexbox and Grid let you change visual order with order or grid placement. Screen readers and keyboard tab order still follow the HTML source order. Keep the source order logical and use visual reordering only for small adjustments. More on this in Web Accessibility Basics.
Next, make your layouts adapt to screen sizes with Responsive Design Breakpoints, or compare with a framework approach in Bootstrap 5 Grid Explained.
Frequently asked questions
Is CSS Grid replacing Flexbox?
No. They solve different problems and are designed to work together. Grid is for two-dimensional layout; Flexbox is for distributing items along one axis.
Which is better for performance?
For normal websites the difference is not something you need to worry about. Choose the tool that expresses the layout most clearly.
Can I use gap with Flexbox?
Yes. The gap property works with Flexbox in all current major browsers, so you no longer need margin hacks between flex items.
Should beginners learn Flexbox or Grid first?
Flexbox first is a common path because navbars and simple components appear early. Learn Grid soon after – page layouts are much easier with it.
Does Bootstrap use Flexbox or Grid?
Bootstrap 5’s main row-and-column grid is built on Flexbox. It also offers an optional CSS Grid mode that you can enable through Sass.


