Skip to content
Kordu Tools

CSS Flexbox & Grid Cheat Sheet: Every Property Explained

Complete CSS Flexbox and Grid reference with every property, values, and visual examples. 92% of sites now use Flexbox or Grid for layout.

I
iyda
14 min read
css flexbox css grid css cheat sheet css layout

Every modern website runs on Flexbox, Grid, or both. According to the Web Almanac (2024), 92% of pages use Flexbox and 40% use CSS Grid. These two layout systems handle virtually every layout problem you’ll face in CSS. Yet their property lists are long, the naming is inconsistent, and the behavior sometimes feels unintuitive.

This cheat sheet covers every Flexbox and Grid property with its values and a plain description of what it actually does. Bookmark it. You’ll be back.

CSS tools and developer references

Key Takeaways

  • Flexbox handles one-dimensional layouts (rows or columns). Grid handles two-dimensional layouts (rows and columns together).
  • 92% of websites use Flexbox and 40% use Grid, per the 2024 Web Almanac.
  • You don't pick one or the other. Use Flexbox inside Grid cells, or Grid inside flex items. They compose well.
  • Master six properties (display, flex-direction, justify-content, align-items, grid-template-columns, gap) and you can build most layouts.

Part 1: Flexbox

Flexbox became a W3C Recommendation in 2017, and browser support hit 98.8% globally by 2024 (Can I Use, 2024). It’s the default choice for laying out items along a single axis. You set a direction, and Flexbox distributes space among child elements.

browser compatibility tools

How Flexbox Works

Flexbox operates on two axes. The main axis runs in the direction you set with flex-direction. The cross axis runs perpendicular to it. Every alignment property in Flexbox references one of these two axes.

flex-direction: row (default)

Main Axis →
┌──────────────────────────────────┐
│  ┌─────┐  ┌─────┐  ┌─────┐     │  ↕ Cross Axis
│  │  A  │  │  B  │  │  C  │     │
│  └─────┘  └─────┘  └─────┘     │
└──────────────────────────────────┘

flex-direction: column

Main Axis ↓
┌──────────┐
│ ┌──────┐ │
│ │  A   │ │  ↔ Cross Axis
│ └──────┘ │
│ ┌──────┐ │
│ │  B   │ │
│ └──────┘ │
│ ┌──────┐ │
│ │  C   │ │
│ └──────┘ │
└──────────┘

Remember: justify-content always aligns along the main axis. align-items always aligns along the cross axis. The axis flips when you change flex-direction. This single concept trips up more developers than anything else in Flexbox.

Flexbox Container Properties

These properties go on the parent element (the flex container). They control how children are arranged.

Property Values What It Does
display flex | inline-flex Creates a flex container. flex makes it block-level, inline-flex makes it inline.
flex-direction row | row-reverse | column | column-reverse Sets the main axis direction. row is left-to-right, column is top-to-bottom.
flex-wrap nowrap | wrap | wrap-reverse Controls whether items wrap to new lines. Default is nowrap (items shrink to fit).
justify-content flex-start | flex-end | center | space-between | space-around | space-evenly Distributes space along the main axis. space-between puts equal gaps between items.
align-items flex-start | flex-end | center | baseline | stretch Aligns items along the cross axis. stretch (default) makes items fill the container height.
align-content flex-start | flex-end | center | space-between | space-around | stretch Controls spacing between wrapped lines. Only works when flex-wrap is wrap.
gap length (e.g. 16px, 1rem) Sets spacing between flex items. Replaces margin hacks. Works in all modern browsers.

justify-content visualized

justify-content: flex-start (default)
┌──────────────────────────────┐
│ [A] [B] [C]                 │
└──────────────────────────────┘

justify-content: flex-end
┌──────────────────────────────┐
│                 [A] [B] [C] │
└──────────────────────────────┘

justify-content: center
┌──────────────────────────────┐
│         [A] [B] [C]         │
└──────────────────────────────┘

