Back To Basic: Mental Model to Understand Flexbox
const x = () =>
<div className="...">
npm install
git commit -m
console.log()
Back to blog
cssflexbox

Back To Basic: Mental Model to Understand Flexbox

These are the mental models that I use to really understand flexbox, and I hope these can help you to understand too.

6 min read
14,385 views views

Introduction

When I first learned about Flexbox, I found it confusing. The properties, the terminology, the behavior – it all seemed overwhelming. But once I developed a mental model for how Flexbox works, everything clicked into place.

In this post, I'll share the mental models that helped me truly understand Flexbox. I hope they help you too!

The Container and Items Mental Model

The first and most important mental model is understanding that Flexbox works with two types of elements:

  1. Flex Container (the parent)
  2. Flex Items (the children)
html
<div class="flex-container"> <!-- This is the container -->
  <div>Item 1</div> <!-- These are the items -->
  <div>Item 2</div>
  <div>Item 3</div>
</div>
css
.flex-container {
  display: flex; /* This activates flexbox */
}

Think of the container as a manager and the items as employees. The manager (container) tells the employees (items) how to arrange themselves.

The Main Axis and Cross Axis

This is where many people get confused, but it's actually simple once you visualize it correctly.

Mental Model: Think of it as a coordinate system

  • Main Axis: The primary direction items flow (default: left to right)
  • Cross Axis: Perpendicular to the main axis (default: top to bottom)
txt
Main Axis (horizontal) →
   ┌──────────────────┐
   │  Item 1  Item 2  │ ↕ Cross Axis (vertical)
   └──────────────────┘

When you use flex-direction: column, the axes flip:

txt
Cross Axis (horizontal) →
   ┌────┐
   │Item│ ↕ Main Axis (vertical)
   │  1 │
   ├────┤
   │Item│
   │  2 │
   └────┘

Key takeaway: justify-content ALWAYS works on the main axis, and align-items ALWAYS works on the cross axis.

The "justify-content" Mental Model

Think of justify-content as "How should I distribute space between items along the main axis?"

css
.flex-container {
  display: flex;
  justify-content: space-between;
}

Mental Image: Imagine pushing items apart or pulling them together:

  • flex-start: Push all items to the start
  • flex-end: Push all items to the end
  • center: Pull all items to the center
  • space-between: Push items to edges, distribute space between
  • space-around: Give each item equal space around it
  • space-evenly: Distribute all space evenly

The "align-items" Mental Model

Think of align-items as "How should each item align itself on the cross axis?"

css
.flex-container {
  display: flex;
  align-items: center;
}

Mental Image: Imagine items on a shelf:

  • flex-start: Items sit on the top shelf
  • flex-end: Items sit on the bottom shelf
  • center: Items float in the middle
  • stretch: Items grow to fill the shelf (default)
  • baseline: Items align based on their text baseline

The "flex-grow, flex-shrink, flex-basis" Mental Model

This trio is powerful but often misunderstood. Here's my mental model:

flex-basis

Mental Model: "What's my starting size?"

css
.item {
  flex-basis: 200px; /* I want to start at 200px */
}

Think of it as your ideal size before any growing or shrinking happens.

flex-grow

Mental Model: "How greedy am I for extra space?"

css
.item-1 {
  flex-grow: 1; /* I'll take 1 unit of extra space */
}

.item-2 {
  flex-grow: 2; /* I'll take 2 units of extra space */
}

If there's extra space, item-2 will grow twice as much as item-1.

flex-shrink

Mental Model: "How much am I willing to shrink?"

css
.item {
  flex-shrink: 1; /* I'll shrink proportionally */
  flex-shrink: 0; /* I refuse to shrink! */
}

When space is tight, items with higher flex-shrink values will shrink more.

The Practical Mental Model

Here's how I think about common patterns:

Centering Everything

Mental thought: "Push to center on both axes"

css
.container {
  display: flex;
  justify-content: center; /* Center on main axis */
  align-items: center;     /* Center on cross axis */
  min-height: 100vh;
}

Mental thought: "Logo on left, links on right"

css
.navbar {
  display: flex;
  justify-content: space-between; /* Push items to edges */
  align-items: center;            /* Center vertically */
}

Card Grid that Wraps

Mental thought: "Let items wrap and space themselves evenly"

css
.card-container {
  display: flex;
  flex-wrap: wrap;           /* Allow wrapping */
  gap: 1rem;                 /* Space between items */
  justify-content: center;   /* Center the wrapped rows */
}

.card {
  flex: 0 0 300px; /* Don't grow, don't shrink, start at 300px */
}

Common Pitfalls and Mental Fixes

Pitfall 1: Items not taking full height

Mental fix: "Make sure container has a defined height"

css
.container {
  display: flex;
  min-height: 100vh; /* Give container a height! */
}

Pitfall 2: Items overflowing container

Mental fix: "Tell items they're allowed to shrink"

css
.item {
  flex-shrink: 1; /* Default, but be explicit */
  min-width: 0;   /* Allow shrinking below content size */
}

Pitfall 3: Unwanted gaps

Mental fix: "Remove default margins and use gap instead"

css
.container {
  display: flex;
  gap: 1rem; /* Use gap for consistent spacing */
}

.item {
  margin: 0; /* Remove item margins */
}

Conclusion

The key to mastering Flexbox is developing strong mental models. Remember:

  1. Container vs Items - Two different roles
  2. Axes - Main and cross, they can flip
  3. justify-content - Distribution along main axis
  4. align-items - Alignment along cross axis
  5. flex properties - Growing, shrinking, and sizing

With these mental models, you'll find Flexbox becomes intuitive rather than frustrating. Practice with these models in mind, and soon you'll be using Flexbox without even thinking about it!

Happy coding! 🎉