Flex Item Properties

Learn the properties applied to individual flex items — order, flex-grow, flex-shrink, flex-basis, the flex shorthand, and align-self — and use them to build a layout that reflows responsively.

Container properties control the layout as a whole, but sometimes you need to control how one specific item behaves differently from its siblings — make it grow to fill leftover space, refuse to shrink below a certain width, jump to a different visual position, or override its own cross-axis alignment. That's the job of flex item properties, applied directly to a flex item rather than its parent.

order and align-self

order changes the visual position of a flex item without touching the HTML source order. Every flex item has a default order value of 0. Items are laid out in ascending order value, and items with equal order values fall back to their source order. This is purely visual — screen readers and keyboard tab order still follow the DOM, so order should be used carefully and never as a substitute for correct HTML structure.

align-self lets one specific flex item override the container's align-items value just for itself, using the same set of values (auto, stretch, flex-start, flex-end, center, baseline). auto (the default) means 'defer to the parent's align-items'.

• order: 0 by default; lower values appear first • order is visual-only — it doesn't change DOM/tab order, so use sparingly for accessibility reasons • align-self: auto (default, inherits align-items) | stretch | flex-start | flex-end | center | baseline

flex-grow, flex-shrink, and flex-basis

These three properties control how a flex item sizes itself along the main axis, and together they're the real power of Flexbox for responsive design. flex-basis sets the item's starting size along the main axis before any growing or shrinking happens — think of it like width in a row layout, or height in a column layout. Its default is auto, meaning 'use the item's own width/height, or its content size'.

flex-grow is a unitless number (default 0) that decides how much of the leftover space in the container an item should absorb, relative to its siblings. If all items have flex-grow: 1, any extra space is split evenly between them. An item with flex-grow: 2 will take twice as much of the leftover space as a sibling with flex-grow: 1. Critically, flex-grow only distributes *leftover* space — it doesn't do anything if the items already fill the container exactly.

flex-shrink (default 1) is the mirror image: it controls how much an item shrinks, relative to its siblings, when there isn't enough room to fit everyone at their flex-basis size. Setting flex-shrink: 0 on an item means 'never shrink this below its flex-basis, even if it causes overflow' — useful for logos or icons that shouldn't get squashed.

• flex-basis: the item's starting main-axis size before growing/shrinking (default: auto) • flex-grow: how eagerly an item absorbs *leftover* space (default: 0, meaning it won't grow) • flex-shrink: how eagerly an item gives up space when the container is too small (default: 1, meaning it will shrink)

The flex shorthand and the flex: 1 pattern

In practice, these three properties are almost always set together using the flex shorthand: flex: <grow> <shrink> <basis>. The famous pattern flex: 1 is actually shorthand for flex: 1 1 0% — grow freely, shrink freely, and start from a basis of 0 (ignore natural content size and just divide space evenly). This is the go-to declaration for 'make this item share available space equally with its siblings'.

Other common shorthand values: flex: auto expands to flex: 1 1 auto (grow and shrink, but start from the item's natural size). flex: none expands to flex: 0 0 auto (never grow, never shrink, stick to natural size — effectively rigid). flex: initial, the default, expands to flex: 0 1 auto (won't grow, will shrink if needed, starts from natural size).

