Ian Ian - 4 months ago 16
HTML Question

Combine auto, fixed, and percentage width in same HTML table row

I would like to create a table that has 4 columns. 2 of the columns in the table are labels and should auto-size to the widest element. One of the other columns is fixed width and the last should fill the remaining space. My first attempt to create this table looks like this:

HTML

<table style="width:100%">
<tr>
<td class="lbl">lbl:</td> <td class="fluidContent">Expandable Content 1</td>
<td class="lbl">longer label:</td> <td class="fixedContent">Me Fixed</td>
</tr>
<tr>
<td class="lbl">longer label:</td> <td class="fluidContent">Expandable Content 2</td>
<td class="lbl">lbl:</td> <td class="fixedContent">Me Fixed</td>
</tr>
</table>


CSS

table {
white-space: nowrap;
}

td {
border: 1px solid orange;
}

.lbl {
text-align: right;
font-style: italic;
width: auto;
}

.fluidContent {
width: calc(100% - 120px);
}

.fixedContent {
width: 120px;
}


https://jsfiddle.net/vf5p0m82/

Unfortunately this markup yields label columns with fluid width. The "lbl" class cells are treated as though they had a width of 27% specified with the "fluidContent" cells having a width of 46%. What I want is for the "lbl" cells to be as small as possible while still fitting the largest string they contain.

Is there any way to do this how I want simply with tables or is it time to employ the new CSS3 flex-boxes?

Edit: A Solution

Whilst adding another example to this question for clarity I stumbled upon a hack to make it work. If you just give the auto-sized columns a width of 1px everything works out. See here:
https://jsfiddle.net/vf5p0m82/2/

Is there an established/canonical way to do this or is this it?

Answer

There might be a more official way to do this, but the thing I've found works is to just set the cell width to 1px. The content size overrides it, so it will just collapse to content size.

.lbl {
  text-align: right;
  font-style: italic;
  width: 1px;
}

By the way, the calc seems to be overridden by table formatting, but it doesn't seem like you need it from what you described.

See it in action: https://jsfiddle.net/vf5p0m82/1/