Design

CSS Flexbox for Beginners: Main vs Cross Axis, justify-content, align-items

Flexbox is a CSS layout method that arranges elements in a row or column and controls spacing and stretching with very little code. This article explains what display:flex is, the idea of the main and cross axes, placement with justify-content and align-items, wrapping with flex-wrap, the roles of flex-grow/shrink/basis, staple layouts like centering and even spacing, and when to use Grid instead.

Published: 2026-10-16

When building web pages, situations like "I want this menu in a horizontal row," "I want this button in the center of the screen," or "I want these cards evenly spaced" come up constantly. In the past these were achieved with floats, tables, or fiddly margin tweaks, but today Flexbox lets you build them intuitively with far less code. This article explains, step by step, what Flexbox is and how it thinks.

What Flexbox Is: The Basics of display:flex

Flexbox (formally CSS Flexible Box Layout) is a CSS layout module for arranging elements in one direction (horizontal or vertical) and flexibly controlling the spacing and stretching between them. The key idea is that you apply the style not to the elements you want to arrange, but to their parent element.

Using it is very simple: just set display: flex; on the parent element that wraps the children you want to arrange.

.container { display: flex; }

The parent with display: flex; is called the flex container, and its direct children are called flex items. The moment you declare flex on the container, the children automatically line up horizontally. This is why <div> elements, which are block-level, line up from the left with no extra work.

To see what code produces what appearance, it is easiest to switch properties around in the Flexbox Generator. The preview changes every time you adjust a value, so you can understand each property's effect with your own eyes.

The Idea of the Main and Cross Axes

The most important thing for understanding Flexbox is the concept of two axes: the main axis and the cross axis. Once you grasp these two, the properties introduced later fall neatly into place.

  • Main axis: the axis along which flex items line up. By default this is the horizontal "left to right" direction.
  • Cross axis: the axis perpendicular to the main axis. If the main axis is horizontal, the cross axis is the vertical "top to bottom" direction.

The flex-direction property decides the direction of the main axis. Changing its value rotates the axis itself.

flex-direction valueMain axis directionArrangement
row (default)left to rightHorizontal
row-reverseright to leftHorizontal (reversed)
columntop to bottomVertical
column-reversebottom to topVertical (reversed)

What matters here is that when the main axis direction changes, the direction in which the placement properties take effect changes with it. For example, setting flex-direction: column; makes the main axis vertical, so a property that handled horizontal placement now acts vertically. Always being aware of "which one is the main axis" is the shortcut to mastering Flexbox.

Placing Items with justify-content and align-items

Once you understand the axes, the placement properties become much easier. Placement in Flexbox is decided mainly by two properties.

1. justify-content (placement along the main axis)

justify-content specifies how items are arranged along the main axis. By default (main axis horizontal) it controls how they are pushed left or right and how spacing is distributed.

ValueEffect
flex-startPush to the start of the main axis (left)
centerPush to the center
flex-endPush to the end of the main axis (right)
space-betweenPin both ends, space between them evenly
space-aroundEqual space on each side of every item
space-evenlyAll gaps completely equal

2. align-items (placement along the cross axis)

align-items specifies how items are aligned along the cross axis. By default (cross axis vertical) it controls vertical alignment. Setting center aligns them to the vertical center, while stretch (the default) stretches them to fill the container's height.

Combining just these two lets you achieve perfect centering both horizontally and vertically, long considered difficult, in only three lines. Just add justify-content: center; and align-items: center; to display: flex;. There is also align-content, which controls how rows align to each other when items wrap onto multiple lines, but grasping these two first is enough.

Wrapping with flex-wrap

By default, Flexbox tries to cram items onto a single line without wrapping. Even if the total width of the items exceeds the container, each item shrinks to force itself onto one line. The flex-wrap property controls this.

  • nowrap (default): do not wrap; fit on one line.
  • wrap: wrap items that do not fit onto the next line.
  • wrap-reverse: wrap in the reverse direction.

Setting flex-wrap: wrap; makes it easy to create responsive behavior: on narrow smartphone screens cards naturally wrap onto multiple lines, while on wide desktops they line up in a single row. You can also write flex-direction and flex-wrap together using the one-line shorthand flex-flow.

