Web Dev

CSS Flexbox: The Complete Guide for Beginners

Master CSS Flexbox from scratch — the container vs items model, every key property explained, and real layouts (navbars, cards, centering) you can copy today.

June 7, 202610 min read
Share
Advertisement (not configured)

Introduction

For years, centering a <div> was a running joke among web developers. Floats, tables, absolute positioning — every method had ugly edge cases. Then Flexbox arrived and made layout sane.

Flexbox (the Flexible Box Layout) is a CSS tool for arranging elements in a single direction — a row or a column — and controlling how they align, space out, and resize. Once it clicks, you'll reach for it every single day.

This guide assumes zero Flexbox knowledge. By the end you'll understand the model, know every important property, and have copy-paste layouts for the things you actually build.

The One Idea That Makes Flexbox Click

Flexbox has exactly two roles:

Role What it is
Flex container The parent — you set display: flex on it
Flex items The direct children — they get arranged automatically
<div class="container">   <!-- flex container -->
  <div class="item">1</div>  <!-- flex item -->
  <div class="item">2</div>  <!-- flex item -->
  <div class="item">3</div>  <!-- flex item -->
</div>
.container {
  display: flex;   /* that's it — children are now flex items */
}

The moment you write display: flex, the children line up in a row. Everything else is just fine-tuning.

The Two Axes (Important)

Flexbox works along two axes, and almost every property targets one of them:

  • Main axis → the direction items flow (horizontal by default)
  • Cross axis → perpendicular to it (vertical by default)
flex-direction: row  (default)

  main axis  ───────────────►
  ┌─────┐ ┌─────┐ ┌─────┐
  │  1  │ │  2  │ │  3  │     │ cross axis
  └─────┘ └─────┘ └─────┘     ▼

Remember this: justify-content controls the MAIN axis, align-items controls the CROSS axis. Mixing these two up is the #1 beginner confusion.

Container Properties

These go on the parent (.container).

display: flex

Turns on Flexbox. Use inline-flex if you want the container itself to behave like an inline element.

flex-direction

Sets the main axis — which way items flow.

.container { flex-direction: row; }            /* default: left → right */
.container { flex-direction: column; }          /* top → bottom */
.container { flex-direction: row-reverse; }     /* right → left */
.container { flex-direction: column-reverse; }  /* bottom → top */

justify-content (main axis)

Distributes items along the main axis.

.container { justify-content: flex-start; }     /* default: packed to start */
.container { justify-content: center; }         /* centered */
.container { justify-content: flex-end; }       /* packed to end */
.container { justify-content: space-between; }   /* edges, even gaps between */
.container { justify-content: space-around; }    /* even space around each */
.container { justify-content: space-evenly; }    /* perfectly equal gaps */
Value Use it for
center Centering a row of items horizontally
space-between Navbar: logo left, links right
space-evenly Equal spacing in a button group

align-items (cross axis)

Aligns items along the cross axis.

.container { align-items: stretch; }     /* default: fill container height */
.container { align-items: center; }      /* vertically centered */
.container { align-items: flex-start; }  /* top */
.container { align-items: flex-end; }    /* bottom */
.container { align-items: baseline; }    /* align text baselines */

gap

The cleanest way to add space between items — no more margin hacks.

.container {
  display: flex;
  gap: 1rem;          /* space between all items */
  /* gap: 1rem 2rem;  row-gap column-gap */
}

flex-wrap

By default items squeeze onto one line. wrap lets them flow to the next line.

.container { flex-wrap: nowrap; }   /* default: one line, items shrink */
.container { flex-wrap: wrap; }     /* items wrap to new lines */

Item Properties

These go on the children (.item).

flex-grow, flex-shrink, flex-basis

These control how items resize. Most of the time you'll use the flex shorthand instead:

