Notes on flex-grow, flex-shrink, and flex-basis

Tiger AbrodiTiger Abrodi
2 min read

The three-value syntax

flex: 1 1 300px;
/*    │ │ │
      │ │ └── flex-basis (starting size)
      │ └──── flex-shrink (how much it can shrink)
      └────── flex-grow (how much it can grow)
*/

Most people use the shorthand (flex: 1) but the three-value version gives you way more control.

Grow: distributing extra space

.item-a { flex: 2 0 100px; } /* gets 2x the extra space */
.item-b { flex: 1 0 100px; } /* gets 1x the extra space */

If there's 300px of extra space, item-a gets 200px and item-b gets 100px. Both start at 100px, then grow proportionally.

Shrink: handling tight spaces

.sidebar { flex: 0 0 200px; } /* never shrinks */
.main    { flex: 1 1 0;     } /* shrinks first */

When space is tight, items with higher shrink values give up space first. flex-shrink: 0 means "never shrink, ever."

Basis: the starting point

flex: 1 1 0;    /* start from 0, distribute all space equally */
flex: 1 1 auto; /* start from content size, distribute leftover */
flex: 1 1 200px; /* start from 200px, then grow/shrink from there */

Basis isn't "width", it's more like "ideal size before flexing happens."

The min-width gotcha

Flex items have min-width: auto by default, meaning they won't shrink below their content size. This breaks layouts:

/* Broken -> long text will overflow */
.flex-item { flex: 1; }

/* Fixed -> allows shrinking below content */
.flex-item { flex: 1; min-width: 0; }

Common patterns

/* Equal columns */
.col { flex: 1; min-width: 0; }

/* Fixed sidebar, flexible main */
.sidebar { flex: 0 0 200px; }
.main { flex: 1; min-width: 0; }

/* Responsive cards */
.card { flex: 1 1 300px; }

/* Grow only, never shrink */
.item { flex: 1 0 auto; }
0
Subscribe to my newsletter

Read articles from Tiger Abrodi directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Tiger Abrodi
Tiger Abrodi

Just a guy who loves to write code and watch anime.