The Core Concept
Flexbox works on a container–item relationship. Apply display: flex to a parent — it becomes the flex container. Its direct children automatically become flex items. Flex properties on the container control how items are distributed; properties on the items control how individual items size and align themselves.
.container {
display: flex; /* turns element into flex container */
/* or: */
display: inline-flex; /* flex container that flows inline */
}
flex-direction – Main Axis
Controls the direction items flow. The main axis is the primary direction; the cross axis is perpendicular to it.
flex-direction: row; /* default — left to right */
flex-direction: row-reverse; /* right to left */
flex-direction: column; /* top to bottom */
flex-direction: column-reverse; /* bottom to top */
justify-content – Main Axis Alignment
Distributes space along the main axis (horizontal in row direction).
justify-content: flex-start; /* default — items at start */
justify-content: flex-end; /* items at end */
justify-content: center; /* items centered */
justify-content: space-between; /* first and last at edges, equal gaps between */
justify-content: space-around; /* equal space around each item (half at edges) */
justify-content: space-evenly; /* equal space between all items including edges */
↑ justify-content: space-between
↑ justify-content: center
align-items – Cross Axis Alignment
Aligns items along the cross axis (vertical in row direction). This is how you vertically center things.
align-items: stretch; /* default — items stretch to fill container height */
align-items: flex-start; /* items align to cross-axis start (top) */
align-items: flex-end; /* items align to cross-axis end (bottom) */
align-items: center; /* items centered on cross axis — vertical centering! */
align-items: baseline; /* items aligned by text baseline */
↑ align-items: center (all vertically centered)
flex-wrap
By default, flex items stay on one line even if they overflow. flex-wrap allows wrapping to multiple lines.
flex-wrap: nowrap; /* default — all on one line, may overflow */
flex-wrap: wrap; /* wrap to new lines as needed */
flex-wrap: wrap-reverse; /* wrap, but new lines go upward */
gap – Spacing Between Items
gap sets the space between flex items. Far cleaner than using margins on children.
gap: 16px; /* equal gap rows and columns */
gap: 16px 24px; /* row-gap: 16px, column-gap: 24px */
row-gap: 16px; /* between rows (when wrapping) */
column-gap: 24px; /* between columns */
flex-grow, flex-shrink, flex-basis
These three properties control how individual flex items size themselves relative to available space.
/* flex-grow — how much an item grows to fill extra space */
/* 0 = don't grow (default), 1 = take proportional share */
.item { flex-grow: 0; } /* stays its natural size */
.item { flex-grow: 1; } /* takes available space */
/* Multiple items with different grow values */
.sidebar { flex-grow: 0; width: 250px; } /* fixed width */
.main { flex-grow: 1; } /* fills the rest */
/* flex-shrink — how much to shrink when space is tight */
/* 1 = shrink proportionally (default), 0 = never shrink */
.logo { flex-shrink: 0; } /* logo never shrinks */
/* flex-basis — the initial size before grow/shrink */
.item { flex-basis: 200px; } /* start at 200px, then grow/shrink */
.item { flex-basis: auto; } /* use item's content size (default) */
.item { flex-basis: 0; } /* start at 0, grow proportionally */
/* flex shorthand: grow shrink basis */
.item { flex: 1; } /* grow:1, shrink:1, basis:0 — fills space equally */
.item { flex: 0 0 250px; } /* fixed 250px, no grow or shrink */
.item { flex: 1 1 auto; } /* default flex behavior */
align-self – Per-Item Cross Axis
Override align-items for a single flex item:
.container { display: flex; align-items: center; height: 120px; }
.item-default { /* inherits align-items: center */ }
.item-top { align-self: flex-start; }
.item-bottom { align-self: flex-end; }
.item-stretch { align-self: stretch; }
.item-auto { align-self: auto; } /* use container's align-items */
order – Visual Reordering
/* Default order is 0. Lower values appear first. */
.first { order: -1; } /* moves before all order:0 items */
.last { order: 1; } /* moves after all order:0 items */
/* Reverse order on mobile */
@media (max-width: 768px) {
.sidebar { order: 2; } /* sidebar below main on mobile */
.main { order: 1; } /* main above sidebar */
}
Screen readers and keyboard navigation follow DOM order, not visual order. Using order to reorder elements that matter to reading sequence or focus order creates an accessibility mismatch. Use it only for purely visual reordering where the logical reading order is unaffected.
Real-World Flexbox Patterns
/* 1. Perfect centering (horizontal + vertical) */
.center {
display: flex;
justify-content: center;
align-items: center;
}
/* 2. Navigation bar */
.nav {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24px;
height: 64px;
}
/* 3. Sidebar + main layout */
.page {
display: flex;
gap: 24px;
}
.sidebar { flex: 0 0 260px; }
.main { flex: 1; min-width: 0; } /* min-width: 0 prevents overflow */
/* 4. Card grid (wrapping) */
.card-grid {
display: flex;
flex-wrap: wrap;
gap: 24px;
}
.card { flex: 1 1 280px; } /* min 280px, grow to fill */
/* 5. Button group */
.btn-group {
display: inline-flex;
gap: 8px;
align-items: center;
}
/* 6. Push last item to the end */
.header {
display: flex;
align-items: center;
}
.header .spacer { flex: 1; } /* pushes everything after to the right */
/* 7. Responsive column stack */
.columns {
display: flex;
gap: 24px;
}
@media (max-width: 768px) {
.columns { flex-direction: column; }
}
The One-Liners Worth Memorizing (and the Overflow Gotcha)
Two flexbox recipes cover most real layouts. Perfect centering, both axes:
.center {
display: flex;
justify-content: center; /* main axis (horizontal by default) */
align-items: center; /* cross axis (vertical by default) */
}
A nav bar with logo left, links right:
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
}
Flex items have min-width: auto by default, which refuses to shrink below the content's size — so a long text or a wide child blows out the layout. The fix is min-width: 0 (or overflow: hidden) on the flex item. This one line resolves a surprising number of "my text won't truncate" bugs.
Remember the axis rule: justify-content works along the main axis, align-items along the cross axis. Set flex-direction: column and those axes swap — the source of much confusion.
🏋️ Practical Exercise
- Make a container
display: flex. - Switch
flex-directionbetween row and column. - Use
justify-contentto space items. - Use
align-itemsto center items vertically. - Make an item grow with
flex: 1.
🔥 Challenge Exercise
Build a responsive navbar with a logo on the left and links on the right using justify-content: space-between. Then build a hero where content is centered on both axes. Explain the difference between justify-content and align-items and what the main vs cross axis means.
📋 Summary
- display: flex — activates flexbox on the container. Children become flex items.
- flex-direction — row (default) or column. Sets the main axis.
- justify-content — main axis distribution.
center,space-between,space-evenly. - align-items — cross axis alignment.
center= vertical centering in row direction. - flex-wrap: wrap — allows items to wrap to multiple lines.
- gap — space between items. Cleaner than margins.
- flex: 1 — item grows to fill available space equally.
- flex: 0 0 250px — fixed-width item that neither grows nor shrinks.
- align-self — overrides align-items for one specific item.
- order — visual reorder only. DOM order unchanged.
Interview Questions
- What problem does flexbox solve?
- What is the difference between the main axis and the cross axis?
- What does
justify-contentcontrol versusalign-items? - What does
flex: 1mean? - How do you center an element both horizontally and vertically with flexbox?
Related Topics
FAQ
Flexbox is one-dimensional — best for laying out items in a single row or column (navigation bars, button groups, card rows, centering). Grid is two-dimensional — best for layouts that have both rows and columns simultaneously (full-page layouts, image galleries, complex dashboards). The practical rule: if you're thinking about rows OR columns, use flex. If you're thinking about rows AND columns at the same time, use grid. They can and should be combined — grid for the overall page, flexbox for components within it.
Apply to the parent: display: flex; align-items: center;. For both horizontal and vertical centering: display: flex; align-items: center; justify-content: center;. The parent must have a height larger than the content for this to be visible. Use min-height: 100vh to make it fill the viewport.
flex: 1 is shorthand for flex-grow: 1; flex-shrink: 1; flex-basis: 0%. The key part is flex-basis: 0 — the item starts at zero width and grows to fill its share of available space. When multiple items all have flex: 1, they split the available space equally. When one has flex: 2 and another flex: 1, the first gets double the space. Compare with flex: auto which uses flex-basis: auto (content size) before distributing remaining space.
A flex item with min-width: auto (the default) won't shrink below its content width. Add min-width: 0 to the overflowing item — this allows it to shrink below its content size. This is especially important for items containing long text, pre-formatted code blocks, or images. The fix is almost always min-width: 0 on the flex item, or overflow: hidden if you want to clip the content.

