The Three Negotiators: Mastering `flex-grow`, `shrink`, & `basis`
If `display: flex` is the boss that creates the team, then `flex-grow`, `flex-shrink`, and `flex-basis` are the three negotiators that decide how the team members (the flex items) share their resources (the space in the container). Mastering them is the difference between a layout that *works* and a layout that is truly *resilient* and *responsive*.
1. `flex-basis`: The Starting Offer
`flex-basis` is the first and most important negotiator. It defines the ideal starting size of an item *before* any growing or shrinking happens. Think of it as an item's opening bid: "I'd *like* to be this big."
flex-basis: 150px: The item wants to be 150px wide (if in a row).flex-basis: 25%: The item wants to be 25% of the container's width.flex-basis: auto: (The default) The item says, "Just use my `width` or `height` property as my starting size." If neither is set, it sizes to its content.flex-basis: 0: The item says, "I'll start with no size and let `flex-grow` determine my final size." This is key for making items grow based *only* on their grow-factor, not their content.
Key Rule: If `flex-basis` is set to anything other than `auto`, it **overrides** the `width` or `height` property in that direction.
2. `flex-grow`: Dividing the Riches (Positive Space)
`flex-grow` decides what happens when there is **extra space** in the container. It's a number that represents a *proportion* or *ratio*.
flex-grow: 0: (The default) The item **refuses** to grow. It will stay at its `flex-basis` size.flex-grow: 1: The item will take a share of the extra space. If all items have `flex-grow: 1`, they share the extra space equally.
Example: You have 300px of extra space.
- Item A: `flex-grow: 1`
- Item B: `flex-grow: 2`
- Item C: `flex-grow: 1`
The total "grow factors" are 1 + 2 + 1 = **4 shares**. The 300px is divided into 4 shares (75px each).
- Item A gets 1 share (75px).
- Item B gets 2 shares (150px).
- Item C gets 1 share (75px).
3. `flex-shrink`: Sharing the Burden (Negative Space)
`flex-shrink` decides what happens when there is **not enough space** and items overflow. It determines how much an item is *willing* to shrink.
flex-shrink: 1: (The default) The item **agrees** to shrink proportionally with other items to prevent overflow.flex-shrink: 0: The item **refuses** to shrink. It will stay at its `flex-basis` size, even if it overflows the container. This is extremely useful for logos, icons, or fixed-width sidebars.
The math for shrinking is more complex (it's weighted by the item's size), but the main takeaway is: **`flex-shrink: 0` means "do not shrink, ever."**
The `flex` Shorthand: Common Prescriptions
You will rarely write the three properties separately. Instead, you'll use the `flex` shorthand: flex: [grow] [shrink] [basis].
flex: 1;
/* Expands to:
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;
*/The "Equal Share": This tells an item to start at zero size and take an equal share of all available space. Perfect for equal-width columns.
flex: auto;
/* Expands to:
flex-grow: 1;
flex-shrink: 1;
flex-basis: auto;
*/The "Default Flexible": This tells an item to use its content size (`auto`), but feel free to grow or shrink from there.
flex: none;
/* Expands to:
flex-grow: 0;
flex-shrink: 0;
flex-basis: auto;
*/The "Rigid Item": This tells an item to use its content size and *never* grow or shrink.
flex: 1 1 250px;
/* Expands to:
flex-grow: 1;
flex-shrink: 1;
flex-basis: 250px;
*/The "Responsive Card": The most common pattern for grids. "Try to be 250px, but grow or shrink if you need to."
Key Takeaway: Use `flex-basis` to set the ideal size, `flex-grow` to distribute extra space, and `flex-shrink` to control what happens in tight spaces. Use the `flex` shorthand to set them all at once.