Home Module 05 Flex Item Properties

1. Introduction

The previous lesson covered container properties — properties you set on the parent to control all children. This lesson covers item properties — properties you set on individual flex items to control their own sizing and behaviour.

Item properties let you:

  • Control how much an item grows to fill space (flex-grow)
  • Control how much an item shrinks when space is tight (flex-shrink)
  • Set the initial size of an item before growing/shrinking (flex-basis)
  • Override the container's align-items for one specific item (align-self)
  • Reorder items visually without changing HTML (order)

The most important is the flex shorthand which combines the first three.

2. Theory

flex-grow

Controls how much an item grows to fill available space. A unitless number (growth factor). Default: 0 (don't grow).

.item-a { flex-grow: 1; } /* takes up 1 part of available space */
.item-b { flex-grow: 2; } /* takes up 2 parts — twice as much as a */
.item-c { flex-grow: 1; } /* takes up 1 part */
/* Total: 4 parts. a = 25%, b = 50%, c = 25% of extra space */
/* All items grow equally */
.flex-item { flex-grow: 1; }

/* Only the middle item grows */
.sidebar   { flex-grow: 0; width: 250px; }
.main-area { flex-grow: 1; } /* takes all remaining space */

flex-shrink

Controls how much an item shrinks when there is not enough space. Default: 1 (can shrink). Set to 0 to prevent shrinking.

.item { flex-shrink: 1; }  /* can shrink (default) */
.item { flex-shrink: 0; }  /* will NOT shrink — maintains its size */
.item { flex-shrink: 2; }  /* shrinks twice as fast as items with shrink: 1 */

flex-basis

Sets the initial size of a flex item before growing or shrinking. Can be a length (200px, 30%) or auto (default, uses the element's width/height).

.item { flex-basis: 200px; }  /* starts at 200px, then grows/shrinks */
.item { flex-basis: 30%; }    /* starts at 30% of container */
.item { flex-basis: auto; }   /* uses item's own width (default) */
.item { flex-basis: 0; }      /* starts at 0, then grows (for equal distribution) */

The flex Shorthand

The shorthand combines flex-grow flex-shrink flex-basis:

flex: 1;           /* flex-grow: 1; flex-shrink: 1; flex-basis: 0% */
flex: 1 1 auto;    /* grow, shrink, auto basis */
flex: 1 0 200px;   /* grow freely, don't shrink, start at 200px */
flex: 0 0 100px;   /* don't grow, don't shrink, always 100px */
flex: auto;        /* 1 1 auto */
flex: none;        /* 0 0 auto — fully inflexible */

Key shortcuts:

ShorthandMeansUse case
flex: 1grow 1, shrink 1, basis 0Equal-width columns
flex: autogrow 1, shrink 1, basis autoItems share space proportionally
flex: nonegrow 0, shrink 0, basis autoFixed-size items that don't flex
flex: 1 1 300pxflexible but min 300pxResponsive card grids

align-self

Overrides align-items for a single item. Same values: auto, flex-start, flex-end, center, stretch, baseline.

.container {
  display: flex;
  align-items: center;   /* all items centred */
}

.special-item {
  align-self: flex-end;  /* this one goes to the bottom */
}

order

Changes the visual order of an item without changing the HTML. Default: 0. Lower values appear first.

.item-1 { order: 2; }   /* appears last */
.item-2 { order: 1; }   /* appears second */
.item-3 { order: 0; }   /* appears first (default) */
Accessibility warning: order changes visual order but NOT keyboard tab order or screen reader order. Do not use order to change meaningful content sequence — only for visual decoration.

3. Real World Example

A classic layout pattern — "Holy Grail" layout with header, footer, and a three-column middle:

  • Left sidebar: fixed 250px, flex: 0 0 250px
  • Main content: grows to fill remaining space, flex: 1
  • Right sidebar: fixed 200px, flex: 0 0 200px

On mobile, use order to move the main content above both sidebars for better reading flow, without changing the HTML.

4. Code Example

/* ===== FLEX ITEM PROPERTIES ===== */

/* Sidebar layout */
.page-layout {
  display: flex;
  gap: 24px;
}

.sidebar-left {
  flex: 0 0 250px;  /* don't grow, don't shrink, stay 250px */
}

.main-content {
  flex: 1;          /* take all remaining space */
  min-width: 0;     /* prevent overflow with long content */
}

.sidebar-right {
  flex: 0 0 200px;  /* fixed right sidebar */
}


/* ===== EQUAL COLUMNS ===== */
.columns {
  display: flex;
  gap: 16px;
}

.columns .col {
  flex: 1;         /* all columns share space equally */
}

/* One column twice as wide */
.col--wide { flex: 2; } /* takes 2 shares vs 1 share for others */


/* ===== RESPONSIVE CARD GRID ===== */
.card-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}

.card-grid .card {
  flex: 1 1 280px;  /* min 280px, grows and shrinks */
  max-width: 100%;  /* prevent overflow */
}


/* ===== ALIGN-SELF EXAMPLE ===== */
.mixed-row {
  display: flex;
  align-items: flex-start; /* default: items align to top */
  gap: 16px;
  height: 200px;
}

.mixed-row .item-centered {
  align-self: center;    /* this item is vertically centred */
}

.mixed-row .item-bottom {
  align-self: flex-end;  /* this item sticks to bottom */
}


/* ===== ORDER EXAMPLE (mobile nav) ===== */
@media (max-width: 768px) {
  .page-layout {
    flex-direction: column;
  }

  .sidebar-left  { order: 2; } /* appears below main on mobile */
  .main-content  { order: 1; } /* main content first on mobile */
  .sidebar-right { order: 3; }
}

5. Code Breakdown

flex: 0 0 250px on sidebar
grow=0 (don't expand), shrink=0 (don't shrink), basis=250px. The sidebar always stays exactly 250px regardless of available space. Perfect for fixed sidebars.
flex: 1 on main content
grow=1, shrink=1, basis=0. The main content takes all remaining space after the fixed sidebars claim their 250px + 200px. On a 1000px container: 1000 - 250 - 200 - gaps = main content gets ~526px.
min-width: 0 on flex items
A subtle but important fix. By default, flex items cannot shrink below their content's intrinsic minimum width. If you have a long word or a wide code block, the item won't shrink past it, causing overflow. min-width: 0 allows it to shrink correctly.
flex: 2 vs flex: 1
If one column has flex: 2 and two others have flex: 1, the total is 4 parts. The wide column gets 2/4 = 50%, each narrow column gets 1/4 = 25%.
order for mobile reordering
In the media query, we change to flex-direction: column and use order to put the main content first on mobile. The HTML still has sidebar-left first in source, which is fine for desktop. This is visual-only reordering.

6. Common Mistakes

  • Confusing flex: 1 and flex: 1 1 auto. flex: 1 sets basis to 0 (items start at 0 and grow equally). flex: 1 1 auto starts from the item's own content width then distributes remaining space — items won't be equal width if their content differs.
  • Forgetting min-width: 0 on flex items. Long content (URLs, code) can cause flex items to overflow. Adding min-width: 0 fixes this.
  • Using order for meaningful content reordering. order only changes visual order, not keyboard tab order or screen reader reading order. Never use it to resequence content that matters in reading order.
  • Not understanding the difference between flex-grow: 0 and flex-basis: auto. flex-grow: 0 means don't grow — but the item still has its natural size. flex-basis: 0 means start with 0 width then only grow as specified.

7. Best Practices

  • Use the flex shorthand — avoid writing all three properties separately.
  • Use flex: 1 for equal-width columns.
  • Use flex: 0 0 Xpx for fixed-size sidebars.
  • Add min-width: 0 to flex items containing text or code that might overflow.
  • Avoid order for content resequencing — only use for purely decorative visual changes.
  • Set max-width: 100% on flex items to prevent them from exceeding their container.

8. Practice Exercise

  1. Create a three-column layout: fixed 200px left, flexible middle, fixed 150px right. Use flex on all three items.
  2. Create a row of 4 boxes. Give the second one flex-grow: 3 and the others flex-grow: 1. Observe the width distribution.
  3. Create a row where items have different heights. Use align-self to position different items at top, center, and bottom.
  4. Create a card with an image header, text body, and button footer. Use Flexbox (column direction) on the card with flex: 1 on the body to push the footer to the bottom — making all cards in a row have bottom-aligned buttons.

9. Assignment

Build a "dashboard" layout using flex item properties:

  • A three-panel layout: fixed left nav (220px), scrollable main area (flex: 1), fixed right panel (280px)
  • In the main area: a stats bar with 4 metric cards each using flex: 1 for equal width
  • One "featured" stat card using flex: 2 to be twice as wide
  • A two-column activity feed below, with the left column taking 60% (flex: 3) and right 40% (flex: 2)
  • On mobile (max-width: 768px): stack everything vertically and use order to move stats above the nav

10. Interview Questions

Q1: What is the flex shorthand and what are its three values?

Answer: flex is shorthand for flex-grow flex-shrink flex-basis. flex-grow determines how much the item grows to fill space, flex-shrink how much it shrinks when space is tight, and flex-basis its initial size before growing/shrinking.

Q2: What does flex: 1 mean?

Answer: flex: 1 is shorthand for flex-grow: 1; flex-shrink: 1; flex-basis: 0%;. All items with flex: 1 share available space equally, starting from 0 width. This creates equal-width columns regardless of content.

Q3: How do you prevent a flex item from shrinking below a certain size?

Answer: Either set flex-shrink: 0 (prevents any shrinking) or set a flex-basis (e.g. flex: 0 0 300px) which sets the minimum size. You can also use min-width to set a hard minimum.

Q4: What is align-self and how does it differ from align-items?

Answer: align-items is a container property that sets the cross-axis alignment for all flex items. align-self is an item property that overrides the container's align-items for just that one item, allowing it to have a different alignment from the rest.

Q5: What is the purpose of min-width: 0 on flex items?

Answer: By default, flex items cannot shrink below their content's minimum width (flex's "min-content" intrinsic minimum). This can cause overflow when content is wide (URLs, code). Setting min-width: 0 overrides this default and allows the item to shrink correctly.

11. Additional Resources

  • MDN — flex-grow (search "MDN flex-grow")
  • MDN — flex shorthand (search "MDN flex CSS property")
  • CSS-Tricks — A Complete Guide to Flexbox (search "css-tricks flexbox")
  • web.dev — Flexbox alignment (search "web.dev flexbox alignment")
  • Flexbox Zombies — mastery.games/flexboxzombies (game to practice flex)