justify-content: space-between
┌──────────────────────────────┐
│ [A]         [B]         [C] │
└──────────────────────────────┘

justify-content: space-evenly
┌──────────────────────────────┐
│    [A]      [B]      [C]    │
└──────────────────────────────┘

align-items visualized

align-items: stretch (default)
┌──────────────────────────────┐
│ ┌────────┐ ┌────────┐       │
│ │   A    │ │   B    │       │
│ │        │ │        │       │
│ │        │ │        │       │
│ └────────┘ └────────┘       │
└──────────────────────────────┘

align-items: center
┌──────────────────────────────┐
│                              │
│  ┌──┐  ┌──────┐             │
│  │A │  │  B   │             │
│  └──┘  └──────┘             │
│                              │
└──────────────────────────────┘

align-items: flex-start
┌──────────────────────────────┐
│  ┌──┐  ┌──────┐             │
│  │A │  │  B   │             │
│  └──┘  └──────┘             │
│                              │
│                              │
└──────────────────────────────┘

The centering trick

Perfect centering in CSS is three lines. Set display: flex, justify-content: center, and align-items: center on the parent. That’s it. Works for any content, any size. No more transform: translate(-50%, -50%) hacks.

.center-everything {
  display: flex;
  justify-content: center;
  align-items: center;
}

Flexbox Item Properties

These go on child elements inside the flex container. They control how individual items behave.

Property Values What It Does
flex-grow number (default: 0) How much an item grows relative to siblings. flex-grow: 1 on all items distributes space equally.
flex-shrink number (default: 1) How much an item shrinks when space is tight. Set to 0 to prevent shrinking.
flex-basis length | auto | content The initial size before growing/shrinking. Works like width (in row) or height (in column).
flex shorthand: grow shrink basis Shorthand for flex-grow, flex-shrink, flex-basis. flex: 1 means flex: 1 1 0%.
align-self auto | flex-start | flex-end | center | baseline | stretch Overrides align-items for a single item. Lets one item break from the group.
order integer (default: 0) Controls visual order without changing HTML. Lower numbers appear first.

Understanding flex shorthand

The flex shorthand is what you’ll use 90% of the time. Here’s how the common values break down:

/* Equal-width columns */
.item { flex: 1; }          /* flex: 1 1 0% */

/* Item takes twice the space */
.wide { flex: 2; }          /* flex: 2 1 0% */

/* Fixed-width item that won't grow or shrink */
.fixed { flex: 0 0 200px; } /* stays at 200px */

/* Item that grows but starts at its content width */
.auto { flex: 1 1 auto; }   /* grows from content size */
``` In our experience building tool interfaces, `flex: 1` on items with a fixed-width sidebar (`flex: 0 0 280px`) handles 80% of application layouts. It's the pattern behind every dashboard, email client, and documentation site.

<Callout type="tip" title="Sidebar layout in four lines">
  The classic sidebar-plus-content layout needs almost no CSS. The sidebar gets a fixed basis, the content area gets `flex: 1` to fill remaining space.
</Callout>

```css
.layout {
  display: flex;
  gap: 24px;
}
.sidebar {
  flex: 0 0 280px;  /* fixed width, no grow, no shrink */
}
.content {
  flex: 1;           /* fill remaining space */
}
┌────────────────────────────────────────┐
│ ┌──────────┐ ┌───────────────────────┐ │
│ │          │ │                       │ │
│ │ Sidebar  │ │    Content (flex:1)   │ │
│ │ (280px)  │ │                       │ │
│ │          │ │                       │ │
│ └──────────┘ └───────────────────────┘ │
└────────────────────────────────────────┘

Part 2: CSS Grid

CSS Grid support reached 97.8% global browser coverage by 2024 (Can I Use, 2024). Unlike Flexbox’s single axis, Grid works in two dimensions simultaneously. You define rows and columns, then place items into that structure.

layout and design tools

How CSS Grid Works

