CSS Flexbox Complete Guide - Learn Flexbox in 2026

What Is Flexbox

CSS Flexible Box Layout, commonly known as Flexbox, is a one-dimensional layout model that provides an efficient way to distribute space among items in a container and align them, even when their sizes are unknown or dynamic. The specification was first proposed in 2009 and reached Candidate Recommendation status in 2012. Today it is supported by every modern browser and is one of the most widely used CSS layout techniques.

Before Flexbox, developers relied on floats, inline-block elements, and table display modes to create layouts. These techniques were workarounds rather than proper layout tools. They required clearfix hacks, negative margins, and complex calculations to achieve layouts that Flexbox handles naturally. Centering an element vertically, creating equal-height columns, and distributing space proportionally were all notoriously difficult problems that Flexbox solves with a few lines of CSS.

The term "one-dimensional" means Flexbox handles layout in one direction at a time: either as a row (horizontal) or as a column (vertical). This distinguishes it from CSS Grid, which handles both rows and columns simultaneously. Flexbox and Grid are complementary tools. Most modern layouts use both, applying Flexbox for component-level layouts and Grid for page-level layouts.

Flexbox operates on a parent-child relationship. The parent element becomes a flex container by setting display: flex. Its direct children automatically become flex items. Properties on the container control the overall layout direction, wrapping, and alignment. Properties on individual items control how each item grows, shrinks, and positions itself within the container.

To experiment with Flexbox properties visually and generate the CSS code instantly, try our Flexbox Generator tool.

The Flex Container

A flex container is created by setting display: flex (or display: inline-flex for an inline-level flex container) on an element. This single declaration changes the layout behavior of all direct children.

.container {
  display: flex;
}

When you set display: flex, several things happen immediately. The direct children of the container become flex items. They lay out in a row (the default flex-direction). They take up only as much width as their content requires. They stretch to fill the full height of the container. Floats on flex items have no effect. Vertical-align on flex items has no effect.

The difference between flex and inline-flex is how the container itself behaves in the document flow. display: flex makes the container a block-level element that takes the full width of its parent. display: inline-flex makes it an inline-level element that only takes the width needed by its contents, allowing other inline elements to sit alongside it.

Flexbox introduces two axes that govern how items are placed. The main axis runs in the direction specified by flex-direction (horizontal by default). The cross axis runs perpendicular to the main axis (vertical by default). Understanding these axes is essential because most Flexbox properties operate relative to them, not relative to "horizontal" or "vertical."

flex-direction

The flex-direction property sets the main axis direction, which determines how flex items are placed in the container. It accepts four values:

.container {
  display: flex;
  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 */
}

row is the default value. Items are laid out from left to right (in left-to-right languages). The main axis is horizontal and the cross axis is vertical.

row-reverse lays items out from right to left. The first item in the DOM appears on the right side of the container.

column changes the main axis to vertical. Items stack from top to bottom, like a traditional block layout. The cross axis becomes horizontal.

column-reverse stacks items from bottom to top. This is useful for chat interfaces where the most recent message should appear at the bottom and the list should be scrollable upward.

Tip: When you switch to column or column-reverse, remember that justify-content now controls vertical alignment and align-items controls horizontal alignment. The properties always refer to the main and cross axes, regardless of their visual orientation.

flex-wrap

By default, flex items try to fit on one line. The flex-wrap property controls whether items can wrap to multiple lines when they overflow the container.

.container {
  display: flex;
  flex-wrap: nowrap;       /* default: single line, items may shrink */
  flex-wrap: wrap;         /* items wrap to new lines as needed */
  flex-wrap: wrap-reverse; /* items wrap in reverse order */
}

nowrap is the default. All items are forced onto a single line. If the total width of items exceeds the container width, items will shrink (if allowed by flex-shrink) or overflow the container.

wrap allows items to wrap to new lines. When items exceed the container width, additional items flow to the next line below (or to the right, in column direction). Each line is treated as a separate flex line with its own alignment.

wrap-reverse wraps items in the reverse direction. New lines appear above the first line rather than below it.

The shorthand flex-flow combines flex-direction and flex-wrap into one declaration: flex-flow: row wrap is equivalent to setting flex-direction: row and flex-wrap: wrap separately.

justify-content

The justify-content property controls how flex items are distributed along the main axis. It determines what happens to the extra space when items do not fill the entire container.

.container {
  display: flex;
  justify-content: flex-start;    /* default: items pack to the start */
  justify-content: flex-end;      /* items pack to the end */
  justify-content: center;        /* items center on the main axis */
  justify-content: space-between; /* equal space between items */
  justify-content: space-around;  /* equal space around items */
  justify-content: space-evenly;  /* equal space between and around */
}

