This layout bug shows up in a lot of UIs. A row has an icon, a long file name and a button. You want the name to end with "..." when space runs out. You add the usual three lines. Nothing happens. The name keeps its full length and shoves the button past the edge of the card.
The setup
<div class="file-row"> <img class="icon" src="pdf.svg" alt=""> <span class="name">quarterly-report-final-version-2-really-final.pdf</span> <button>Share</button> </div> .file-row { display: flex; align-items: center; gap: 8px; width: 280px; } .name { flex: 1; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } Those three lines on .name are right. MDN points out that text-overflow cannot cause an overflow on its own. You pair it with overflow and white-space, and MDN's own example is overflow: hidden plus white-space: nowrap. Both are here.
This first version works, because .name is itself the flex item and overflow: hidden gives it a zero minimum.
So why no dots? In many real layouts, the text is not the flex item. It sits one level deeper.
The version that breaks
<div class="file-row"> <img class="icon" src="pdf.svg" alt=""> <div class="meta"> <span class="name">quarterly-report-final-version-2-really-final.pdf</span> <span class="size">2.4 MB</span> </div> <button>Share</button> </div> .meta { flex: 1; display: flex; flex-direction: column; } .name { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } Now .meta is the flex item in the row. It has no overflow of its own. That one detail is the whole bug.
Why it happens: the automatic minimum size
Every flex item starts with min-width: auto. For flex items, auto does not mean zero.
Section 4.5 of the CSS Flexbox spec covers this. A flex item's automatic minimum width comes from its content, unless the item is a scroll container. MDN's min-width page says the same thing in shorter words: for flex items, auto resolves to a content-based size, and a scroll container gets a minimum of 0.
What does "based on content" mean for one long line of text that cannot wrap? The smallest the item may get is the full width of that line. So:
- The row is 280px wide.
-
.metawants to shrink to fit next to the icon and the button. - Its minimum width is the full width of the file name.
- Shrinking stops there. The row overflows.
-
.nameis as wide as its text, so it never needs to cut anything. No dots appear.
flex-shrink is still on, by the way. It just cannot shrink an item below its minimum size.
The fix: let the flex item get small
Give the flex item that holds the text a zero minimum:
.meta { flex: 1; display: flex; flex-direction: column; min-width: 0; /* the fix */ } Now .meta can shrink below its content width. .name inside it gets a real, narrow width, its text overflows, and the ellipsis shows up.
Another way is overflow: hidden on .meta. That turns it into a scroll container, and per the spec and MDN, a scroll container's automatic minimum is 0. We prefer min-width: 0 for this case. It states the intent directly, and it does not hide parts of .meta's children that paint past its edges, such as a child's focus ring.
One note from reading the docs: MDN says overflow: clip does not create a scroll container, while hidden does. So we would not expect overflow: clip on .meta to reset the minimum. Use min-width: 0 or overflow: hidden here.
Nested rows need it at every level
If the text sits inside several nested flex containers, each flex item between the row and the text can hold the line open. Put min-width: 0 on each flex item on that path, not only the one nearest the text.
A quick checklist
- Text has
overflow: hidden,white-space: nowrapandtext-overflow: ellipsis. - The text element has a width limit (for example it is a block, or a flex item that can shrink).
- Every flex item between the row and the text has
min-width: 0. - If the dots still do not show, open DevTools and look for the first ancestor whose width equals the full text width. That one is missing the fix.
These properties are well supported. MDN lists min-width, overflow and text-overflow as Baseline widely available since July 2015, and flex-shrink since September 2015.
Sources
- W3C Flexbox spec (css-flexbox-1), section 4.5: https://www.w3.org/TR/css-flexbox-1/#min-size-auto
- MDN, min-width: https://developer.mozilla.org/en-US/docs/Web/CSS/min-width
- MDN, text-overflow: https://developer.mozilla.org/en-US/docs/Web/CSS/text-overflow
- MDN, overflow: https://developer.mozilla.org/en-US/docs/Web/CSS/overflow
- MDN, flex-shrink: https://developer.mozilla.org/en-US/docs/Web/CSS/flex-shrink
Engineers who can explain why min-width: 0 works, not just paste it, are the people PIXEL RECRUITING LLC likes to introduce to product teams that need frontend and UI help. We are a direct staffing partner for Mastercard in O'Fallon, MO, and you can learn more at pixelrecruiting.com.