Grid creates a coordinate system on your container. You define columns and rows using grid-template-columns and grid-template-rows. Items can be placed explicitly into cells, or they flow in automatically. Think of it like a spreadsheet where you control the column widths and row heights.

grid-template-columns: 1fr 2fr 1fr
grid-template-rows: auto 1fr auto

     1fr        2fr        1fr
  ┌─────────┬───────────┬─────────┐
  │  auto   │   auto    │  auto   │  ← row 1 (header)
  ├─────────┼───────────┼─────────┤
  │         │           │         │
  │   1fr   │    1fr    │   1fr   │  ← row 2 (content, fills space)
  │         │           │         │
  ├─────────┼───────────┼─────────┤
  │  auto   │   auto    │  auto   │  ← row 3 (footer)
  └─────────┴───────────┴─────────┘

The fr unit is unique to Grid. It represents a fraction of available space. 1fr 2fr 1fr splits the container into 4 equal parts: the first column gets 1/4, the middle gets 2/4, the last gets 1/4.

Grid Container Properties

These go on the parent element (the grid container).

Property Values What It Does
display grid | inline-grid Creates a grid container. grid makes it block-level, inline-grid makes it inline.
grid-template-columns track sizes (e.g. 1fr 200px 2fr) Defines the number and width of columns. Use fr units, px, %, auto, or minmax().
grid-template-rows track sizes (e.g. auto 1fr auto) Defines the number and height of rows. Same units as columns.
grid-template-areas named area strings Lets you name grid regions and place items by name. Great for page layouts.
gap (row-gap, column-gap) length (e.g. 16px, 1rem 2rem) Sets spacing between grid cells. One value for both, or two values for row/column.
grid-auto-flow row | column | dense Controls how auto-placed items fill the grid. dense fills holes left by spanning items.
grid-auto-rows track size Sets the height of implicitly created rows (rows not defined in grid-template-rows).
grid-auto-columns track size Sets the width of implicitly created columns.
justify-items start | end | center | stretch Aligns all items horizontally within their grid cells. stretch is the default.
align-items start | end | center | stretch Aligns all items vertically within their grid cells.
justify-content start | end | center | space-between | space-around | space-evenly Aligns the entire grid horizontally within the container (when grid is smaller than container).
align-content start | end | center | space-between | space-around | space-evenly Aligns the entire grid vertically within the container.

The repeat() and minmax() functions

These two functions save enormous amounts of repetition. repeat() creates multiple tracks with the same size. minmax() sets a minimum and maximum size for a track.

/* 12 equal columns */
grid-template-columns: repeat(12, 1fr);

/* 3 columns, each between 200px and 1fr */
grid-template-columns: repeat(3, minmax(200px, 1fr));

/* Auto-fill: as many 250px columns as fit */
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));

/* Auto-fit: same as auto-fill, but collapses empty tracks */
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));

What’s the difference between auto-fill and auto-fit? Both create as many columns as the container can hold. But when there aren’t enough items to fill every column, auto-fill keeps the empty tracks (preserving their space), while auto-fit collapses them (letting existing items stretch).

Responsive grid without media queries

repeat(auto-fit, minmax(250px, 1fr)) creates a fully responsive grid. Items are at least 250px wide and expand to fill space. No media queries needed. This single line handles card grids, image galleries, and product listings.

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 24px;
}

grid-template-areas: layouts in plain English

Named grid areas let you describe your layout visually in CSS. Each string represents a row. Each word in the string is a column. Use . for empty cells.

.page {
  display: grid;
  grid-template-columns: 200px 1fr 200px;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header  header  header"
    "sidebar content aside"
    "footer  footer  footer";
  gap: 16px;
  min-height: 100vh;
}

