Flexbox and CSS Grid can both build responsive layouts, but they organize space differently. Flexbox is a natural fit when items flow along one axis and share available room; Grid is useful when rows and columns need a coordinated structure. Choose based on how the content should align and respond, not on a rule that one model is always more modern.
Start with the component's alignment problem
Ask what relationship the items need to maintain. If they form a row of controls that can wrap when space runs out, Flexbox may fit. If cards should line up across both rows and columns, Grid may make the shared tracks easier to express. A page can use Grid for its major regions and Flexbox inside a card; the models work well together.
Questions that help:
- Do items flow primarily in a row or a column?
- Should each row determine its own item widths, or should columns align across rows?
- Do you need explicit track sizes or named page regions?
- Should items grow, shrink, wrap, or stay at an intrinsic size?
- Will the design reorder content at smaller widths, and will that preserve a sensible reading order?
The answer should describe the content behavior. Avoid choosing a layout method only because a screenshot resembles a familiar CSS example.
What Flexbox does well
Flexbox lays out items along a main axis and a cross axis. You choose a row or column direction, then control spacing, alignment, growth, and wrapping. It is especially convenient for a row or stack of related items whose sizes may vary with content.
Common uses include:
- Navigation items aligned in a row
- A form label and control paired together
- Buttons grouped in a toolbar
- A card's title, metadata, and actions arranged vertically
- A row of tags that wraps when the container narrows
For example, a button group can distribute space and wrap without needing to define a two-dimensional track system:
.actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.75rem;
}
Flex items can grow or shrink according to their flex properties. This is useful when one item should consume remaining space or when a toolbar needs to compress gracefully. But implicit sizing can be surprising if a child has a long unbreakable value or a wide minimum content size. Test real labels and set min-width: 0 or wrapping rules where needed.
A wrapping Flexbox layout treats each line independently. The items on one row do not automatically align into the same column tracks as items on the next row. That distinction matters for cards whose headings or prices should line up across a whole collection.
Example: a responsive filter form
A short search form with an input and a submit button can use Flexbox: the input grows to fill remaining space, while the button keeps its natural width. If the form contains several labels and controls that must line up in columns, Grid may be clearer. At a narrow width, either layout can stack controls, but the markup should keep each label associated with its field and preserve the same logical order. The choice follows the alignment relationship, not the fact that the component happens to contain form controls.
What CSS Grid does well
Grid lets you define rows and columns as tracks, then place items in that structure. It is well suited to a card board, dashboard, or page layout where horizontal and vertical alignment both matter. Tracks can be fixed, flexible, or based on content.
A responsive collection of cards can use intrinsic track sizing:
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
gap: 1rem;
}
This lets the number of columns respond to available container width while preserving a minimum track size. Tune the minimum based on the card content, and test long titles, buttons, and narrow containers. If the cards should remain a fixed count at specific widths, explicit columns and media queries may be clearer.
Grid is also useful for larger page regions, such as a sidebar alongside a main panel. Use minmax(0, 1fr) for flexible areas that contain wide content when you need the track to shrink rather than expand the whole page. Give tables, charts, or code panels their own overflow behavior if they must keep a minimum width.
Compare how wrapping behaves
Flexbox with flex-wrap: wrap and a Grid with auto-fitting columns can look similar at first. Their behavior differs when the last row has fewer items or when each item has a different preferred width.
In a wrapping Flexbox row, items can size according to their content and available line space. The final row distributes its own items independently. This can make controls feel natural but may lead to uneven column alignment in a card catalog.
In Grid, each column track aligns across rows. If the final row has fewer cards, those cards stay in their assigned columns or may expand depending on the sizing rule (auto-fit and auto-fill behave differently). This predictability often helps comparison layouts, though it can leave empty space or stretch a small number of cards more than desired.
Choose by evaluating a collection with a non-full final row, not just a screenshot where every row happens to contain the same number of items.
Also test with the longest label, a missing image, and a card that has extra metadata. Those content changes reveal whether a layout rule is genuinely flexible or only works for identical placeholders.
Use the two models together
A common pattern is Grid for the larger structure and Flexbox inside each component:
.dashboard {
display: grid;
grid-template-columns: 14rem minmax(0, 1fr);
gap: 1.5rem;
}
.card {
display: flex;
flex-direction: column;
}
.cardAction {
margin-top: auto;
}
The dashboard establishes the sidebar and content tracks. Each card uses Flexbox to place its internal content and keep an action near the bottom. This avoids forcing one layout model to solve two different problems.
You can also use Flexbox for a header row within a Grid region, or a nested Grid inside a Flexbox item when that inner region needs aligned columns. Use the model that makes each container's relationship easiest to describe. Do not add nesting just to satisfy a pattern; normal block flow may be enough for a simple component.
Choose the model by example
| Component | A sensible starting point | Why | |---|---|---| | Header with logo and actions | Flexbox | Items share a row and may need to push apart or wrap | | Responsive card collection | Grid | Columns align across rows and track sizes can adapt | | Form label and input | Flexbox or Grid | Use whichever clearly expresses the desired label/control relationship | | Dashboard sidebar and main area | Grid | The page has coordinated columns that may change structure at a breakpoint | | Card content and bottom action | Flexbox column | Content stacks while the action can align after variable text | | Small row of chips | Flexbox with wrap | Items flow naturally onto another line without shared column alignment |
These are starting points, not mandates. A form with multiple aligned columns may benefit from Grid; a short card row may be simpler in Flexbox.
Keep visual order and reading order aligned
Both layout models can visually place items in ways that differ from the document order. CSS placement does not automatically change screen-reader reading order or keyboard focus order. Keep the HTML in the order users should read and operate it, and use CSS to adapt the visual layout without creating a confusing sequence.
Avoid using Grid's dense auto-placement to fill gaps when it causes items to appear in an unexpected visual order. Avoid reversing Flexbox direction merely to compensate for markup that is in the wrong order. If a mobile design changes the sequence, consider whether the content structure should be adjusted or whether the visual arrangement can remain consistent.
A layout's semantics come from HTML elements, not from Grid or Flexbox. Use lists for collections when appropriate, headings for sections, and real buttons or links for actions. CSS decides where those elements appear.
Common layout problems
- Cards do not align across rows: Flexbox wrapping treats lines independently. Use Grid if shared column tracks are important.
- The last row looks too stretched: Review
auto-fitbehavior, cap the grid container width, or chooseauto-fillor explicit tracks. - Flex items overflow: Check long unbreakable content,
min-width, and flex shrink behavior; allow text to wrap where appropriate. - Grid causes horizontal scrolling: Use flexible track minimums and
min-width: 0for shrinkable regions; isolate intentionally wide content. - Mobile order feels unnatural: Keep source order logical and adjust the layout without creating conflicting keyboard and visual sequences.
- The CSS becomes hard to maintain: Use the simplest model that describes the relationship; avoid nested layout containers without a need.
A practical decision workflow
- Describe the content relationship in plain language: row, stack, card board, or page regions.
- Decide whether items need shared row and column alignment.
- Try Flexbox for a one-axis flow and Grid for coordinated tracks or regions.
- Test wrapping, uneven content lengths, and a partially filled final row.
- Combine models when the outer and inner layout problems differ.
- Check keyboard and reading order after visual changes.
- Inspect narrow widths and confirm no unwanted page overflow.
The Flexbox Generator and Grid Generator can help explore syntax. Treat their output as a starting point and test it with your actual content and responsive states.
Frequently asked questions
Is CSS Grid better than Flexbox?
Neither is universally better. Grid is convenient for coordinated rows, columns, and page regions. Flexbox is convenient for items flowing along one axis. Choose the model that makes the content relationship clear.
Can I use Grid and Flexbox together?
Yes. A page can use Grid for major regions and Flexbox inside cards or toolbars. Nested layout models are common when the outer and inner containers have different needs.
Should I use Grid for every card layout?
No. Use Grid when shared column alignment or track control matters. A short row of variable-width controls or tags may be simpler with Flexbox.
Why do cards in my Flexbox layout have uneven columns?
Wrapped Flexbox lines distribute their items independently, so each row may have different widths. Use Grid when cards should share column tracks across rows.
Which layout model is more accessible?
Neither is automatically more accessible. Semantic markup, logical document order, keyboard behavior, and responsive readability matter. Avoid visual reordering that conflicts with reading or focus order.
Next step
Take one component and describe how its items should align as the viewport changes. Try Flexbox for a one-axis flow or Grid for shared tracks, then test uneven content and a narrow layout. Use both when the outer structure and the component internals need different behavior.
