// CSS Layout Systems — Complete Lecture

Master Flexbox
& CSS Grid

Everything real developers know — clear definitions, live demos, and practical examples. No fluff.

flexbox css grid

// Table of Contents

Why Flexbox & Grid?

Before these two existed, developers used floats, tables, and inline-block hacks just to center a div. It was painful. Then CSS gave us two dedicated layout tools:

Flexbox
Lays items out in one direction — either a row or a column. Perfect for components and alignment.
CSS Grid
Lays items out in two dimensions — rows AND columns simultaneously. Perfect for page layouts.
💡

Simple rule: Use Flexbox for 1D layouts (a row of buttons, a nav, a card's inner content). Use Grid for 2D layouts (whole page structure, image galleries, dashboards).

Flexbox — The Concept

Flexbox works by designating one element as a flex container. Its direct children automatically become flex items and are laid out according to flexbox rules.

activate flexbox
.container {
  display: flex;  /* That's it. Now children are flex items. */
}
Live result — three divs become a row automatically
Item 1
Item 2
Item 3

The Two Axes

Flexbox has two axes. Every alignment property targets one of them. This is the most important concept to understand.

Main Axis
→ (default: row)
Cross Axis
↓ (perpendicular)
🎯

justify-content controls the main axis. align-items controls the cross axis. Remember this and flex makes sense.

Flex Container Properties

These go on the parent (the element with display: flex).

flex-direction

Sets which direction the main axis runs.

ValueEffectDescription
rowDefault. Items go left to right.
row-reverseItems go right to left.
columnItems stack top to bottom.
column-reverseItems stack bottom to top.
flex-direction: column example
.container {
  display: flex;
  flex-direction: column;  /* stack vertically */
}
flex-direction: column
Item 1
Item 2
Item 3

justify-content

Distributes items along the main axis (horizontal by default).

ValueBehaviorUse case
flex-startPack to startDefault behavior
flex-endPack to endRight-align buttons
centerCenter all itemsCentered nav
space-betweenFirst→start, Last→end, equal space betweenNav with logo + links
space-aroundEqual space around each itemEven distribution
space-evenlyPerfectly equal space everywhereTab bars
justify-content: space-between
A
B
C
justify-content: center
A
B
C

align-items

Controls how items are placed along the cross axis (vertical by default).

ValueBehavior
stretchDefault. Items stretch to fill the container height.
flex-startAlign to the top (cross start).
flex-endAlign to the bottom (cross end).
centerVertically center items. The most useful one.
baselineAlign text baselines across items.
align-items: center — items of different heights all center-aligned
Tall
Short
Medium

Perfect centering trick: display: flex; justify-content: center; align-items: center; — centers anything both horizontally and vertically. No more margin: auto hacks.

flex-wrap

By default, flex items try to fit on one line. flex-wrap: wrap lets them break to the next line when they run out of space.

flex-wrap
.container {
  display: flex;
  flex-wrap: wrap;      /* wrap to next line */
  flex-wrap: nowrap;    /* (default) force one line */
  flex-wrap: wrap-reverse; /* wrap upward */
}

gap

Adds space between flex items. Much cleaner than using margins.

gap
.container {
  display: flex;
  gap: 16px;           /* same gap in all directions */
  gap: 16px 8px;      /* row-gap column-gap */
  row-gap: 16px;       /* only between rows */
  column-gap: 8px;     /* only between columns */
}

align-content

When items wrap to multiple lines, align-content controls how those lines are distributed vertically. Same values as justify-content.

⚠️

align-content vs align-items: align-items aligns items within a single row. align-content aligns the whole group of rows. It only works when flex-wrap: wrap is set.

Flex Item Properties

These go on the children (the flex items themselves).

flex-grow

Tells an item how much of the remaining space to claim. Default is 0 (don't grow).

flex-grow
.sidebar  { flex-grow: 1; }  /* claims 1 share */
.main     { flex-grow: 3; }  /* claims 3 shares (3x bigger) */
sidebar (flex-grow: 1) vs main (flex-grow: 3)
grow: 1
grow: 3 (3× wider)

flex-shrink

Controls how much an item shrinks when there's not enough space. Default is 1 (shrink proportionally). Set to 0 to prevent shrinking.

flex-shrink
.logo {
  flex-shrink: 0;  /* Never squish the logo */
}

flex-basis

Sets the initial size of the item before any growing or shrinking happens. Think of it as the "starting width" (or height in column mode).

flex-basis
.item {
  flex-basis: 200px;  /* start at 200px, then grow/shrink */
  flex-basis: auto;    /* (default) use the item's natural size */
  flex-basis: 0;       /* start from 0, distribute all space via flex-grow */
}

The shorthand: flex

In real code, you'll almost always use the flex shorthand instead of the three individual properties.

flex shorthand → flex: grow shrink basis
.item {
  flex: 1;         /* flex: 1 1 0% — most common, equal columns */
  flex: auto;      /* flex: 1 1 auto */
  flex: none;      /* flex: 0 0 auto — rigid, won't grow or shrink */
  flex: 2 1 100px; /* grow:2, shrink:1, start at 100px */
}

align-self

Overrides align-items for a single item. Let one item do something different from the rest.

align-self
.container { align-items: center; }

.special {
  align-self: flex-end;  /* only this item goes to the bottom */
}

order

Changes the visual order of flex items without changing the HTML. Default is 0 for all items.

order
.first-visually  { order: -1; }  /* appears first */
.last-visually   { order: 99; }  /* appears last */

CSS Grid — The Concept

CSS Grid divides a container into a defined table of rows and columns. You then assign items to specific cells. It's purpose-built for 2D layouts.

activate css grid
.container {
  display: grid;
  grid-template-columns: 200px 1fr 1fr;  /* 3 columns */
  grid-template-rows: auto 1fr 60px;     /* 3 rows */
}
grid-template-columns: 1fr 1fr 1fr — three equal columns
1
2
3
4
5
6

The fr unit

The fr unit means "fraction of available space". It's the most important Grid unit. It's like flex-grow but for grid tracks.

fr unit examples
/* 3 equal columns */
grid-template-columns: 1fr 1fr 1fr;

/* Sidebar + big content + small aside */
grid-template-columns: 1fr 3fr 1fr;

/* Fixed sidebar + flexible content */
grid-template-columns: 250px 1fr;

Grid Lines

When you define a grid, CSS automatically numbers the lines between columns and rows. These numbers let you place items precisely.

Grid Lines Explained
A 3-column grid has 4 vertical lines (1, 2, 3, 4). A 2-row grid has 3 horizontal lines (1, 2, 3). You can also count from the end using negative numbers (-1 = last line).

Grid Container Properties

grid-template-columns & grid-template-rows

Define your grid's structure. These are the most fundamental Grid properties.

defining the grid
.container {
  grid-template-columns: 100px 200px 100px;   /* fixed sizes */
  grid-template-columns: 1fr 2fr 1fr;          /* proportional */
  grid-template-columns: repeat(4, 1fr);       /* 4 equal columns */
  grid-template-columns: repeat(3, minmax(100px, 1fr));

  grid-template-rows: 80px 1fr 60px;  /* header + main + footer heights */
}

repeat() function

Shorthand to avoid repeating yourself. Real developers use this constantly.

repeat()
/* Instead of this: */
grid-template-columns: 1fr 1fr 1fr 1fr 1fr;

/* Write this: */
grid-template-columns: repeat(5, 1fr);

/* Auto-fill as many as fit: */
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
repeat(auto-fill, minmax(140px, 1fr)) — responsive grid, no media queries!
1
2
3
4
5
🔥

repeat(auto-fill, minmax(200px, 1fr)) is one of the most powerful CSS lines you can write — it creates a fully responsive card grid with zero media queries.

gap

Same as Flexbox — adds space between grid cells.

gap in grid
.container {
  gap: 20px;          /* same row and column gap */
  gap: 20px 10px;    /* row-gap: 20px, column-gap: 10px */
}

grid-template-areas

This is the superpower of Grid. You draw your layout visually with names. It makes complex layouts obvious to read and maintain.

grid-template-areas — visual ASCII layout
.container {
  display: grid;
  grid-template-columns: 200px 1fr;
  grid-template-rows: 60px 1fr 50px;
  grid-template-areas:
    "header  header"   /* header spans both columns */
    "sidebar main"
    "footer  footer";  /* footer spans both columns */
}

/* Assign items to named areas */
.header  { grid-area: header;  }
.sidebar { grid-area: sidebar; }
.main    { grid-area: main;    }
.footer  { grid-area: footer;  }
grid-template-areas live result
header
sidebar
main

justify-items & align-items

Control how items are aligned inside their grid cells.

PropertyDirectionValues
justify-itemsHorizontal (inline)start, end, center, stretch
align-itemsVertical (block)start, end, center, stretch
place-itemsBoth at oncealign-items / justify-items
place-items shorthand
.container {
  place-items: center;          /* center both axes */
  place-items: center start;    /* center vertically, start horizontally */
}

justify-content & align-content

When the grid is smaller than its container, these distribute the tracks themselves inside the container (same concept as Flexbox).

Grid Item Properties

These go on the children to control exactly where they sit in the grid.

grid-column & grid-row

Tell an item which column/row lines to start and end at. This lets items span multiple cells.

spanning cells with line numbers
.hero-image {
  grid-column: 1 / 3;   /* from line 1 to line 3 (spans 2 columns) */
  grid-row: 1 / 2;      /* from line 1 to line 2 (1 row) */
}

/* Span keyword is cleaner: */
.wide-item {
  grid-column: span 2;    /* span 2 columns, wherever it lands */
  grid-row: span 3;       /* span 3 rows */
}

/* -1 means the last line: */
.full-width {
  grid-column: 1 / -1;   /* span the ENTIRE width */
}
Item 1 spans 2 columns (grid-column: span 2), item 5 spans all columns (1/-1)
1 — span 2
2
3
4
5 — 1/-1 (full width)

grid-area (shorthand)

The shorthand combining all four line properties, or a reference to a named template area.

grid-area
/* As named area reference: */
.header { grid-area: header; }

/* As line shorthand: row-start / col-start / row-end / col-end */
.item   { grid-area: 1 / 1 / 3 / 3; }

justify-self & align-self

Override alignment for a single item inside its cell.

self-alignment
.centered-item {
  justify-self: center;   /* center horizontally in its cell */
  align-self: end;         /* stick to bottom of its cell */
  place-self: center;     /* both at once — center in cell */
}

Real World Examples

🧭 Classic Navbar flexbox
navbar CSS
nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 2rem;
  height: 64px;
}

nav ul {
  display: flex;
  gap: 2rem;
  list-style: none;
}
🃏 Responsive Card Row flexbox
card row CSS
.card-row {
  display: flex;
  gap: 1.5rem;
  flex-wrap: wrap;
}

.card {
  flex: 1 1 280px;  /* grow, shrink, min 280px */
  display: flex;
  flex-direction: column;
}

.card .btn {
  margin-top: auto;  /* push button to bottom of card */
}
🗂️ Full Page Layout grid
HEADER
SIDEBAR
MAIN CONTENT
page layout CSS
body {
  display: grid;
  min-height: 100vh;
  grid-template-columns: 250px 1fr;
  grid-template-rows: 64px 1fr 60px;
  grid-template-areas:
    "header  header"
    "sidebar main"
    "footer  footer";
}

header  { grid-area: header;  }
aside   { grid-area: sidebar; }
main    { grid-area: main;    }
footer  { grid-area: footer;  }
🖼️ Responsive Gallery (no media queries!) grid
1
2
3
4
5
6
7
8
responsive gallery
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 1rem;
}
/* That's literally it. */
🎯 Perfect Centering (the holy grail) flexbox grid
two ways to perfectly center anything
/* Method 1 — Flexbox */
.center-flex {
  display: flex;
  justify-content: center;
  align-items: center;
}

