sodcalculator

10 Tech How-To

CSS Flexbox vs Grid: Key Differences

Guide 10-12154 · Updated · Step by step

CSS Flexbox and CSS Grid are both layout systems, but they solve different problems: Flexbox is designed for one-dimensional layouts (a row or a column), while Grid is designed for two-dimensional layouts (rows and columns at the same time). In short, use Flexbox for distributing space along a single axis, and use Grid for placing items into a defined grid structure.

Background: How We Got Here

Before Flexbox and Grid, web developers used floats, tables, and inline-block elements to create layouts. These techniques were never intended for full page layout, so they required hacks like clearfixes and negative margins. Flexbox arrived first, gaining broad browser support around 2015, and it solved alignment and distribution along one axis. Grid followed, with stable support in all major browsers by 2017, and it brought true two-dimensional layout to the web. Today, both are supported in every modern browser, and they can be used together within the same page.

How Flexbox Works

Flexbox operates on a main axis and a cross axis. You set display: flex on a container, and its direct children become flex items. The main axis is defined by flex-direction (row, row-reverse, column, column-reverse). Along that axis, you can control alignment with justify-content and along the cross axis with align-items. Flex items can grow, shrink, and wrap, which makes Flexbox excellent for distributing space between items of unknown size.

Key properties:

  • flex-direction: sets the direction of the main axis
  • justify-content: aligns items along the main axis
  • align-items: aligns items along the cross axis
  • flex-wrap: allows items to wrap to new lines
  • flex-grow, flex-shrink, flex-basis: control how items size

Because Flexbox only knows about one line at a time, when items wrap, each line becomes its own flex context. This means you cannot align items in one wrapped line with items in another line—that is a common limitation.

How Grid Works

Grid works with explicit rows and columns. You define a grid container with display: grid, then set up tracks using grid-template-columns and grid-template-rows. Items are placed into cells using line numbers, named areas, or auto-placement. Unlike Flexbox, Grid is truly two-dimensional: you can control both the row and column of an item simultaneously.

Key properties:

  • grid-template-columns: defines the column track sizes
  • grid-template-rows: defines the row track sizes
  • grid-template-areas: lets you name regions of the grid
  • gap: sets the gutter between rows and columns
  • grid-column and grid-row: place an item by line numbers

Grid also supports the fr unit, which represents a fraction of the available space. For example, grid-template-columns: 1fr 2fr creates two columns where the second is twice as wide as the first.

How to Choose: Flexbox or Grid?

The general rule is simple: if the layout is one-dimensional (a row or a column), use Flexbox. If it is two-dimensional (rows and columns at the same time), use Grid. But real layouts often mix both. A common pattern is to use Grid for the overall page structure (header, sidebar, content, footer) and Flexbox inside a component (like a navigation bar or a row of buttons) to align items along one axis.

Here are some concrete examples:

  • Navigation bar: Flexbox is ideal because it is a single row of items.
  • Image gallery: Grid is better because you want equal-sized columns and rows.
  • Card layout: Grid can make all cards equal height, while Flexbox can distribute space inside each card.
  • Centering a button in a section: Flexbox is simpler with justify-content: center and align-items: center.

There is no strict rule that you must use one over the other. Both are powerful, and they work together well. The key is to think about the axis of alignment that matters most.

Common Problems and Misconceptions

One common misconception is that Grid is a replacement for Flexbox. It is not—they are complementary. Another is that Flexbox can handle two-dimensional layouts with wrapping. While flex-wrap creates multiple lines, you cannot align items across those lines, so it is not true two-dimensional layout.

Another frequent issue is with percentage-based sizing. In Flexbox, the flex-basis property sets the initial size, but the final size can change due to flex-grow and flex-shrink. In Grid, the track size is fixed unless you use fr or auto, so it is more predictable.

Also, remember that both Flexbox and Grid only affect direct children. If you want a grandchild to participate in the layout, you need to make its parent a flex or grid container as well.

Practical Comparison: A Simple Example

Consider a layout with a header, a sidebar, a main content area, and a footer. This is a classic two-dimensional layout because the sidebar and main content are side by side, and the header and footer span the full width. With Grid, you can write:

display: grid;
grid-template-columns: 200px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
  "header header"
  "sidebar main"
  "footer footer";

This is concise and clear. With Flexbox alone, you would need multiple nested flex containers and some width calculations to achieve the same result. For a simple row of items, however, Flexbox is much simpler than Grid.

Frequently Asked Questions

Can I use Flexbox and Grid together?

Yes, absolutely. They are not mutually exclusive. A common approach is to use Grid for the overall page layout and Flexbox for the internal alignment of components within that layout.

Is Grid better than Flexbox?

Neither is universally better. Grid is better for two-dimensional layouts, while Flexbox is better for one-dimensional distribution. The best tool depends on the specific layout you need.

Do I need to learn both?

Yes, both are fundamental CSS skills. Knowing both gives you the right tool for any layout task. Many job interviews and real projects expect familiarity with both.

What is the difference between flex-basis and width?

flex-basis is the initial main size of a flex item, but it can be overridden by flex-grow and flex-shrink. Width is the explicit size, but in a flex context, width can be affected by flex properties. In Grid, width is more straightforward because the track size is fixed.

Why is my flex item not shrinking?

Flex items do not shrink below their content size by default. You can change this by setting min-width: 0 on the item (or min-height: 0 for columns). This is a common issue with long text or images.

Can I use Grid without defining rows?

Yes, you can use grid-auto-rows to set the size of implicitly created rows. This is useful when you do not know how many rows you will need, like in a list of items.

Related

General steps for current mainstream versions; menus can differ by device and version. See the disclaimer or report an error.

More in this bed

The whole Tech How-To bed →