Flex-shrink 0 breaks mobile layout when a flex item is told never to shrink, so cards, buttons, images, sidebars, or chips keep desktop widths inside a narrow viewport.
Flex Shrink Fix
Why does flex-shrink:0 break mobile layouts?
flex-shrink:0 breaks mobile layouts when it protects an element from becoming smaller even though the screen has run out of space. The rule is not evil. It is often used correctly for icons, avatars, thumbnails, logos, and small controls that should keep their shape. The bug starts when it is applied to large cards, buttons, sidebars, images, tabs, or entire content panels.
The browser is doing exactly what the CSS says: do not shrink this item. On desktop that may look stable and professional. On mobile, the same item can become a wall. The parent tries to fit the viewport, but the no-shrink child refuses to adapt, so the row becomes wider than the screen and horizontal scroll appears.
- flex-shrink:0
- Mobile overflow
- Flexbox sizing
- Responsive rows
Test by allowing shrink temporarily
When a flex row overflows on mobile, temporarily change flex-shrink:0 to flex-shrink:1 or replace flex:0 0 240px with flex:1 1 180px. If the scrollbar disappears, the bug is not random. A protected flex item was refusing to share the smaller screen.
Related: Try this in the FrontFixer Live Inspector.
Open Live Inspector→What the bug looks like
A row of cards, buttons, images, or layout columns becomes wider than the screen on mobile.
Why it happens
One or more flex items are told not to shrink, so the parent cannot fit the viewport.
What usually fixes it
Allow shrink, add wrapping, use responsive flex-basis, and reserve no-shrink only for small fixed elements.
Why flex-shrink:0 feels stable until mobile
Developers often add flex-shrink:0 because they want to stop an element from getting squeezed. That instinct makes sense. A logo should not become distorted. An icon should not collapse. A small avatar should keep its shape. But the same protection becomes dangerous when it is applied to something large enough to compete with the viewport.
Flexbox works by negotiating space among items. When the row has less room than the items prefer, shrink behavior decides which items are allowed to give up width. If a large item has flex-shrink:0, it refuses to participate in that negotiation. The remaining items may shrink, but the protected one keeps its size and can force the row wider than the parent.
The better pattern is selective protection. Keep tiny fixed elements stable, but let larger layout pieces shrink, wrap, stack, or use a responsive basis. A rule that prevents distortion should not also prevent the entire page from fitting a phone.
Cards use flex-shrink:0 in a narrow row
A no-shrink card row is common in carousels and pricing sections. It becomes a problem when the layout is supposed to be a normal responsive row. If each card keeps a fixed basis and refuses to shrink, the row will overflow as soon as the viewport is too narrow.
Broken code
Cards cannot shrink.cards {
display: flex;
gap: 16px;
}
.card {
flex: 0 0 170px;
flex-shrink: 0;
}
Broken visual result
Every card keeps its protected width.
Correct code
Cards can adapt.cards {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
.card {
flex: 1 1 135px;
min-width: 0;
}
Fixed visual result
The cards can shrink, grow, or move to another line.
A large image or media block refuses to shrink
Fixed thumbnails can use no-shrink safely, but large media blocks need limits. If an image area is protected with flex-shrink:0 and a wide basis, it can steal too much space from the text or force the entire row wider than the viewport.
Broken code
Media is too protected.media-card {
display: flex;
gap: 12px;
}
.media-card__image {
flex: 0 0 190px;
flex-shrink: 0;
}
.media-card__copy {
flex: 1;
}
Broken visual result
The image block refuses to shrink, so the copy has no room.
Correct code
Media has a fluid limit.media-card {
display: flex;
gap: 12px;
}
.media-card__image {
flex: 0 1 140px;
width: min(140px, 40%);
}
.media-card__copy {
flex: 1 1 0;
min-width: 0;
}
Fixed visual result
The image has a preferred size but still respects mobile space.
Chips and buttons are all no-shrink
Filter chips, tabs, and action buttons often use flex-shrink:0 to keep labels readable. That can work inside an intentionally scrollable carousel. It breaks normal mobile layouts when the buttons are expected to fit inside the page width.
Broken code
No-shrink chips.filters {
display: flex;
gap: 10px;
}
.filters button {
flex-shrink: 0;
min-width: 128px;
}
Broken visual result
The chips are readable, but the page is wider than the screen.
Correct code
Wrap chips safely.filters {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.filters button {
flex: 1 1 100px;
min-width: 0;
}
Fixed visual result
The chips can wrap and share the available space.
A no-shrink sidebar blocks the main content
Desktop layouts often protect sidebars with flex-shrink:0. That makes sense when the viewport is wide enough. On tablet and mobile, the sidebar may need to shrink, wrap above the main content, or become a drawer. Keeping it no-shrink everywhere can break the whole layout.
Broken code
Protected sidebar.layout {
display: flex;
gap: 16px;
}
.sidebar {
flex: 0 0 260px;
flex-shrink: 0;
}
.main {
flex: 1;
}
Broken visual result
The sidebar is protected even when the screen is narrow.
Correct code
Responsive sidebar.layout {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
.sidebar {
flex: 1 1 150px;
min-width: 0;
}
.main {
flex: 2 1 180px;
min-width: 0;
}
Fixed visual result
The sidebar and main area can share space or wrap.
A production-minded flex-shrink pattern
A safe Flexbox system uses no-shrink only for the parts that truly need it. Small fixed elements can keep shape. Large components get a responsive basis. Rows can wrap. Text areas get min-width:0. Button groups either wrap or become intentional internal scroll areas.
Premium code
Selective shrink control.row {
display: flex;
flex-wrap: wrap;
gap: clamp(12px, 2vw, 20px);
}
.row__icon {
flex: 0 0 auto; /* safe for small fixed pieces */
}
.row__card {
flex: 1 1 180px;
min-width: 0;
}
.row__media {
flex: 0 1 160px;
max-width: 40%;
}
.row__content {
flex: 1 1 0;
min-width: 0;
}
.actions {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.actions > * {
flex: 1 1 110px;
min-width: 0;
}
Premium visual result
Small pieces stay stable. Large pieces adapt.
Fast practical rule
If flex-shrink:0 breaks a mobile layout, ask whether that element truly must keep its full desktop width. If it is a small icon or avatar, no-shrink may be fine. If it is a card, sidebar, button group, image block, or content panel, give it a responsive basis, allow wrapping, or let it shrink before it creates horizontal scroll.
Debug checklist
- Search for
flex-shrink:0,flex:0 0, andflex:0 0 auto. - Temporarily switch the item to
flex-shrink:1and see whether the scrollbar disappears. - Check whether the no-shrink item is small and intentional or large and risky.
- Use
flex-wrap:wrapwhen several protected items need more than one line. - Replace fixed desktop bases with responsive values like
flex:1 1 160px. - Add
min-width:0to flexible content areas beside fixed pieces. - Use percentage or
min()limits for images and media blocks. - Turn large fixed sidebars into wrapping regions, stacked sections, or drawers on mobile.
flex-shrink:0 on the suspicious item and watch the layout.flex:0 0 auto creates similar no-shrink behavior without saying flex-shrink directly.When flex-shrink:0 is actually correct
flex-shrink:0 is correct when shrinking would damage the meaning or shape of a small fixed element. Icons, avatars, status dots, logos, checkmarks, small thumbnails, and compact controls often need to stay stable. In those cases, the surrounding content should adapt around them.
The rule becomes dangerous when the protected element is large enough to compete with the viewport. A 260px sidebar, a 190px image block, three 170px cards, or several 128px chips can quickly exceed a phone screen when combined with gaps and padding. That is the line to watch: small fixed pieces can be protected, but large layout pieces need responsive escape routes.
A clean mobile layout does not mean every item shrinks equally. It means each item has the right behavior for its job. Some pieces stay fixed, some shrink, some wrap, some stack, and some become internal scroll areas. The mistake is giving all of them the same no-shrink rule.
Final takeaway
flex-shrink:0 breaks mobile layouts when it protects an element that should be allowed to adapt. The rule is useful for small fixed pieces, but risky for large cards, sidebars, image blocks, chip rows, and content panels.
Use no-shrink with intent. Protect icons and small fixed details, but give larger layout pieces responsive bases, wrapping behavior, shrink permission, and min-width:0 where needed. That keeps the design stable without forcing horizontal scroll on mobile.