/* Method 2 — Grid (even shorter) */
.center-grid {
  display: grid;
  place-items: center;
}

Flexbox vs Grid — When to Use Which

Situation Use Flexbox Use Grid
Dimensions One direction (row OR column) Both directions (rows AND columns)
Content vs Layout Content-driven (items decide their own size) Layout-driven (you define the structure)
Use case Navbars, button groups, card content, forms Page layouts, dashboards, galleries, magazine grids
Complexity Simpler, fewer properties to remember More powerful, better for complex 2D layouts
Overlap? Items never overlap (they push each other) Items CAN overlap using the same cell
🧠

Real dev mental model: Grid for the big picture (page skeleton), Flexbox for the detail work inside each section. They complement each other — use both in the same page, often nested.

Full Cheatsheet

Flex Container

  • display: flex activates
  • flex-direction row/column
  • flex-wrap wrap/nowrap
  • justify-content main axis
  • align-items cross axis
  • align-content multi-row
  • gap spacing

Flex Items

  • flex-grow claim space
  • flex-shrink compress
  • flex-basis initial size
  • flex shorthand
  • align-self override
  • order visual order

Grid Container

  • display: grid activates
  • grid-template-columns col defs
  • grid-template-rows row defs
  • grid-template-areas named zones
  • gap spacing
  • justify-items h align
  • align-items v align
  • place-items both

Grid Items

  • grid-column col span
  • grid-row row span
  • grid-area named / lines
  • justify-self h override
  • align-self v override
  • place-self both

Key Grid Functions

  • fr unit fraction
  • repeat(n, val) repeat cols
  • minmax(min, max) responsive
  • auto-fill fit as many
  • auto-fit fit+collapse
  • span N cross cells
  • 1 / -1 full width

Power Combos

  • flex + margin-top:auto push to end
  • flex:1 equal width
  • place-items:center dead center
  • auto-fill+minmax no media q
  • 1/-1 full row span
  • flex-shrink:0 no squish