Flexbox Items
In Flexbox Basics you turned a parent into a flex container and arranged its children in a row or a column. This lesson is about the children themselves, the flex items. You will learn how they decide their size, how they share extra space, how they give space back when the row is too tight, and how to move or align a single item.
These properties are what make Flexbox feel flexible. Once you understand them, layouts like a search bar that fills the header or a footer that stays at the bottom of the page take only a few lines.
How flex items share space
Every time the browser lays out a flex container, it does a small calculation along the main axis (the direction of the row or column):
- It finds each item's starting size, called its flex basis.
- It adds up those sizes and compares the total with the container's size.
- If there is space left over, it hands that free space to items that are allowed to grow.
- If the items are too big, it takes space away from items that are allowed to shrink.
Three properties control this: flex-basis (the starting size), flex-grow (how much of the extra space an item takes) and flex-shrink (how much an item gives up when space is short).
flex-basis: the starting size
flex-basis sets an item's size along the main axis before any growing or shrinking happens. In a row, it acts like a width. In a column, it acts like a height.
.sidebar {
flex-basis: 250px; /* start at 250px wide in a row */
}
.tag {
flex-basis: auto; /* the default: use width, or the content size */
}The default value auto means "look at the item's width (or height in a column), and if that is also auto, use the size of the content". This is why, by default, a short word makes a narrow item and a long sentence makes a wide one.
flex-grow: sharing extra space
flex-grow is a number that says how many shares of the free space an item takes. The default is 0, so items do not grow unless you ask them to. Run this example and compare the two rows.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>flex-grow</title>
<style>
body { font-family: system-ui, sans-serif; }
.row {
display: flex;
gap: 8px;
padding: 8px;
margin-bottom: 12px;
background: #eef2ff;
}
.row div {
padding: 12px;
background: #4338ca;
color: white;
}
.grow-1 { flex-grow: 1; }
.grow-2 { flex-grow: 2; }
</style>
</head>
<body>
<p>No flex-grow (the default):</p>
<div class="row">
<div>Tea</div>
<div>Masala coffee</div>
<div>Lassi</div>
</div>
<p>flex-grow 1, 2, 1:</p>
<div class="row">
<div class="grow-1">Tea</div>
<div class="grow-2">Masala coffee</div>
<div class="grow-1">Lassi</div>
</div>
</body>
</html>In the second row the free space is split into four shares: one for Tea, two for Masala coffee and one for Lassi. Notice that Masala coffee is not exactly twice as wide as Tea. It gets twice as much of the extra space, but it also started wider because its text is longer. If you want sizes in an exact ratio, set the basis to zero so that all of the space counts as free space. The flex shorthand below does exactly that.
flex-shrink: giving space back
When the items are wider than the container, flex-shrink decides who gets smaller. The default is 1, so every item shrinks a little. Items with a bigger basis give up more, so the shrinking feels fair.
Set flex-shrink: 0 on anything that must keep its size, such as a profile photo, a logo or an icon. Without it, a long piece of text next to the photo can squeeze the photo into a thin strip.
There is one surprise here. A flex item will not shrink below the width of its longest word or widest child, because flex items have min-width: auto by default. A long email address or URL can therefore push the whole row wider than the screen. The fix is min-width: 0 on the item that holds the text.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>flex-shrink and min-width</title>
<style>
body { font-family: system-ui, sans-serif; max-width: 360px; }
.contact {
display: flex;
align-items: center;
gap: 12px;
padding: 10px;
border: 1px solid #ccc;
border-radius: 8px;
}
.avatar {
flex-shrink: 0;
width: 48px;
height: 48px;
border-radius: 50%;
background: #f59e0b;
}
.details {
min-width: 0; /* allow the text box to shrink below its content */
}
.email {
margin: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
</head>
<body>
<div class="contact">
<div class="avatar"></div>
<div class="details">
<strong>Ananya Iyer</strong>
<p class="email">ananya.iyer.accounts.department@example-college.ac.in</p>
</div>
</div>
</body>
</html>Delete the min-width: 0 line and run it again: the long email pushes the card wider than its box instead of ending with "...".
The flex shorthand
In real projects you rarely write the three properties separately. The flex shorthand sets flex-grow, flex-shrink and flex-basis in one go, and its keywords cover most needs.
| You write | Same as | Use it for |
|---|---|---|
flex: 1 | 1 1 0 | Equal columns, whatever their content |
flex: auto | 1 1 auto | Grow, but keep content-based starting sizes |
flex: none | 0 0 auto | Fixed items such as icons and buttons |
flex: 0 0 240px | grow 0, shrink 0, basis 240px | A fixed-width sidebar |
flex: 1 1 200px | grow and shrink from 200px | Cards that wrap onto new lines |
The default for every flex item is 0 1 auto: do not grow, may shrink, start from the content size.
The most common mix-up is between flex: 1 and flex: auto. With flex: 1 the basis is zero, so all items end up the same size even if one has much more text. With flex: auto each item starts from its content size, so longer items stay wider.
order and align-self
Two more properties work on a single item.
order moves an item visually. Every item starts with order: 0, and items are drawn from the lowest number to the highest. align-self overrides the container's align-items for one item only, which is handy when one item should sit at the bottom or the top of a row.
.featured {
order: -1; /* drawn before all items with order 0 */
}
.price-tag {
align-self: flex-end; /* this item sits at the bottom of the row */
}Common Flexbox patterns
A few item-level tricks solve everyday layout problems.
- Push one item to the end: an auto margin soaks up all the free space, so
margin-inline-start: autoon the last link pushes it to the right of a navigation bar. - A box that fills the rest:
flex: 1on a search input makes it take whatever space the logo and button leave. - Footer at the bottom: make the page a flex column with
min-height: 100dvhand give the main contentflex: 1. - Fixed plus flexible:
flex: noneon an image andflex: 1withmin-width: 0on the text next to it.
This header uses the first two patterns.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Header patterns</title>
<style>
body { margin: 0; font-family: system-ui, sans-serif; }
.header {
display: flex;
align-items: center;
gap: 12px;
padding: 12px 16px;
background: #0f172a;
color: white;
}
.logo { flex: none; font-weight: bold; }
.search {
flex: 1;
min-width: 0;
padding: 8px;
border: 0;
border-radius: 6px;
font: inherit;
}
.login {
margin-inline-start: auto;
flex: none;
color: #facc15;
}
</style>
</head>
<body>
<header class="header">
<span class="logo">Pune Books</span>
<input class="search" type="search" placeholder="Search books" aria-label="Search books">
<a class="login" href="#">Log in</a>
</header>
</body>
</html>The page-footer pattern looks like this in CSS:
body {
display: flex;
flex-direction: column;
min-height: 100dvh;
margin: 0;
}
main {
flex: 1; /* main grows, so the footer is pushed to the bottom */
}Common mistakes
- Expecting
flex-grow: 2to mean "twice as wide". It means twice the extra space. Useflex: 2andflex: 1(basis zero) for exact ratios. - Text overflowing a flex item. Add
min-width: 0to the item, ormin-height: 0in a column, so it can shrink below its content. - Squashed images and icons. Give them
flex: noneorflex-shrink: 0. - Using
orderto fix the reading order. It only changes the visual order. Fix the HTML instead.
Key points
flex-basisis an item's starting size along the main axis;autouses its width or content.flex-growshares out free space in proportion to each item's number; the default is0.flex-shrinkdecides who gets smaller when space is short;0keeps an item's size.- Use the
flexshorthand:flex: 1for equal items,flex: autofor content-based items,flex: nonefor fixed ones. - Flex items will not shrink below their content unless you set
min-width: 0. orderandalign-selfaffect one item, butordernever changes the reading order.
Exercise
Build a row for a train ticket booking page with three items: a "From" box, a "To" box and a "Search trains" button. The two boxes should share the free space equally, whatever text is inside them, and the button should keep its natural size. Add a fourth item, a small "Swap" button, between the two boxes that never grows or shrinks.
Show solution
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Train search</title>
<style>
.search-row { display: flex; gap: 8px; }
.place { flex: 1; min-width: 0; padding: 8px; }
.swap, .go { flex: none; }
</style>
</head>
<body>
<div class="search-row">
<input class="place" value="Rohtak Junction" aria-label="From">
<button class="swap" type="button">Swap</button>
<input class="place" value="Jaipur" aria-label="To">
<button class="go" type="button">Search trains</button>
</div>
</body>
</html>flex: 1 gives both boxes a basis of zero, so they end up the same width. flex: none keeps both buttons at their content size, and min-width: 0 lets the inputs shrink on a narrow phone.
Quick Quiz
1. Three items have flex-grow values of 1, 1 and 2. What does the last item get?
The free space is split into 1 + 1 + 2 = 4 shares, and the last item takes 2 of them, which is half.
2. What does flex: none mean?
flex: none keeps an item at its natural size: it neither grows nor shrinks.
3. A long URL inside a flex item makes the row wider than the screen. What is the usual fix?
Flex items default to min-width: auto, so they refuse to shrink below their content. min-width: 0 removes that limit.
4. Why should you be careful with the order property?
Keyboard focus and screen readers follow the HTML order, so order can make the page confusing if the order carries meaning.
Learn CSS with a mentor
Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