.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.aside   { grid-area: aside; }
.footer  { grid-area: footer; }
┌──────────────────────────────────────┐
│             header                   │
├────────┬─────────────────┬───────────┤
│        │                 │           │
│sidebar │    content      │   aside   │
│        │                 │           │
├────────┴─────────────────┴───────────┤
│             footer                   │
└──────────────────────────────────────┘
``` Named grid areas are underused in production. We've found that developers default to line-based placement out of habit, but `grid-template-areas` makes responsive redesigns trivial. You just rewrite the area strings in a media query, and the entire layout restructures without touching any item placement rules.

### Grid Item Properties

These go on **child** elements inside the grid container.

<ComparisonTable
  headers={["Property", "Values", "What It Does"]}
  rows={[
    ["grid-column", "start / end (e.g. 1 / 3, span 2)", "Sets which columns an item occupies. grid-column: 1 / 3 spans columns 1 and 2."],
    ["grid-row", "start / end (e.g. 1 / 3, span 2)", "Sets which rows an item occupies. grid-row: span 2 spans two rows from current position."],
    ["grid-area", "name or row-start / col-start / row-end / col-end", "Places an item by named area or by explicit coordinates."],
    ["justify-self", "start | end | center | stretch", "Overrides justify-items for a single item. Controls horizontal alignment within its cell."],
    ["align-self", "start | end | center | stretch", "Overrides align-items for a single item. Controls vertical alignment within its cell."],
    ["place-self", "align-self justify-self", "Shorthand for align-self and justify-self in one declaration."]
  ]}
/>

#### Spanning rows and columns

```css
/* Span 2 columns starting from column 1 */
.item { grid-column: 1 / 3; }

/* Span 2 columns from wherever the item lands */
.item { grid-column: span 2; }

/* Span the full width (works for any number of columns) */
.item { grid-column: 1 / -1; }

/* Span 2 rows */
.item { grid-row: span 2; }

The 1 / -1 pattern is particularly useful. -1 means “the last grid line,” so grid-column: 1 / -1 always spans the full width regardless of how many columns exist.

How Do Flexbox and Grid Compare?

The 2024 State of CSS survey found that 98% of respondents use Flexbox regularly, while 83% use Grid regularly (State of CSS, 2024). They aren’t competitors. They solve different problems, and the best layouts combine both. Here’s when to reach for each. After building hundreds of tool interfaces, we’ve settled on a simple rule: if the layout is a line of things, use Flexbox. If the layout is a grid of things, use Grid. Sounds obvious, but it resolves 95% of the “which one?” questions.

Consideration Flexbox CSS Grid
Axis One dimension (row OR column) Two dimensions (rows AND columns)
Best for Navbars, toolbars, card rows, centering Page layouts, dashboards, card grids, galleries
Content vs layout Content-first (items dictate size) Layout-first (grid dictates size)
Item placement Sequential (source order) Precise (row/column coordinates)
Responsiveness Items wrap naturally with flex-wrap Use auto-fit/auto-fill with minmax()
Browser support 98.8% (Can I Use, 2024) 97.8% (Can I Use, 2024)
Overlap/layering Not built-in Items can overlap with explicit placement

When should you use Flexbox?

Use Flexbox when your content flows in one direction and you want items to size themselves based on their content. Navbars, button groups, form rows, icon-plus-text components, and anything where “just put these things in a line with some spacing” describes the goal.

/* Navigation bar */
.nav {
  display: flex;
  align-items: center;
  gap: 16px;
}
.nav-spacer { flex: 1; }  /* pushes items to opposite ends */

/* Button group */
.button-group {
  display: flex;
  gap: 8px;
}

When should you use CSS Grid?

Use Grid when you need to control both rows and columns, or when you want items to conform to a consistent layout structure. Page templates, card grids, dashboard panels, and any layout where alignment across both axes matters.

/* Dashboard layout */
.dashboard {
  display: grid;
  grid-template-columns: 250px 1fr;
  grid-template-rows: 60px 1fr;
  grid-template-areas:
    "nav header"
    "nav main";
  min-height: 100vh;
}

/* Card grid that auto-wraps */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 24px;
}

Holy grail layout with Grid

