CSS Flex Item Properties

Turning a container into a flex container with display: flex is only half the story. The properties you apply to the children of that container — the flex items — are what actually decide how each item grows, shrinks, spaces itself out, and even reorders itself on screen. This lesson covers order, flex-grow, flex-shrink, flex-basis, the flex shorthand, and align-self: the full toolkit for controlling individual items inside a flex layout.

Overview / How It Works

When a parent element has display: flex (or inline-flex), every direct child becomes a flex item. The flex container establishes a main axis (the direction items lay out in, controlled by flex-direction) and a cross axis (perpendicular to it). All the item-level properties in this lesson are interpreted relative to those two axes, which is why the same property can behave differently depending on whether flex-direction is row or column.

The browser’s layout engine runs a specific algorithm for flex items. First, it computes each item’s hypothetical main size from its flex-basis (or its content/width if flex-basis is auto). Then it sums those sizes and compares the total to the space available on the main axis. If there is leftover space, it is distributed to items according to their flex-grow factor. If items overflow the container, the deficit is removed from items according to their flex-shrink factor (weighted by their basis). This single pass is what makes flexbox so good at flexible, content-aware layouts — you describe growth and shrink ratios instead of hard-coding pixel widths.

order and align-self

Two more properties sit outside that grow/shrink calculation. order changes the visual position of an item along the main axis without touching the underlying document structure — the DOM order, source order for screen readers, and default tab order are unaffected. align-self overrides the container’s align-items value for one specific item on the cross axis, letting a single card sit at the top while its siblings stretch to fill the row, for example.

Syntax

Each item-level property is set directly on the flex item, not on the container:

Property Values Initial value Applies to axis
order any integer (can be negative) 0 main axis position
flex-grow a non-negative number 0 main axis (growth)
flex-shrink a non-negative number 1 main axis (shrinkage)
flex-basis a length, percentage, auto, or content auto main axis (starting size)
flex shorthand: grow shrink basis 0 1 auto main axis
align-self auto, flex-start, flex-end, center, baseline, stretch auto cross axis

The flex shorthand is the recommended way to set grow, shrink, and basis together, because it fills in sensible defaults for the values you omit. Writing flex: 1; is equivalent to flex-grow: 1; flex-shrink: 1; flex-basis: 0%;, while writing flex: 1 200px; (a two-value form) is interpreted as flex-grow: 1; flex-basis: 200px; with flex-shrink left at its default of 1.

Examples

Example 1: flex-grow distributing extra space

Given three items inside a flex container (<div class="container"> holding three <div> elements with classes a, b, and c):

.container {
  display: flex;
  width: 600px;
}

.item {
  flex-grow: 1;
  padding: 10px;
  background: #ddeeff;
}

.b {
  flex-grow: 2;
}

Result: All three boxes start at their natural content width, then any leftover space in the 600px container is split into shares. Item .b gets twice as much of the leftover space as items .a and .c, so it ends up visibly wider than its siblings, while .a and .c remain equal in width to each other.

This is the core idea of flex-grow: it is not a final width, it’s a ratio describing how leftover space should be shared once every item’s base size has already been accounted for.

Example 2: a sidebar layout with flex-basis and flex-shrink

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

.sidebar {
  flex: 0 0 250px;
}

.main {
  flex: 1 1 auto;
  min-width: 0;
}

Result: The sidebar renders at a fixed 250px and never grows or shrinks (flex-grow: 0, flex-shrink: 0), even if the viewport is resized. The .main column takes up all remaining horizontal space and will grow to fill extra room or shrink if the window narrows, because its flex-grow is 1 and flex-shrink is 1.

The min-width: 0 on .main is a common companion rule: flex items default to a minimum size based on their content (min-width: auto), which can prevent long unbreakable content like a URL or a wide table from shrinking as expected. Resetting it to 0 lets flex-shrink actually do its job.

Example 3: reordering and cross-axis alignment

.container {
  display: flex;
  align-items: flex-start;
  height: 200px;
  gap: 1rem;
}

.item {
  order: 2;
}

.item.featured {
  order: 1;
  align-self: center;
}

Result: Even though the featured item might appear later in the HTML source, it visually renders first (leftmost, in a row layout) because its order value of 1 is lower than the default items’ order of 2. While the other items align to the top of the 200px-tall container (inherited from align-items: flex-start), the featured item overrides that and centers itself vertically within the row via align-self: center.

How It Works Step by Step

When the browser lays out a flex line, it effectively performs these steps for the main axis:

1. Resolve each item’s flex basis: if flex-basis is a length or percentage, use it directly; if it’s auto, fall back to the item’s specified width (in a row layout) or height (in a column layout), or its content size if no explicit size is set.

2. Sum all the resolved basis values plus any gaps, and compare that total to the container’s available main-axis space.

3. If there is positive free space (items are smaller than the container), distribute it proportionally using each item’s flex-grow factor: an item’s share is roughly (its flex-grow) ÷ (sum of all flex-grow values) × (free space). Items with flex-grow: 0 receive none of it.

4. If there is negative free space (items overflow the container), remove size from items using a weighted flex-shrink calculation: each item’s shrink factor is multiplied by its flex basis, so larger items with the same shrink factor give up proportionally more space than smaller ones. Items with flex-shrink: 0 refuse to shrink at all, which is why they can cause overflow if the container gets too small.

5. Once every item’s final main-axis size is settled, the browser positions items along the main axis (honoring order for visual sequence and justify-content for extra spacing), then aligns each item on the cross axis using its resolved align-self value.

Common Mistakes

Mistake 1: writing an invalid flex shorthand with too many values. The flex shorthand only accepts one, two, or three values (grow, shrink, basis) — not four:

.item {
  flex: 2 1 0 20%;
}

This is invalid and will be ignored by the browser, silently falling back to the item’s previous or default flex behavior, which is a confusing bug to track down. The fix is to use exactly three values in the correct order (grow, shrink, basis):

.item {
  flex: 2 1 20%;
}

Mistake 2: using a negative flex-shrink (or flex-grow) value. Both properties only accept non-negative numbers:

.item {
  flex-shrink: -2;
}

A negative value makes the declaration invalid, and the browser discards it, leaving flex-shrink at its default of 1 instead of doing whatever the negative number was meant to achieve. If the goal is to prevent shrinking entirely, the correct value is zero, not a negative number:

.item {
  flex-shrink: 0;
}

A closely related, non-syntax mistake worth flagging in prose: relying on order to fix messy HTML. Because order changes only the visual position and not the underlying source order, screen readers and keyboard tab order still follow the original markup. Using order to make a layout look right while the DOM stays in an illogical sequence creates an accessibility mismatch between what sighted mouse users see and what keyboard or assistive-technology users experience.

Best Practices

  • Prefer the flex shorthand (flex: 1;, flex: 0 0 200px;) over setting flex-grow, flex-shrink, and flex-basis separately — it fills in consistent defaults and is less error-prone.
  • Use flex-basis (or the third value in the shorthand) instead of width to set a flex item’s starting main-axis size, since flex-basis takes priority over width in the sizing algorithm when both are present.
  • Add min-width: 0 (or min-height: 0 in column layouts) to flex items that need to shrink below their content size, since the default min-width: auto can silently block shrinking.
  • Reserve order for small visual reshuffles (like moving a call-to-action button first on mobile) and keep the real content sequence correct in the HTML for accessibility.
  • Use align-self sparingly for one-off exceptions; if most items need the same cross-axis alignment, set align-items on the container instead.
  • Test flex-shrink behavior at narrow viewport widths — it’s the property most likely to produce unexpected overflow or squished text if left at its default of 1 on items that shouldn’t shrink.

Practice Exercises

Exercise 1: Build a three-column layout inside a flex container where the first and third columns are fixed at 200px and never grow or shrink, and the middle column fills all remaining space and shrinks gracefully on narrow screens. Which values of flex-grow, flex-shrink, and flex-basis (or which flex shorthand) do you need for each column?

Exercise 2: Given four flex items with no order set, add order values so that the second item in the HTML appears last visually, and the fourth item appears first. Write out the four order declarations you’d use.

Exercise 3: A flex container has align-items: stretch (the default), causing all items to be the same height. Write the CSS for a single item, using its own class, that keeps its natural content height instead of stretching, without changing the alignment of any sibling.

Summary

  • flex-grow distributes leftover main-axis space among items as a ratio; it does not set an absolute size.
  • flex-shrink removes space from items (weighted by their basis) when they collectively overflow the container; set it to 0 to prevent an item from shrinking.
  • flex-basis sets an item’s starting main-axis size before growing or shrinking is applied, and takes priority over width/height.
  • The flex shorthand (grow shrink basis) is the recommended way to combine all three, with sensible defaults for omitted values.
  • order changes only the visual position of an item along the main axis, leaving DOM order, tab order, and screen-reader order untouched.
  • align-self overrides the container’s align-items for a single item on the cross axis.