Flex Items

Difficulty: Intermediate

While the container properties (justify-content, align-items, etc.) control how items are positioned collectively, the flex item properties control how individual items grow, shrink, and size themselves within the available space. The three core properties are flex-grow, flex-shrink, and flex-basis, which are most commonly used through the flex shorthand.

flex-grow determines how much an item should grow relative to the other flex items when there is extra space in the container. The default value is 0, meaning items do not grow beyond their content size. Setting flex-grow: 1 on all items makes them share the extra space equally. If one item has flex-grow: 2 and the others have flex-grow: 1, the first item gets twice as much of the extra space (not twice the total width -- it gets twice the share of the remaining space after all items' base sizes are accounted for).

flex-shrink determines how much an item should shrink relative to the other flex items when the container is too small to fit all items at their base sizes. The default value is 1, meaning all items shrink equally. Setting flex-shrink: 0 on an item prevents it from shrinking at all, which is useful for fixed-width elements like icons or logos. An item with flex-shrink: 2 will shrink twice as fast as items with flex-shrink: 1.

flex-basis sets the initial main-axis size of a flex item before flex-grow and flex-shrink are applied. It is similar to setting width (in row direction) or height (in column direction), but it is Flexbox-aware and participates in the flex algorithm. The default value is auto, which means the item's size is determined by its content or explicit width/height. You can set flex-basis to a length (200px), a percentage (25%), or content (use the content's intrinsic size). When both width and flex-basis are set, flex-basis takes precedence.

The flex shorthand combines all three properties: flex: <grow> <shrink> <basis>. The most common values are flex: 1 (equivalent to flex: 1 1 0%, meaning grow equally and start from zero size), flex: auto (equivalent to flex: 1 1 auto, meaning grow equally from content size), flex: none (equivalent to flex: 0 0 auto, meaning fixed size, no grow/shrink), and flex: 0 1 auto (the default). Using the shorthand is strongly recommended because it sets sensible defaults for the values you omit -- notably, flex: 1 sets flex-basis to 0%, while setting only flex-grow: 1 leaves flex-basis at auto, which produces different results.

Code examples

flex-grow: Distributing Extra Space

.container {
  display: flex;
  gap: 12px;
}

/* All items share extra space equally */
.equal-grow .item {
  flex-grow: 1;
}

/* Middle item gets twice the extra space */
.weighted .item { flex-grow: 1; }
.weighted .item-main { flex-grow: 2; }

/* Only one item grows to fill remaining space */
.fill-one .item-expand { flex-grow: 1; }
/* Other items stay at their content width */

flex-grow distributes the leftover space in the container. When all items have flex-grow: 1, they share equally. When one has a higher value, it gets a proportionally larger share. Items without flex-grow (or flex-grow: 0) keep their natural size.

flex-shrink: Controlling Shrinking

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

/* Default: all items shrink equally */
.item {
  flex-shrink: 1;
  width: 250px; /* 3 * 250 = 750 > 600, items shrink */
}

/* Prevent specific items from shrinking */
.logo {
  flex-shrink: 0;
  width: 150px; /* Logo stays 150px no matter what */
}

.content {
  flex-shrink: 1;
  width: 300px; /* Content absorbs all the shrinking */
}

When items are wider than the container, flex-shrink controls how each item reduces its size. flex-shrink: 0 prevents an item from shrinking, which is important for elements like logos or icons that should maintain a fixed size.

flex-basis vs width

.container {
  display: flex;
  gap: 16px;
}

/* flex-basis sets the starting size before grow/shrink */
.sidebar {
  flex-basis: 250px;   /* Start at 250px */
  flex-grow: 0;        /* Don't grow */
  flex-shrink: 0;      /* Don't shrink */
}

.main-content {
  flex-basis: 0;       /* Start from zero */
  flex-grow: 1;        /* Grow to fill remaining space */
}

/* flex-basis takes precedence over width */
.overridden {
  width: 300px;        /* Ignored in flex context */
  flex-basis: 200px;   /* This wins */
}

flex-basis defines the initial size of a flex item along the main axis. When set to 0, the item starts with no inherent size and relies entirely on flex-grow. When both width and flex-basis are present, flex-basis wins in the flex layout algorithm.

flex Shorthand Patterns

.container {
  display: flex;
  gap: 16px;
}

/* flex: 1 = flex: 1 1 0% (equal size items) */
.equal-items .item {
  flex: 1;
}

/* flex: auto = flex: 1 1 auto (grow from content size) */
.auto-items .item {
  flex: auto;
}

/* flex: none = flex: 0 0 auto (fixed size) */
.fixed-item {
  flex: none;
  width: 200px;
}

/* Common sidebar + main layout */
.sidebar {
  flex: 0 0 280px; /* Fixed 280px sidebar */
}
.main {
  flex: 1;         /* Main fills remaining space */
}

The flex shorthand is the recommended way to set flex item sizing. flex: 1 makes items equal width (basis is 0%). flex: auto makes items grow from their content width. flex: none makes items fixed-size. The sidebar/main pattern is extremely common.

Key points

Concepts covered

flex-grow, flex-shrink, flex-basis, flex Shorthand