flex-start is the default. Items are packed toward the start of the main axis with no extra space between them.

flex-end packs items toward the end of the main axis. In a row layout, this pushes items to the right.

center centers items along the main axis. The remaining space is split equally before and after the group of items.

space-between distributes items evenly. The first item is flush with the start edge and the last item is flush with the end edge. The remaining space is divided equally between adjacent items. This is ideal for navigation bars where you want items spread across the full width.

space-around distributes items with equal space around each item. This means the space between two adjacent items is twice the space between an item and the container edge.

space-evenly distributes items with equal space between every pair of adjacent items and between items and the container edges. The visual spacing is perfectly uniform throughout.

align-items

The align-items property controls how flex items are aligned along the cross axis. In a row layout, this means vertical alignment. In a column layout, this means horizontal alignment.

.container {
  display: flex;
  align-items: stretch;    /* default: items stretch to fill */
  align-items: flex-start; /* items align to the cross start */
  align-items: flex-end;   /* items align to the cross end */
  align-items: center;     /* items center on the cross axis */
  align-items: baseline;   /* items align on text baseline */
}

stretch is the default. Items stretch to fill the container's cross-axis dimension. In a row layout, this means all items become the same height as the tallest item. This is why flex items automatically get equal heights, which was historically one of the hardest layout problems to solve.

flex-start aligns items to the start of the cross axis. In a row layout, items align to the top of the container.

flex-end aligns items to the end of the cross axis. In a row layout, items align to the bottom.

center centers items on the cross axis. Combined with justify-content: center, this creates the simplest perfect centering solution in CSS.

baseline aligns items so that their text baselines line up. This is useful when items have different font sizes or padding but you want their text to sit on the same line.

align-content

The align-content property controls how multiple flex lines are distributed along the cross axis. It only has an effect when flex-wrap is set to wrap or wrap-reverse and there are multiple lines of items.

.container {
  display: flex;
  flex-wrap: wrap;
  align-content: stretch;       /* default: lines stretch to fill */
  align-content: flex-start;    /* lines pack to the start */
  align-content: flex-end;      /* lines pack to the end */
  align-content: center;        /* lines center in the container */
  align-content: space-between; /* equal space between lines */
  align-content: space-around;  /* equal space around lines */
  align-content: space-evenly;  /* equal space between and around */
}

Think of align-content as the cross-axis equivalent of justify-content, but for flex lines rather than individual items. If you have a wrapping flex container with items that form three lines, align-content: space-between will spread those three lines evenly across the cross axis with the first line at the top and the last line at the bottom.

gap

The gap property (also available as row-gap and column-gap) creates space between flex items without adding margins. This is the preferred modern approach to spacing flex items.

.container {
  display: flex;
  gap: 16px;            /* equal row and column gap */
  gap: 16px 24px;       /* row-gap column-gap */
  row-gap: 16px;        /* vertical gap between wrapped lines */
  column-gap: 24px;     /* horizontal gap between items */
}

Before gap was supported in Flexbox, developers used margins on items and negative margins on the container to create spacing. The gap property is cleaner because it only creates space between items, not before the first item or after the last item. It also works correctly with wrapping without requiring complex margin calculations.

The gap property for Flexbox is supported in all modern browsers. It was the last major browser to add support when Safari implemented it in version 14.1 in 2021.

Flex Item Properties

While container properties control the overall layout, item properties control how individual items behave within the flex container.

order

The order property controls the visual order of flex items without changing the DOM order. Items are sorted by their order value from lowest to highest. Items with the same order value appear in their DOM order.

.item-a { order: 2; }  /* appears second */
.item-b { order: 1; }  /* appears first */
.item-c { order: 3; }  /* appears third */

The default order value is 0. Setting an item to order: -1 moves it before all items with the default order. Use this sparingly, as visual order that differs from DOM order can create accessibility issues for keyboard navigation and screen readers.

flex-grow

The flex-grow property defines how much of the remaining space in the container should be assigned to the item. It accepts a unitless number that represents a proportion. The default value is 0, meaning items do not grow by default.

/* All items grow equally to fill the container */
.item { flex-grow: 1; }

/* Item B gets twice the extra space as A and C */
.item-a { flex-grow: 1; }
.item-b { flex-grow: 2; }
.item-c { flex-grow: 1; }

If there are 300px of remaining space in a container and three items have flex-grow: 1, each item receives 100px of extra space. If one item has flex-grow: 2 and the other two have flex-grow: 1, the first item gets 150px and the others get 75px each.

flex-shrink

The flex-shrink property defines how much an item should shrink when there is not enough space in the container. The default value is 1, meaning all items shrink equally by default. Setting flex-shrink: 0 prevents an item from shrinking.

