Key Takeaways
- The CSS box model describes content, padding, borders, and margins. It applies when you use Flexbox or Grid; it isn't a competing layout system.
- Use Flexbox to distribute and align items along one main axis. Wrapped lines distribute their space independently.
- Use Grid when items need shared relationships across rows and columns. Grid tracks can be flexible, not just fixed-width.
- Keep ordinary document content in normal flow, and combine layout methods where their responsibilities differ.
CSS Grid vs Flexbox is a choice between layout models, not a choice about whether to use the box model. Choose Flexbox for one-axis alignment and distribution, Grid for shared row-and-column relationships, and normal flow for ordinary document content. These tools are complementary.
CSS Layout Methods: A Practical Decision Rule
| What you're arranging | Start with | Why |
|---|---|---|
| Headings, paragraphs, and ordinary article content | Normal flow | Block and inline layout already handle document content. |
| A toolbar, navigation list, or group of actions | Flexbox | Items share space along a main axis. |
| Cards aligned across rows, or related page regions | Grid | Items participate in shared row and column tracks. |
| Text wrapping around an image or pull quote | Float | Surrounding text can wrap around the floated box. |
Choose by the relationships between items, not by the component's size. A small component can need two-dimensional alignment; a large page region can need only a single stack or row.
CSS Box Model: Sizing, Not a Competing Layout System
The box model describes four nested areas: content, padding, border, and margin. Padding sits between content and border; margin sits outside the border. Those areas still exist when the box participates in Flexbox or Grid. Calling the box model an older alternative to those layout systems is incorrect.
BOX MODEL: the parts of a box
margin [ border [ padding [ content ] ] ]
FLEXBOX: relationships along a main axis
[A] [B] [C] -->
[D] [E] another independently sized line
GRID: shared tracks across both axes
column 1 column 2
row 1 [ A ] [ B ]
row 2 [ C ] [ D ]Content-box vs Border-box
The initial value of box-sizing is content-box: a declared width excludes padding and borders. With border-box, the declared width includes both. Neither value includes margins. Browser styles already use border-box for some elements, so set your project's convention explicitly.
Put this HTML in a page body and the CSS in its stylesheet:
<div class="box">A predictable border-box width</div>*,
*::before,
*::after {
box-sizing: border-box;
}
.box {
width: 240px;
padding: 16px;
border: 2px solid #555;
}This box's border-box width is 240px, leaving 204px for content. Change its box-sizing to content-box and the border-box width becomes 276px: 240px of content, 32px of horizontal padding, and 4px of borders.
Advantages and Limitations
A consistent sizing convention makes dimensions easier to reason about. But border-box doesn't distribute siblings, align columns, or prevent every kind of overflow: those are separate layout and content-sizing concerns. Use the box model to understand a box's dimensions, then choose how neighboring boxes relate.
Where Normal Flow, Floats, and Clear Fit
Normal flow lays out block and inline content without opting into Flexbox or Grid. Start there for prose instead of turning every wrapper into a layout container. Floats remain useful for text wrapping, but their historical use for multicolumn page layouts has been superseded by more suitable tools. The clear property controls whether a box must move below preceding floats on the specified side.
CSS Flexbox: Arrange Items Along One Axis
Flexbox works around a main axis and a perpendicular cross axis. flex-direction establishes the main direction; justify-content controls main-axis alignment, while align-items controls cross-axis alignment. These aren't permanently horizontal and vertical: changing the direction changes how the axes map to the page.
Advantages
Flexbox is a good starting point for navigation bars, toolbars, and action groups because it can distribute available space while accommodating different item sizes. Items can grow or shrink from a starting size instead of requiring you to assign every item an exact width.
A Wrapping Card Collection
The following examples use the border-box reset above. Use this same HTML and shared CSS for both layouts; start with the flex class, then change it to grid for the Grid example.
<ul class="cards flex">
<li class="card">Account settings</li>
<li class="card">Billing and invoices</li>
<li class="card">Team members</li>
<li class="card">Notifications</li>
<li class="card">Security preferences</li>
</ul>/* Shared styles for both examples. */
.cards {
list-style: none;
margin: 0;
padding: 0;
gap: 1rem;
}
.card {
min-width: 0;
padding: 1rem;
border: 1px solid #777;
overflow-wrap: anywhere;
}
/* Flexbox layout. */
.cards.flex {
display: flex;
flex-wrap: wrap;
}
.cards.flex > .card {
flex: 1 1 16rem;
}flex: 1 1 16rem sets the grow factor, shrink factor, and starting main-axis size, respectively. flex-wrap: wrap permits additional lines. Resize the container until three cards fit on the first line: the remaining two grow to fill their own line.
Limitations
Wrapping doesn't make Flexbox a shared two-dimensional grid. Each line distributes space independently, so items on different lines don't automatically share column widths. If you're calculating widths primarily to align one wrapped row with another, Grid usually expresses that requirement more directly.
CSS Grid: Coordinate Rows and Columns
Grid defines tracks—the spaces between adjacent grid lines—across rows and columns. Items can occupy or span those tracks, and tracks can use fixed, flexible, or content-based sizing. Two-dimensional doesn't mean rigid or desktop-only.
Advantages
Grid makes shared alignment explicit. For example, grid-template-columns: repeat(3, minmax(0, 1fr)) defines three equal flexible columns with a zero minimum. Unlike independently sized Flexbox lines, subsequent rows use those same column tracks.
Responsive Tracks Without a Column-count Breakpoint
Change the card list's class to cards grid and add this rule alongside the shared styles:
.cards.grid {
display: grid;
grid-template-columns:
repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
}The browser chooses how many columns fit in the container. When three columns fit, the last two cards remain aligned with the first two columns rather than stretching across their own row. Here's how the sizing expression works:
repeat()repeats the track definition.auto-fitdetermines the repetition count from the available space, then collapses empty repeated tracks.minmax()provides a minimum and maximum track size.min(100%, 16rem)lets the minimum fall below 16rem when the container is narrower, avoiding a mandatory 16rem-wide track.1frlets the columns share remaining space equally in this example.
These behaviors come from Grid's repeat notation, track sizing, and the min() function. The similar auto-fill keyword retains empty repeated tracks instead of collapsing them; that difference matters when there are fewer items than available columns.
Limitations
Grid can remove explicit column-count breakpoints, but it doesn't eliminate responsive design decisions. You may still need media queries to move a sidebar, change a navigation arrangement, or adjust spacing at a meaningful threshold. For that broader work, see our responsive web design tips.
The learning cost is understanding tracks, placement, and sizing—not simply memorizing more properties. If all you need is a row of content-sized buttons, defining a grid may add structure you don't need.
Combine a Grid Parent With Flexbox Components
A parent Grid can position page regions while a child Flexbox aligns controls inside one region. The header below is both a grid item in the page and a flex container for its own children. Those responsibilities don't conflict.
<div class="page">
<header class="toolbar">
<strong>Catalog</strong>
<a href="#results">Jump to results</a>
</header>
<aside class="sidebar">Category information</aside>
<main class="content" id="results">
<h2>Results</h2>
<p>Your catalog content goes here.</p>
</main>
</div>.page {
display: grid;
grid-template-columns: minmax(0, 1fr);
grid-template-areas:
"header"
"sidebar"
"content";
gap: 1rem;
}
.toolbar {
grid-area: header;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
gap: 1rem;
}
.sidebar {
grid-area: sidebar;
}
.content {
grid-area: content;
min-width: 0;
}
@media (min-width: 48rem) {
.page {
grid-template-columns: 14rem minmax(0, 1fr);
grid-template-areas:
"header header"
"sidebar content";
}
}The initial layout stacks the regions. At a viewport width of 48rem or more, the header spans both columns and the sidebar sits beside the content. The breakpoint is an example design choice, not a Grid requirement; the toolbar can wrap independently.
Keep application structure separate from these CSS decisions. If you're working in that framework, our Next.js layout examples provide a related application-level perspective.
CSS Grid vs Bootstrap's Grid System
CSS Grid is a browser layout capability. Bootstrap's standard grid is a framework-provided, Flexbox-based system using containers, rows, a 12-column convention, and responsive classes. Its breakpoint-specific classes apply framework-defined layout rules at viewport thresholds. These solve overlapping needs, but they aren't the same abstraction.
Native Grid gives you direct control over row and column tracks without requiring a framework. Bootstrap supplies conventions and reusable classes, which can be valuable when your team already works within its design system. Grid should not be described as having been created to reproduce Bootstrap.
You can use Bootstrap's outer layout and native Grid inside a component, or keep Bootstrap components while writing your page layout yourself. Bootstrap also documents an optional CSS Grid system, distinct from its default Flexbox grid. Check which implementation your project uses before comparing behavior.
Common Mistakes
- Ignoring intrinsic sizing. Intrinsic sizes come from content. Flex and Grid items can have content-based automatic minimum widths, so a long string can resist shrinking. Use
min-width: 0where the item should be allowed to shrink; a Grid track'sminmax(0, 1fr)addresses the track's minimum separately. - Confusing shrinking with text wrapping. Allowing a box to shrink doesn't itself break a long URL or identifier. The card example uses
overflow-wrap: anywhereto permit breaks within otherwise unbreakable text. - Using visual ordering to repair document order. Grid placement and Flexbox's
orderproperty alone don't change DOM order or the default keyboard sequence. Write a logical source order and test keyboard navigation after changing placement. - Choosing one layout system for an entire application. Choose per relationship: document flow for prose, Grid for shared tracks, and Flexbox for one-axis distribution.
Browser Support: Check Features, Not Just Layout Names
Core Flexbox and Grid are broadly supported in current major browsers. That doesn't guarantee every related feature works in every browser you support. Check your actual browser versions, including embedded webviews and enterprise installations, rather than treating “supports Grid” as a complete compatibility requirement.
Use feature-specific compatibility tables such as CSS Grid support and Flexbox gap support. Then test narrow containers, long translated labels, zoom, and keyboard navigation in your required browsers. A layout that works with five short English labels hasn't been meaningfully stress-tested.
FAQ
What is the difference between CSS Grid and Flexbox?
Flexbox distributes and aligns items along one main axis; Grid coordinates items through shared row and column tracks. Flexbox can wrap, but its lines distribute space independently. Choose Grid when alignment across multiple rows and columns matters.
Is the box model a CSS layout method?
No. The box model describes a box's content, padding, border, and margin, rather than providing an alternative to Flexbox or Grid. You use it with both layout systems.
Can I use CSS Grid and Flexbox together?
Yes. A Grid parent can arrange page regions while Flexbox aligns controls inside a toolbar or card. An element can be a grid item and a flex container at the same time.
Do I still need Bootstrap if I use CSS Grid?
Not for Grid itself: CSS Grid is a browser capability and doesn't require Bootstrap. You may still choose Bootstrap for its components and conventions, and use native Grid alongside it.
Do Flexbox and CSS Grid work in the browsers I support?
Core Flexbox and Grid are broadly supported in current major browsers, but the answer depends on your supported browser versions and the specific features you use. Check feature-level compatibility and test older embedded or enterprise browsers explicitly.
Further Reading
- MDN: box-sizing — content-box, border-box, and sizing calculations.
- MDN: Basic concepts of Flexbox — axes, wrapping, and flexible sizing.
- MDN: Grid and other layout methods — choosing and combining layout models.
- MDN: CSS grid layout — tracks, fractional sizing, and responsive columns.
- MDN: min-width — automatic minimum sizes for layout items.
- MDN: Grid layout and accessibility — visual order versus reading and navigation order.
- Bootstrap: Grid system — the framework's default grid and responsive conventions.
- Can I use: CSS Grid — feature compatibility across browser versions.
