CSS Flexbox - Complete Guide

Flexbox is a CSS layout module that makes it easy to design flexible and responsive layouts. This guide covers everything you need to know about Flexbox.

What is Flexbox? #

Flexbox (Flexible Box Layout) is a one-dimensional layout method for arranging items in rows or columns. Items flex to fill additional space or shrink to fit smaller spaces.

Basic Concepts #

Flex Container and Flex Items #

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>
.container {
  display: flex;  /* Creates flex container */
}

Main Axis and Cross Axis #

  • Main Axis - Primary direction items are laid out
  • Cross Axis - Perpendicular to main axis

Container Properties #

display: flex #

Enables flexbox layout:

.container {
  display: flex;  /* Block-level flex container */
}

.inline-container {
  display: inline-flex;  /* Inline flex container */
}

flex-direction #

Defines the main axis direction:

.container {
  flex-direction: row;  /* Default: left to right */
}

.column {
  flex-direction: column;  /* Top to bottom */
}

.row-reverse {
  flex-direction: row-reverse;  /* Right to left */
}

.column-reverse {
  flex-direction: column-reverse;  /* Bottom to top */
}

Example:

<div class="row-container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>
.row-container {
  display: flex;
  flex-direction: row;
}
/* Items: 1 2 3 (horizontal) */

flex-wrap #

Controls whether items wrap to new lines:

.container {
  flex-wrap: nowrap;  /* Default: single line */
}

.wrap {
  flex-wrap: wrap;  /* Wrap to multiple lines */
}

.wrap-reverse {
  flex-wrap: wrap-reverse;  /* Wrap in reverse */
}

Example:

.container {
  display: flex;
  flex-wrap: wrap;
  width: 300px;
}

.item {
  width: 100px;
  height: 100px;
}
/* Items wrap when container width is exceeded */

flex-flow #

Shorthand for flex-direction and flex-wrap:

.container {
  flex-flow: row wrap;
  /* Same as:
     flex-direction: row;
     flex-wrap: wrap;
  */
}

justify-content #

Aligns items along the main axis:

.container {
  justify-content: flex-start;  /* Default: start */
}

.center {
  justify-content: center;  /* Center items */
}

.end {
  justify-content: flex-end;  /* End of container */
}

.space-between {
  justify-content: space-between;  /* Space between items */
}

.space-around {
  justify-content: space-around;  /* Space around items */
}

.space-evenly {
  justify-content: space-evenly;  /* Equal space */
}

Visual Examples:

flex-start:    [1][2][3]______
center:        ___[1][2][3]___
flex-end:      ______[1][2][3]
space-between: [1]___[2]___[3]
space-around:  _[1]__[2]__[3]_
space-evenly:  __[1]__[2]__[3]__

align-items #

Aligns items along the cross axis:

.container {
  align-items: stretch;  /* Default: fill container */
}

.flex-start {
  align-items: flex-start;  /* Top of container */
}

.center {
  align-items: center;  /* Vertical center */
}

.flex-end {
  align-items: flex-end;  /* Bottom of container */
}

.baseline {
  align-items: baseline;  /* Align text baselines */
}

align-content #

Aligns multiple lines along cross axis:

.container {
  flex-wrap: wrap;
  align-content: flex-start;
}

.center {
  align-content: center;
}

.space-between {
  align-content: space-between;
}

Note: Only works with multiple lines (flex-wrap: wrap)

gap #

Adds space between flex items:

.container {
  display: flex;
  gap: 20px;  /* 20px gap between items */
}

.custom-gap {
  row-gap: 20px;     /* Vertical gap */
  column-gap: 10px;  /* Horizontal gap */
}

Item Properties #

order #

Controls the order of flex items:

.item1 {
  order: 2;
}

.item2 {
  order: 1;
}

.item3 {
  order: 3;
}
/* Display order: item2, item1, item3 */

flex-grow #

Defines how much an item should grow:

.item {
  flex-grow: 0;  /* Default: don't grow */
}

.grow {
  flex-grow: 1;  /* Grow to fill space */
}

.grow-more {
  flex-grow: 2;  /* Grow twice as much */
}

Example:

.container {
  display: flex;
  width: 600px;
}

.item1 {
  flex-grow: 1;  /* Gets 1/3 of extra space */
}

.item2 {
  flex-grow: 2;  /* Gets 2/3 of extra space */
}

flex-shrink #

Defines how much an item should shrink:

.item {
  flex-shrink: 1;  /* Default: can shrink */
}

.no-shrink {
  flex-shrink: 0;  /* Don't shrink */
}

flex-basis #

Defines the initial size of an item:

.item {
  flex-basis: auto;  /* Default: based on content */
}

.fixed {
  flex-basis: 200px;  /* Initial width of 200px */
}

.percent {
  flex-basis: 33.33%;  /* 1/3 of container */
}

flex #

