Difficulty: Intermediate
Flexbox (Flexible Box Layout) is a one-dimensional layout model designed for distributing space and aligning items within a container. Unlike older layout methods (floats, inline-block, tables), Flexbox was purpose-built for component layout and provides powerful alignment capabilities with minimal code. It operates along a single axis at a time -- either a row (horizontal) or a column (vertical) -- which is why it is called one-dimensional.
To activate Flexbox, you set display: flex on a container element. This makes the element a flex container, and all of its direct children automatically become flex items. By default, flex items are laid out in a single row from left to right, they stretch to fill the container's height, and they shrink to fit if the container is too narrow. The container itself behaves as a block-level element. You can also use display: inline-flex to create an inline-level flex container.
The flex-direction property controls the main axis -- the primary direction in which flex items are laid out. The four values are row (left to right, the default), row-reverse (right to left), column (top to bottom), and column-reverse (bottom to top). When flex-direction is row, the main axis is horizontal and the cross axis is vertical. When flex-direction is column, the main axis is vertical and the cross axis is horizontal. Understanding which axis is 'main' and which is 'cross' is critical because all Flexbox alignment properties reference these axes.
The flex-wrap property controls whether flex items are forced onto a single line or can wrap onto multiple lines. The default value nowrap squeezes all items onto one line, shrinking them if necessary. The value wrap allows items to flow onto additional lines when they would overflow the container. The value wrap-reverse wraps in the opposite direction. The shorthand flex-flow combines flex-direction and flex-wrap into a single declaration: flex-flow: row wrap.
A common source of confusion is the relationship between flex-direction and the concepts of 'main axis' and 'cross axis'. In row direction, justify-content works horizontally and align-items works vertically. In column direction, justify-content works vertically and align-items works horizontally. The properties always operate on the same axes (justify on main, align on cross), but which physical direction those axes correspond to changes with flex-direction.
.container {
display: flex;
background-color: #f3f4f6;
padding: 16px;
gap: 12px;
}
.item {
background-color: #3b82f6;
color: white;
padding: 20px;
border-radius: 8px;
}
Setting display: flex on the container causes all direct children (.item) to be laid out in a horizontal row. By default, items are placed left to right with no wrapping. The gap property adds consistent spacing between items.
/* Default: horizontal left-to-right */
.row {
display: flex;
flex-direction: row;
}
/* Horizontal right-to-left */
.row-reverse {
display: flex;
flex-direction: row-reverse;
}
/* Vertical top-to-bottom */
.column {
display: flex;
flex-direction: column;
}
/* Vertical bottom-to-top */
.column-reverse {
display: flex;
flex-direction: column-reverse;
}
flex-direction controls the main axis. With row, items flow horizontally; with column, items flow vertically. The -reverse variants flip the order without changing the DOM. This is useful for right-aligned navigation or bottom-up stacking.
.no-wrap {
display: flex;
flex-wrap: nowrap; /* default: items shrink to fit */
}
.wrap {
display: flex;
flex-wrap: wrap; /* items flow to new lines */
gap: 16px;
}
.wrap .item {
width: 200px; /* items maintain width and wrap */
}
With nowrap (default), items are compressed onto one line even if they overflow. With wrap, items maintain their width and flow to the next line when the container is too narrow. This is essential for responsive card grids.
/* Longhand */
.container-long {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
/* Shorthand: flex-flow: <direction> <wrap> */
.container-short {
display: flex;
flex-flow: row wrap;
}
/* Column with wrapping */
.sidebar {
display: flex;
flex-flow: column nowrap;
height: 100vh;
}
flex-flow is a shorthand for flex-direction and flex-wrap. The first value is the direction and the second is the wrap behavior. This reduces two declarations to one.
display:flex, flex-direction, flex-wrap, flex-flow