The classic header-sidebar-content-footer layout is five lines of CSS with Grid. Define three columns and three rows, name the areas, and you’re done. Making it responsive requires changing only the grid-template-areas in a media query.

Can you use Flexbox inside Grid?

Absolutely, and you should. Grid defines the macro layout (page structure, card grid). Flexbox handles the micro layout inside each cell (aligning icons, spacing text, centering buttons). This isn’t an either-or choice.

/* Grid for the page */
.page {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 24px;
}

/* Flexbox inside each card */
.card {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.card-footer {
  margin-top: auto;  /* pushes footer to bottom */
  display: flex;
  justify-content: space-between;
  align-items: center;
}

The margin-top: auto trick on a flex child is worth memorizing. It pushes that element to the far end of the flex container, which is perfect for card footers, “stick to bottom” buttons, and nav items that need to sit at the end of a sidebar.

What Are Common Flexbox and Grid Patterns?

According to a 2024 analysis by HTTP Archive, gap is now used on 72% of pages that use Flexbox or Grid (HTTP Archive, 2024). The old spacer-div and margin-based approaches are fading fast. Here are patterns you’ll use constantly.

Responsive card grid (no media queries)

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 20px;
}

Cards fill available space, wrapping to new rows as the viewport shrinks. Each card is at least 280px wide. Zero media queries.

body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
main {
  flex: 1;  /* main content fills all available space */
}

The footer stays at the bottom of the viewport when content is short, and pushes down naturally when content is long. Two properties on the body, one on main.

Equal-height columns

.row {
  display: flex;
  gap: 24px;
}
.column {
  flex: 1;
}

Flex items stretch to match the tallest sibling by default (align-items: stretch). No JavaScript height-matching needed.

Centering absolutely anything

.center {
  display: grid;
  place-items: center;
}

Two lines. place-items: center is shorthand for align-items: center and justify-items: center. Works with Grid and is even simpler than the Flexbox version.

FAQ

What is the difference between Flexbox and Grid?

Flexbox is one-dimensional, controlling layout in either a row or a column. Grid is two-dimensional, controlling rows and columns simultaneously. According to MDN Web Docs (2025), Flexbox is best when content drives the layout, while Grid is best when the layout drives the content.

Can I use Flexbox and Grid together?

Yes, and most production layouts do. Grid handles page-level structure, like columns and named regions. Flexbox handles component-level alignment, like centering icons in buttons or spacing items in a navbar. The 2024 Web Almanac reports that 38% of pages use both Flexbox and Grid on the same page.

Is CSS Grid supported in all browsers?

CSS Grid has 97.8% global browser support as of 2024 (Can I Use, 2024). Every modern browser, including Chrome, Firefox, Safari, and Edge, fully supports it. Internet Explorer 11 had partial support with an older syntax, but IE is no longer maintained.

What does fr mean in CSS Grid?

The fr unit stands for “fraction of available space.” In grid-template-columns: 1fr 2fr, the container’s free space is split into 3 parts. The first column gets 1/3, the second gets 2/3. The fr unit only applies to CSS Grid and is not available in Flexbox.

How do I make a responsive grid without media queries?

Use grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)). This creates as many columns as fit, each at least 250px wide, expanding to share remaining space equally. According to CSS-Tricks (2023), this pattern handles the majority of responsive grid needs without a single media query.

explore developer tools

Quick Reference Card

Here’s the shortest possible summary for both systems.

Flexbox container: display: flex, flex-direction, justify-content (main axis), align-items (cross axis), flex-wrap, gap.

Flexbox items: flex (shorthand for grow/shrink/basis), align-self, order.

Grid container: display: grid, grid-template-columns, grid-template-rows, grid-template-areas, gap, justify-items, align-items.

Grid items: grid-column, grid-row, grid-area, justify-self, align-self.

That’s every property. Most layouts use fewer than half of them. Start with display: flex or display: grid, add gap, set your alignment, and build from there. The rest you’ll reach for when you need it.

bookmark our developer tools