Shorthand for flex-grow, flex-shrink, and flex-basis:

.item {
  flex: 1;
  /* Same as:
     flex-grow: 1;
     flex-shrink: 1;
     flex-basis: 0%;
  */
}

.custom {
  flex: 2 1 200px;
  /* flex-grow: 2
     flex-shrink: 1
     flex-basis: 200px */
}

.fixed-size {
  flex: 0 0 100px;  /* Fixed 100px, no grow or shrink */
}

Common Patterns:

.equal {
  flex: 1;  /* Equal size items */
}

.double {
  flex: 2;  /* Twice as large */
}

.auto {
  flex: auto;  /* Size based on content */
  /* Same as: flex: 1 1 auto */
}

.none {
  flex: none;  /* Fixed size */
  /* Same as: flex: 0 0 auto */
}

align-self #

Overrides align-items for individual items:

.container {
  align-items: flex-start;
}

.special-item {
  align-self: center;  /* This item centered */
}

Common Layouts #

Horizontal Navigation #

<nav class="nav">
  <a href="#">Home</a>
  <a href="#">About</a>
  <a href="#">Contact</a>
</nav>
.nav {
  display: flex;
  gap: 20px;
  padding: 20px;
  background: #333;
}

.nav a {
  color: white;
  text-decoration: none;
}

Centered Content #

<div class="center-box">
  <div class="content">Centered!</div>
</div>
.center-box {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

Three Column Layout #

<div class="three-column">
  <div class="sidebar">Sidebar</div>
  <div class="main">Main Content</div>
  <div class="sidebar">Sidebar</div>
</div>
.three-column {
  display: flex;
  gap: 20px;
}

.sidebar {
  flex: 0 0 200px;  /* Fixed 200px */
}

.main {
  flex: 1;  /* Takes remaining space */
}

Card Layout #

<div class="cards">
  <div class="card">Card 1</div>
  <div class="card">Card 2</div>
  <div class="card">Card 3</div>
</div>
.cards {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

.card {
  flex: 1 1 300px;  /* Min 300px, grows to fill */
  padding: 20px;
  border: 1px solid #ddd;
}

Holy Grail Layout #

<div class="holy-grail">
  <header>Header</header>
  <div class="body">
    <nav>Nav</nav>
    <main>Content</main>
    <aside>Aside</aside>
  </div>
  <footer>Footer</footer>
</div>
.holy-grail {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.body {
  display: flex;
  flex: 1;
}

nav {
  flex: 0 0 200px;
}

main {
  flex: 1;
}

aside {
  flex: 0 0 200px;
}
<div class="page">
  <main>Content</main>
  <footer>Footer</footer>
</div>
.page {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

main {
  flex: 1;  /* Pushes footer to bottom */
}

Responsive Design with Flexbox #

Mobile-First Approach #

/* Mobile: Stack vertically */
.container {
  display: flex;
  flex-direction: column;
}

/* Tablet: Horizontal */
@media (min-width: 768px) {
  .container {
    flex-direction: row;
  }
}

/* Desktop: Adjust spacing */
@media (min-width: 1024px) {
  .container {
    gap: 40px;
  }
}

Responsive Navigation #

.nav {
  display: flex;
  flex-direction: column;
}

@media (min-width: 768px) {
  .nav {
    flex-direction: row;
    justify-content: space-between;
  }
}

Flexbox vs Grid #

FeatureFlexboxGrid
DimensionOne-dimensionalTwo-dimensional
Use CaseNavigation, cardsComplex layouts
AlignmentExcellentExcellent
Item OrderEasy to changeEasy to change
Browser SupportExcellentGood (IE11 needs prefixes)

When to use Flexbox:

  • Navigation menus
  • Card layouts
  • Centering content
  • Simple one-dimensional layouts

When to use Grid:

  • Complex page layouts
  • Two-dimensional control needed
  • Magazine-style layouts

Browser Support #

Flexbox is supported in all modern browsers:

  • Chrome 29+
  • Firefox 28+
  • Safari 9+
  • Edge 12+
  • IE 11 (with prefixes)

Common Issues and Solutions #

Items Overflowing Container #

.item {
  min-width: 0;  /* Allow shrinking below content size */
}

Text Not Wrapping #

.item {
  min-width: 0;
  overflow-wrap: break-word;
}

Items Not Equal Height #

.container {
  align-items: stretch;  /* Default, ensures equal height */
}

Best Practices #

  1. Use flex shorthand - flex: 1 instead of individual properties
  2. Mobile-first - Start with column layout
  3. Use gap for spacing - Cleaner than margins
  4. Semantic HTML - Use proper HTML elements
  5. Test across browsers - Especially IE11 if needed
  6. Combine with Grid - Use both where appropriate

Flexbox makes creating flexible, responsive layouts straightforward. Master these properties and you can build almost any layout with ease.