/* Sidebar stays fixed width, main content shrinks */
.sidebar { flex-shrink: 0; width: 250px; }
.main    { flex-shrink: 1; }

flex-basis

The flex-basis property defines the initial size of a flex item before growing or shrinking is applied. It can be a length (200px, 30%), the keyword auto (use the item's width/height), or the keyword content (size based on content).

.item {
  flex-basis: auto;  /* default: use width/height property */
  flex-basis: 200px; /* start at 200px before grow/shrink */
  flex-basis: 30%;   /* start at 30% of container */
  flex-basis: 0;     /* start from zero, grow proportionally */
}

When flex-basis is set, it overrides the width property (or height in column direction) for the purpose of flex calculations. If flex-basis is auto, the item's width property is used as the basis.

align-self

The align-self property overrides the container's align-items value for a specific item. It accepts the same values: auto, flex-start, flex-end, center, baseline, and stretch.

.container { align-items: flex-start; }
.special-item { align-self: center; } /* only this item centers */

The flex Shorthand

The flex shorthand property combines flex-grow, flex-shrink, and flex-basis into one declaration. Understanding this shorthand is important because its default values differ from setting the individual properties separately.

/* flex: grow shrink basis */
.item { flex: 0 1 auto; }    /* default when using individual props */
.item { flex: initial; }      /* same as 0 1 auto */
.item { flex: auto; }         /* same as 1 1 auto */
.item { flex: none; }         /* same as 0 0 auto */
.item { flex: 1; }            /* same as 1 1 0% */
.item { flex: 2; }            /* same as 2 1 0% */
.item { flex: 1 200px; }      /* same as 1 1 200px */

The important distinction: when you write flex: 1, the flex-basis becomes 0%, not auto. This means items start from zero size and grow proportionally. With flex-basis: auto, items start from their content size and then grow to fill extra space. The difference matters when items have different content sizes and you want them to be exactly equal widths.

Tip: The CSS specification recommends using the flex shorthand rather than setting the individual properties. The shorthand correctly resets unspecified values. Most commonly, you will use flex: 1 for items that should share space equally, flex: none for items that should not grow or shrink, and flex: auto for items that should grow but start from their content size.

Common Flexbox Layout Patterns

Perfect Centering

Centering an element both horizontally and vertically is the simplest practical use of Flexbox:

.center-container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

Navigation Bar

A navigation bar with a logo on the left and links on the right:

.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 24px;
  height: 64px;
}

.nav-links {
  display: flex;
  gap: 24px;
  list-style: none;
}

Sidebar Layout

A fixed-width sidebar with a flexible main content area:

.layout {
  display: flex;
  min-height: 100vh;
}

.sidebar {
  flex: 0 0 280px; /* no grow, no shrink, 280px basis */
}

.main {
  flex: 1; /* grows to fill remaining space */
  padding: 24px;
}

Card Grid with Wrapping

A responsive card layout that adjusts to the container width:

.card-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

.card {
  flex: 1 1 300px; /* grow, shrink, min 300px basis */
  max-width: 400px;
}

Sticky Footer

A page layout where the footer always stays at the bottom, even when content is short:

