I'm using flexbox to display a text label along with a numeric value in a narrow column, so that the text is truncated with ellipsis if it doesn't fit.
It worked fine, until I had the need to place the entire column in a table-cell - at which point the browser (Chrome) just ignored the column width and made the table wide enough to fit all the text.
Here's the label layout:
<div class="line">
<span>Very long label text</span>
<span>12345</span>
</div>
.line {
display: flex;
width: 100%;
}
.line span:first-child {
white-space: nowrap;
flex-grow: 1;
overflow: hidden;
text-overflow: ellipsis;
}
.line span:last-child {
flex-shrink: 0;
margin-left: 5px;
}
Placing it in a regular div with a fixed width works as expected. Placing it in a table-cell doesn't:
Fiddle: http://jsfiddle.net/98o7m7am/
.wrapper {
width: 150px;
}
.table {
display: table;
}
.table > div {
display: table-cell;
}
.line {
display: flex;
width: 100%;
}
.line span:first-child {
white-space: nowrap;
flex-grow: 1;
overflow: hidden;
text-overflow: ellipsis;
}
.line span:last-child {
flex-shrink: 0;
margin-left: 5px;
}
<div class="wrapper">
<div class="line">
<span>Very long label text</span>
<span>12345</span>
</div>
</div>
<div class="table wrapper">
<div>
<div class="line">
<span>Very long label text</span>
<span>12345</span>
</div>
</div>
</div>
Update: I ended up 'solving' this by using more flexboxes instead of tables, but I would still like to know why the original example doesn't work.
Flex[box] is for boxes and not for texts so never make your text container a flexbox container.
Flexbox is inherently a one dimensional layout model. Flex items within a flex container can be laid out either horizontally or vertically, but not both. If you want to lay out items in both dimensions, you'll need to nest a flex container inside another one.
You need a content-first design : Flexbox is the ideal layout system to create web pages if you don't know exactly how your content is going to look, so if you want everything just to fit in, flexbox is perfect for that.
This works because when you give an element a fixed position and a left and right of 0 or a top and bottom of 0, the element is stretched to fill the space from left to right, or top to bottom. That in turn allows a flex-box to use the amount of space you would expect without position fixed. Save this answer.
That's because, by default, tables use the automatic table layout:
The CSS 2.1 spec doesn't define that layout mode, but suggests a (non-normative) algorithm, which reflects the behavior of several popular HTML user agents.
According to that algorithm, the table's width
will only be treated like a minimum width, and the real width will be enough so that the content does not overflow:
Calculate the minimum content width (MCW) of each cell: the formatted content may span any number of lines but may not overflow the cell box.
Since you have white-space: nowrap
, the MCW will be the width of the full text.
To avoid that, you can set the initial width of your first span to 0:
.line span:first-child {
width: 0;
}
.wrapper {
width: 150px;
}
.table {
display: table;
}
.table > div {
display: table-cell;
}
.line {
display: flex;
width: 100%;
}
.line span:first-child {
width: 0;
white-space: nowrap;
flex-grow: 1;
overflow: hidden;
text-overflow: ellipsis;
}
.line span:last-child {
flex-shrink: 0;
margin-left: 5px;
}
<div class="wrapper">
<div class="line">
<span>Very long label text</span>
<span>12345</span>
</div>
</div>
<div class="table wrapper">
<div>
<div class="line">
<span>Very long label text</span>
<span>12345</span>
</div>
</div>
</div>
Alternatively, you may want to try the fixed table mode, which is properly defined in the spec (and thus more reliable), is usually faster, and solves the problem too.
table-layout: fixed;
.wrapper {
width: 150px;
}
.table {
display: table;
table-layout: fixed;
}
.table > div {
display: table-cell;
}
.line {
display: flex;
width: 100%;
}
.line span:first-child {
white-space: nowrap;
flex-grow: 1;
overflow: hidden;
text-overflow: ellipsis;
}
.line span:last-child {
flex-shrink: 0;
margin-left: 5px;
}
<div class="wrapper">
<div class="line">
<span>Very long label text</span>
<span>12345</span>
</div>
</div>
<div class="table wrapper">
<div>
<div class="line">
<span>Very long label text</span>
<span>12345</span>
</div>
</div>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With