Controlling Stretch with flex-grow / shrink / basis

So far the properties applied to the parent (container), but the stretching of individual items is specified on the items themselves. This is the heart of the "Flexible" in Flexbox. There are three properties.

PropertyRole
flex-growIn what ratio it grows to share leftover space
flex-shrinkIn what ratio it shrinks when space is short
flex-basisThe baseline width (or height) before stretching

flex-grow is a number expressing the proportion by which an item absorbs leftover space and grows when the container has space to spare. The default is 0, which means no growth. Setting flex-grow: 1; on an item makes that item absorb all the leftover space and expand. Assigning 1 and 2 to multiple items shares the space in a 1:2 ratio.

flex-shrink is the opposite: the proportion by which an item shrinks when space is short. The default is 1, so items shrink as needed on their own. Setting 0 means "do not let this item shrink."

flex-basis is the baseline size before stretching begins. It plays a role close to width, but the final size is decided in combination with flex-grow and flex-shrink. These three are commonly written together with the flex shorthand, as in flex: 1;. The value flex: 1; means "share leftover space evenly and end up the same width," the most common setting in practice. Since value combinations can get complicated, it helps to move the numbers around in the Flexbox Generator and watch the behavior.

Common Layouts and the Difference from Grid

Finally, let us organize the staple layouts that come up often with Flexbox, and when to use it versus the similar CSS Grid.

Staple layouts

  • Perfect centering: the three-piece set of display: flex; justify-content: center; align-items: center;.
  • A header aligned to both ends: to put a logo on the left and a menu on the right, justify-content: space-between; is handy.
  • Evenly spaced cards: with flex-wrap: wrap;, flex: 1; on each card, and the gap property for spacing, you can build an even card layout.

The difference between Flexbox and Grid

Flexbox is often compared with CSS Grid. The biggest difference lies in the number of dimensions they handle.

FlexboxGrid
Best directionOne dimension (horizontal or vertical)Two dimensions (both rows and columns)
ApproachControl the flow of content by axisDefine a grid in advance and place items
Good forMenus, button groups, single-line alignmentWhole pages, grid-style card layouts

Roughly speaking, remember: use Flexbox to arrange things in one direction, and Grid when you want precise control over both rows and columns. In practice, it is common to use both together, building the page's overall skeleton with Grid and arranging the fine parts inside with Flexbox. When you want to try out a grid, build one in the CSS Grid Generator and compare it side by side with the Flexbox Generator to see clearly how their roles differ.

Flexbox is a powerful mechanism that, once you understand the two axes (main and cross), lets you achieve exactly the placement you want with little code. The shortcut to learning it is to change values yourself and watch how the preview changes with your own eyes.

Please note that this article is intended to provide general information. CSS specifications and browser support can change. When implementing, make your decision after checking the latest official information and documentation.

FAQ

What is Flexbox?

Flexbox (CSS Flexible Box Layout) is a CSS layout method for arranging elements in one direction, horizontal or vertical, and flexibly controlling the spacing and stretching between them. Just set display: flex; on the parent element that wraps the children, and the children automatically line up horizontally. It lets you build placement intuitively with little code.

What are the main axis and the cross axis?

The main axis is the direction along which flex items line up, by default left to right (horizontal). The cross axis is perpendicular to it, by default top to bottom (vertical). When you change the main axis direction with flex-direction, the direction in which justify-content and align-items take effect changes too, so always be aware of which is the main axis.

How do I center an element both horizontally and vertically?

Set display: flex; on the parent, then add justify-content: center; (centering along the main axis = horizontal) and align-items: center; (centering along the cross axis = vertical). Perfect centering, once considered difficult, is achieved in just three lines.

What does flex: 1; mean?

flex: 1; is a shorthand that writes flex-grow, flex-shrink, and flex-basis together, roughly equivalent to flex-grow: 1; flex-shrink: 1; flex-basis: 0;. Setting it on multiple items makes each share the leftover space evenly and end up the same width. It is the most common setting for even layouts.

Is the WAZA TOOLS Flexbox Generator free, and is my data safe?

WAZA TOOLS' Flexbox Generator runs entirely in your browser, so what you enter is never sent to or stored on a server. It works on smartphones too, and you can generate CSS code as many times as you like, for free.