.page {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.header { /* fixed height */ }
.main   { flex: 1; } /* grows to push footer down */
.footer { /* fixed height */ }

Equal Height Columns

Columns that automatically match the height of the tallest column:

.columns {
  display: flex;
  gap: 24px;
}

.column {
  flex: 1;
  /* All columns automatically stretch to equal height */
  /* because align-items defaults to stretch */
}

To generate these layout patterns and more with a visual interface, use our Flexbox Generator. For two-dimensional grid layouts, our CSS Grid Generator provides similar visual generation for Grid-based designs.

Flexbox vs CSS Grid

Flexbox and CSS Grid serve different purposes and work best in different situations. Understanding when to use each one will help you write cleaner, more maintainable CSS.

Use Flexbox when your layout is one-dimensional. Navigation bars, toolbars, card rows, form layouts, and component internal layouts are all natural fits for Flexbox. Items flow in one direction and wrap to new lines if needed. The content drives the size of items.

Use CSS Grid when your layout is two-dimensional. Page layouts, dashboards, image galleries with defined grid structures, and any layout where you need to control both rows and columns simultaneously are better suited to Grid. The layout drives the placement of items.

In practice, most modern web pages use both. A typical approach is to use Grid for the overall page structure (header, sidebar, main content, footer) and Flexbox for the components within each section (navigation links, card groups, form elements). The two systems work perfectly together and can be nested freely.

One practical difference: Flexbox distributes space along a single axis based on content sizes and flex ratios. Grid defines a rigid grid structure and places items into cells. If you want items to wrap naturally based on their content size, use Flexbox. If you want items to align in a strict grid regardless of content size, use Grid.

Practical Tips and Gotchas

Years of working with Flexbox have revealed certain patterns and pitfalls that come up repeatedly. Here are the most important ones to know.

The min-width: auto problem is the most common source of Flexbox layout bugs. Flex items have a default min-width of auto, which means they cannot shrink below their content size. If you have a flex item containing a long word, a wide image, or a pre element, the item will overflow its container rather than shrinking. The fix is to add min-width: 0 to the flex item, which allows it to shrink below its content size. You may also need overflow: hidden to clip the overflowing content.

/* Item overflows because min-width: auto prevents shrinking */
.container { display: flex; width: 300px; }
.item { flex: 1; } /* will overflow if content is wider than 300px */

/* Fix: allow item to shrink below content size */
.item { flex: 1; min-width: 0; overflow: hidden; }

Margins work differently in Flexbox. Specifically, margin: auto in a flex context absorbs all available free space in that direction. This creates a powerful alignment tool. For example, margin-left: auto on a flex item pushes it and all subsequent items to the right edge. This technique is commonly used to push a single item (like a login button) to the far right of a navigation bar.

Images in flex containers need special attention. By default, images will stretch because align-items: stretch is the default. Set align-self: flex-start on image items to prevent unwanted stretching, or set an explicit width/height on the image.

Percentage-based heights in flex items can be unpredictable. If you need a flex item to have a percentage height relative to the container, make sure the container has a defined height (not just min-height). Alternatively, use flex-basis with a percentage for more predictable sizing.

For visual design tasks beyond layout, our Border Radius Generator helps you create rounded corners with visual feedback, and our Box Shadow Generator lets you design shadows interactively. When converting between pixel values and relative units for responsive designs, our PX to REM Converter handles the math.

Accessibility note: The order property and flex-direction: row-reverse / column-reverse change the visual order of items without changing the DOM order. Screen readers and keyboard navigation follow the DOM order. If the visual order and DOM order diverge significantly, keyboard users will experience a confusing tab order. Use these properties sparingly and test with keyboard navigation.

Frequently Asked Questions

Flexbox is a one-dimensional layout system designed for laying out items in a single row or column. CSS Grid is a two-dimensional layout system designed for laying out items in rows and columns simultaneously. Use Flexbox for components like navigation bars, card rows, and form layouts where items flow in one direction. Use Grid for full page layouts, dashboard grids, and any layout that requires precise control over both rows and columns at the same time. They work well together and are not mutually exclusive.

To center an element both horizontally and vertically with Flexbox, set the parent container to display: flex, justify-content: center, and align-items: center. The parent also needs a defined height (such as min-height: 100vh for full viewport centering). This is the simplest and most reliable centering technique in CSS and works for any number of child elements.

flex: 1 is a shorthand that sets flex-grow: 1, flex-shrink: 1, and flex-basis: 0%. This tells the item to grow and fill available space equally with other flex: 1 items. If three items all have flex: 1, each takes up one-third of the available space. The flex-basis of 0% means the items start from zero width (or height) and grow from there, rather than starting from their content size.

Flex items may not shrink for several reasons. The most common cause is that min-width defaults to auto in flex items, which prevents them from shrinking below their content size. Fix this by setting min-width: 0 on the item. Another common cause is overflow content like long words or URLs that prevent shrinking. Set overflow: hidden or word-break: break-word on the item. Also check that flex-shrink is not set to 0, which explicitly disables shrinking.

Yes. Flexbox has full support in all modern browsers including Chrome, Firefox, Safari, Edge, and Opera. It has been fully supported since approximately 2015. Internet Explorer 11 has partial support with known bugs, but IE 11 reached end of life in June 2022. You can use Flexbox in production without vendor prefixes or fallbacks for any browser released in the last several years.

Wikipedia

CSS Flexible Box Layout, commonly known as Flexbox, is a CSS layout model that provides an efficient way to lay out, align, and distribute space among items in a container.

Source: Wikipedia - CSS Flexible Box Layout · Verified March 20, 2026

Stack Overflow Community

2341How to center a div with flexbox876Flexbox vs CSS Grid654Understanding flex-grow, flex-shrink

Video Tutorials

▶ Watch related tutorials on YouTube

Quick Facts

Properties
12
Axes
Main + Cross
Support
98%+
Spec
W3C CR

Update History

March 20, 2026 - Article published with comprehensive coverage
March 19, 2026 - Research and drafting completed

Browser Compatibility

Chrome 90+ Firefox 88+ Safari 14+ Edge 90+ Opera 76+

Last Updated: March 20, 2026