.item { flex: 1; }        /* grow to fill equal space */
.item { flex: 2; }        /* take twice as much space as flex: 1 items */
.item { flex: 0 0 200px; } /* don't grow, don't shrink, stay 200px wide */
Shorthand Meaning
flex: 1 Item grows to share leftover space equally
flex: 0 0 auto Fixed size, never grows or shrinks
flex: 0 0 200px Locked to 200px

align-self

Override align-items for a single item.

.item { align-self: flex-end; }   /* this one item drops to the bottom */

order

Change visual order without touching the HTML.

.item { order: 2; }   /* higher number = appears later. Default is 0 */

The Famous "Center a Div"

The thing Flexbox is most loved for — perfect centering, both axes, in 3 lines:

.container {
  display: flex;
  justify-content: center;  /* horizontal */
  align-items: center;      /* vertical */
  min-height: 100vh;        /* full screen height */
}
<div class="container">
  <div>I am perfectly centered 🎯</div>
</div>

That's it. The decade-long struggle, solved.

Real Layout #1 — Navbar

Logo on the left, links on the right:

.navbar {
  display: flex;
  justify-content: space-between;  /* push logo and links apart */
  align-items: center;            /* vertically center everything */
  padding: 1rem 2rem;
}

.nav-links {
  display: flex;
  gap: 1.5rem;                    /* space between links */
}
<nav class="navbar">
  <div class="logo">MySite</div>
  <div class="nav-links">
    <a href="#">Home</a>
    <a href="#">Blog</a>
    <a href="#">Contact</a>
  </div>
</nav>

Real Layout #2 — Responsive Card Row

Cards that sit in a row and wrap on small screens:

.card-row {
  display: flex;
  flex-wrap: wrap;     /* wrap on small screens */
  gap: 1.5rem;
}

.card {
  flex: 1 1 250px;     /* grow, shrink, min width 250px */
}

Each card is at least 250px wide, grows to fill the row, and wraps to the next line when there's no room. Fully responsive with no media queries.

Real Layout #3 — Sticky Footer (Holy Grail)

Footer stays at the bottom even when content is short:

body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

main {
  flex: 1;            /* main content grows to fill, pushing footer down */
}

Common Mistakes Beginners Make

Mistake Fix
Setting justify-content to center vertically That's align-itemsjustify-content is the main axis
Forgetting display: flex on the parent Item properties do nothing without it
Using margins for spacing Use gap instead — much cleaner
Expecting align-items to work with one item filling height It works; check the container has a defined height
Confusing it with Grid Flexbox = 1 direction (row OR column). Grid = 2D (rows AND columns)

Flexbox vs CSS Grid

A quick rule of thumb:

Use Flexbox when… Use Grid when…
Laying out items in one direction Laying out a 2D layout (rows + columns)
Navbars, button groups, card rows Page layouts, dashboards, image galleries
You want content to dictate size You want a strict grid structure

They work great together — Grid for the page skeleton, Flexbox for the components inside it.

Flexbox Cheat Sheet

CONTAINER (parent)
  display: flex            → turn it on
  flex-direction: row|column
  justify-content: ...     → MAIN axis alignment
  align-items: ...         → CROSS axis alignment
  gap: 1rem                → space between items
  flex-wrap: wrap          → allow multiple lines

ITEM (child)
  flex: 1                  → grow to fill space
  flex: 0 0 200px          → fixed 200px
  align-self: ...          → override alignment for one item
  order: 2                 → change visual order

Final Thought

Flexbox feels confusing for about a day, then becomes second nature. The trick is to always ask two questions: "Which way are my items flowing?" (main axis) and "How do I align them across?" (cross axis). Answer those and the right property is obvious.

Open your editor, paste the centering snippet, and start tweaking values. Nothing teaches Flexbox faster than watching boxes move in real time. Once it clicks, you'll never fight CSS layout the same way again.

Advertisement (not configured)

Written by

Raretechsol

International software company specializing in Python and JavaScript. Passionate about automation, AI, and building practical web applications.

Related Articles