Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to get Flexbox to work inside label?

Tags:

html

css

flexbox

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:

Flexbox issue

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.

like image 596
riv Avatar asked May 15 '15 11:05

riv


People also ask

Does flexbox work on text?

Flex[box] is for boxes and not for texts so never make your text container a flexbox container.

Can you use flexbox inside flexbox?

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.

Can I use flexbox for everything?

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.

Does position fixed work with flexbox?

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.


1 Answers

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>
like image 186
Oriol Avatar answered Sep 22 '22 22:09

Oriol