• flex: 1 → flex-grow: 1, flex-shrink: 1, flex-basis: 0% (equal sharing, ignores content size) • flex: auto → 1 1 auto (grow/shrink from natural size) • flex: none → 0 0 auto (rigid, never resizes) • flex: initial (default) → 0 1 auto (won't grow, can shrink, natural size)

Flex item property set

flex is almost always preferred over setting the three longhands separately flex: 1 is the most common single declaration for 'grow to fill available space equally'

.item {
  order: 0;
  flex-grow: 0;
  flex-shrink: 1;
  flex-basis: auto;
  flex: 0 1 auto;   /* shorthand for the three above */
  align-self: auto;
}

Code Examples

Three flex items sit inside the nav: a logo, a nav-links list, and a call-to-action button. The next example makes the nav-links section absorb leftover space while the logo and button stay their natural size.

.nav-links uses flex: 1 to expand and fill whatever space is left after the logo and button take their natural size, then centers its own links within that expanded space. .cta uses flex-shrink: 0 so it never gets visually compressed even if the container gets tight.

On small screens, order: -1 pulls the sign-up button ahead of the logo visually, without reordering the underlying HTML — useful for emphasizing a call to action on mobile.

Common mistake: Overusing order for layout purposes can confuse keyboard and screen-reader users, since their navigation still follows DOM order.

<nav class="site-nav">
  <div class="logo">Brand</div>
  <ul class="nav-links">
    <li>Home</li>
    <li>Docs</li>
    <li>Pricing</li>
  </ul>
  <button class="cta">Sign Up</button>
</nav>
.site-nav {
  display: flex;
  align-items: center;
  gap: 16px;
}

.logo {
  flex: none; /* never grow or shrink, stay natural size */
}

.nav-links {
  display: flex;
  gap: 16px;
  flex: 1; /* absorb all leftover horizontal space */
  justify-content: center;
}

.cta {
  flex-shrink: 0; /* don't let the button get squashed */
}
@media (max-width: 600px) {
  .site-nav {
    flex-wrap: wrap;
  }
  .cta {
    order: -1; /* visually moves the button to the front on mobile */
  }
}

Important Rules

flex-grow only kicks in when there is leftover space to distribute — it can't create space that doesn't exist flex-shrink only kicks in when items would otherwise overflow the container flex: 1 sets flex-basis to 0%, which means the item's natural content size is ignored as a starting point — all items with flex: 1 start equal and grow from there order affects visual order only, never DOM order, tab order, or accessibility tree order

Real-world usage

flex: 1 is one of the most-written declarations in modern CSS — it appears constantly in sidebars that should fill remaining width, form inputs that should expand next to a fixed-width label, and content areas that grow around a fixed header/footer. flex-shrink: 0 is the standard fix for images or icons getting unintentionally squished in a tight flex row..item { flex-grow: 1; width: 300px; /* expecting this to be the final width */ }.item { flex: 1 1 300px; /* 300px is just the starting basis, grow/shrink still apply */ }

When flex-grow or flex-shrink is active, a fixed width is only a starting point (better expressed as flex-basis), not a guarantee — the item will still grow or shrink from there..icon { flex: 1; /* icon awkwardly stretches to fill space */ }.icon { flex: none; /* stays its natural, fixed size */ } flex: 1 tells an item to grow and shrink and ignore its natural size — fine for flexible content areas, but wrong for something like a fixed-size icon that should never resize.

[Identify the Error] A developer wants a sidebar to stay a fixed 250px wide no matter what, even if the flex container gets narrow. They wrote: .sidebar { flex-basis: 250px; } and nothing else. What's missing? A. Nothing — flex-basis alone is always enough to lock in a fixed size B. They also need flex-shrink: 0, since the default flex-shrink: 1 will still shrink the sidebar below 250px when space is tight C. flex-basis only works if flex-grow is also set to 0 D. They should have used width instead, since flex-basis is ignored inside flex containers

B. They also need flex-shrink: 0, since the default flex-shrink: 1 will still shrink the sidebar below 250px when space is tight — flex-basis only sets the starting size. Because the default flex-shrink is 1, the sidebar will still shrink below 250px if the container runs out of room — flex-shrink: 0 is required to truly lock the size.

Build a .card-row of three cards where the middle card is twice as wide as the other two, and none of the cards ever shrink below 150px..card-row { display: flex; gap: 16px; }.card-row.card { flex: 1 1 150px; }.card-row.card--middle { flex: 2 1 150px; }

Use flex-grow values of 1, 2, 1 and a shared flex-basis with flex-shrink managed via the flex shorthand.