Chris Chris - 5 months ago 21
HTML Question

Strange behavior on table and table-cell

I recently stumbled upon a question here where someone was trying to get a proper line-behind behavior on their headers. Something like this:



Their implementation yielded different results across different headers, and hence the question. The implementation was quite odd by using

table
for the element and
table-cell
for the
:before
and
:after
. The resulting behavior was for me quite surprising. I made a test on jsfiddle, have a look.

You'll see that I have two classes;
a
and
b
, where the former has a width of 25% and the latter 40%. Despite this, the
b
is nearly 5 times wider than
a
. Setting them to 40% and 45% respectively makes
b
twice as large as
a
. This is totally unexpected behavior for just a 5% difference. The length of the text seems to affect this too.

I get that this implementation is bad and that it would "break". However, I'd like to know why it breaks the way it does. This makes no sense to me.



div {
display: table;
background: grey;
margin: 10px 0;
}
div:before,
div:after {
width: 25%;
position: relative;
content: '';
border-top: 2px solid black;
display: table-cell;
}
div.b:before,
div.b:after {
width: 45%;
}

<div class="a">text</div>
<div class="a">some more text</div>

<div class="b">text</div>
<div class="b">some more text</div>




Answer

The auto tabular layout is not specified by the standard, so I recommend against using this kind of percentage tricks, which will probably break on some browsers.

However, it seems most browsers behave like this:

  • The ::before and ::after pseudo-elements will take the specified percentage of the table.
  • The text is wrapped inside an anonymous cell which has the width of the text. That will represent the remaining percentage left by the pseudo-elements.
  • The width of the table will be determine by the constraints above.

So if you have width: 25%, the text will take the remaining 50%.

tablewidth = textwidth / 50% = 2 * textwidth
pseudowidth = 25% * tablewidth = 0.5 * textwidth

If you have width: 40%, the text will take the remaining 20%.

tablewidth = textwidth / 20% = 5 * textwidth
pseudowidth = 40% * tablewidth = 2 * textwidth

If you have width: 45%, the text will take the remaining 10%. That is, the table will double its width with respect to the previous case, if the text is the same.

tablewidth = textwidth / 10% = 10 * textwidth
pseudowidth = 45% * tablewidth = 4.5 * textwidth
Comments