Door 5 – Flexbox Fundamentals | CSS Adventskalender
Skip to content

Door 5 – Flexbox Fundamentals

Published: at 07:00 AM

Flexbox is one of the most important layout tools in modern CSS. Yet even though it has been a standard for years, I see the same stumbling blocks in code reviews again and again. Flexbox seems simple at first glance, but many of its rules are not intuitive, and that is exactly what leads to unexpected behavior in everyday life.

Those who really understand Flexbox build more stable layouts, avoid unnecessary overrides, and save a huge amount of debugging time. That’s why I’m dedicating an entire door to this topic before moving on to advanced Flexbox patterns in the next step.

The Central Idea of Flexbox

Flexbox is a layout model for one dimension.

This means:

The most important question for every Flexbox component is therefore:

What is the main axis? Horizontal or vertical?

Only when that is clear do the rest of the properties make sense.

The Most Important Entry Point: flex-direction

Many mistakes happen because the main axis is not consciously defined.

.container {
  display: flex;
  flex-direction: row;   /* Default */
}

Vertical layouts:

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

In real projects, flex-direction is surprisingly often forgotten, and people then wonder why, for example, justify-content doesn’t do what they expect.

justify-content vs. align-items – The Most Common Confusion

The basic rule is simple:

If flex-direction: row:

justify-content: center; /* align horizontally */
align-items: center;     /* align vertically */

If flex-direction: column:

justify-content: center; /* align vertically */
align-items: center;     /* align horizontally */

Many “Flexbox isn’t working” bugs are actually just a case of swapped axes.

An Example: Button Group

A developer wants to distribute buttons evenly in a row:

.btn-group {
  display: flex;
  justify-content: space-between;
}

So far so good. But then the group should work vertically:

.btn-group {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

Suddenly space-between distributes not horizontally but vertically! Many change only flex-direction but don’t understand that this changes the entire axis logic – and wonder about shifted layouts.

flex-grow, flex-shrink, flex-basis – The Engine of Flexbox

Flexbox distributes available space dynamically. The key lies in the three sub-properties of flex:

flex-grow

How much additional available space an item may take up.

.item {
  flex-grow: 1; /* Item may grow */
}

flex-shrink

How much items may shrink if there is not enough space.

.item {
  flex-shrink: 0; /* Item may NOT shrink */
}

A common mistake in real projects:

input {
  flex: 1;
}

This means:

flex-grow: 1
flex-shrink: 1
flex-basis: 0

Shrinking can lead to input fields becoming smaller than expected.

flex-basis

The starting width (or height) of an item.

.card {
  flex-basis: 200px;
}

A classic: flex-basis takes precedence over width if both are set – unless flex-basis is auto, then width applies again.

Practical Example: Three Cards with Automatic Space Behavior

Many teams build the following grid:

.cards {
  display: flex;
}

.card {
  flex: 1;
  margin: 1rem;
}

The problem: On small screens, the cards shrink to illegibility because flex-shrink: 1 is active.

The better variant:

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

With this:

This pattern is robust and is one of the central Flexbox patterns.

gap – The Underestimated Game Changer

For years, spacing in Flexbox was a pain point. Now there is gap – and it solves many of these problems.

Previously:

.item {
  margin-right: 1rem;
}

Today:

.container {
  display: flex;
  gap: 1rem;
}

No selector problems. No negative margins. No last elements that need to be corrected.

Modern layouts should almost always use gap instead of margin for internal spacing.

Common Flexbox Traps in Large Projects

1. The default align-items: stretch is not considered

Default behavior with row:

This often leads to:

The solution: set align-items explicitly:

.form-group {
  display: flex;
  align-items: center;
}

Without explicit align-items, stretch remains active and causes unclean line heights.

2. Fixed Heights + Flexbox = Problems

Many teams declare:

.header {
  display: flex;
  height: 60px;
}

If the content then overflows, the layout breaks or changes invisibly. Better:

.header {
  min-height: 60px;
}

Flexbox is made for flexible layouts – fixed heights often contradict this.

3. Flexbox is used where Grid would be better

Typical case:

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

But if you actually need a 2D layout, Grid is clearer and more stable. Flexbox should only be used when you think in one axis.

A Small Practical Pattern: Flexbox for Centering

The most important Flexbox pattern of all:

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

You use it so often that it pays to maintain it as a utility.

Conclusion

Flexbox seems simple, but its logic differs strongly from the classic Box Model. Those who understand the basic principles – main axis, grow/shrink/basis, and the role of align/justify – solve layout problems faster and build more robust components.

Door 6 continues with Flexbox Patterns that appear in every codebase and that you should simply have in your head in everyday life.


☕ Buy me a coffee

If you enjoy my articles and they help you in your work, I would appreciate a "coffee" and a few kind words from you.

Buy me a coffee

Previous Post
Door 6 – Everyday Flexbox Patterns
Next Post
Door 4 – Mastering the Box Model

Comments