Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is there extra white space in a table cell when text wraps?

Tags:

html

css

I have a horizontally centered div with two children. Each of the children are centered vertically with display: table-cell and vertical-align:middle

Everything works fine when the screen (or parent container) is wide enough for all the text to be on one line. However, if the screen/parent shrinks, then the text wraps and leaves a large amount of white space. Why doesn't the div shrink to fit the text?

The image below shows the problem. Everything is the way I want it in the top image. The grey section wraps the content, and is centered within its parent container. However, if the parent shrinks so the text wraps, a bunch of white space is left over (see the area highlighted in the red rectangle). This whitespace creates the illusion that the whole element is aligned left instead of centered.

A jsFiddle example with what I have so far is here: http://jsfiddle.net/eterpstra/pRgeL/1/

Any way to get rid of this whitespace so everything appears more centered, instead of shifted to the left?

enter image description here

like image 625
eterps Avatar asked Sep 11 '25 13:09

eterps


1 Answers

As @andi writes, browsers do table layout in a bit odd way. This can be demonstrated using just a single-cell table in HTML:

<div style="width: 270px; background: yellow">
<table>
<tr><td style="font-size: 25px; border: solid 1px">Way too much white space
</table>
</div>

Browsers try first to set all the text on the same line, allocating the available width (here 270px), then find out that the text needs to be wrapped, but then forget to tune down the cell width according to the length of the longest line of the content.

Putting a <br> tag in the content (at the point(s) where the line will be broken) would “fix” this, but it would be poor design, very inflexible, to use fixed line breaks that way.

It seems that this can be fixed by using an inner span element inside the cell and setting the style.width property of the cell to equal the offsetWidth property of the span element, with the unit px appended:

<div style="width: 270px; background: yellow">
<table>
<tr><td id=cell style="font-size: 25px; border: solid 1px"><span id=t>Way too much white
  space</span>
</table>
</div>
<script>
 document.getElementById('cell').style.width = 
   document.getElementById('t').offsetWidth + 'px';
</script>

jsfiddle

For a general solution, I suppose you could – instead of specific coding like the above – write a script that traverses the td elements (or elements shown with display: table-cell) that may need fixing, insert a span element dynamically, and then do the fix. Something like this, assuming, for definiteness, that your table cells are all td elements and have content that can safely be wrapped in in span elements:

<script>
var cells = document.getElementsByTagName('td');
for(var i = 0; i < cells.length; i++) {
  var cell = cells[i];
  var span = document.createElement('span');
  span.innerHTML = cell.innerHTML;
  cell.innerHTML = span.outerHTML;
}
for(var i = 0; i < cells.length; i++) {
  var cell = cells[i];
  cell.style.width = cell.childNodes[0].offsetWidth + 'px';
}
</script>
like image 107
Jukka K. Korpela Avatar answered Sep 14 '25 04:09

Jukka K. Korpela