Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrong width of `inline-block` parent element

I'm working with some HTML/CSS which lines up <li> elements horizontally using a lot of display:inline-block rules. I've traced a JS bug to a $("ol").width() which measures the width of the element incorrectly - seemingly because of the width of the <li> contents?

Here's an example of the problem: http://jsfiddle.net/q01ng8b6/ - note how the red border of the <ol> element doesn't go all the way around the contents:

enter image description here

Here's an example of how removing a width on the <li> contents fixes the size of my <ol> element: http://jsfiddle.net/q01ng8b6/1/ - note how the red border of the properly goes all the way around the contents.

I don't understand what's happening here - how could a rule changing the width of the "grandchildren" have such a pronounced effect on the width of my <ol> element? Is this a browser bug or standards compliant?

like image 479
Richard JP Le Guen Avatar asked Nov 09 '22 14:11

Richard JP Le Guen


1 Answers

Probably not a browser bug, but possibly an inadequately tightly defined spec.

What appears to be happening is that the calculation of the width of the li elements has multiple solutions. Its width depends on its contents (shrink-to-fit), and its contents width depends on their container (100%). Any value from 0 to infinity will work.

Now, for the ol element, the shrink-to-fit algorithm applies. From CSS basic box model

Calculation of the shrink-to-fit width is similar to calculating the width of a table cell using the automatic table layout algorithm. Roughly: calculate the preferred width by formatting the content without breaking lines other than where explicit line breaks occur, and also calculate the preferred minimum width, e.g., by trying all possible line breaks. CSS does not define the exact algorithm. Thirdly, find the available width: in this case, this is the width of the containing block minus the used values of ‘margin-left’, ‘border-left-width’, ‘padding-left’, ‘padding-right’, ‘border-right-width’, ‘margin-right’, and the widths of any relevant scroll bars.

Then the shrink-to-fit width is: min(max(preferred minimum width, available width), preferred width).

Define in more detail, using a text by David Baron.

The spec is clearly inadequate for this case, but it seems that for the purposes of the preferred minimum width, the li width solution = 0 is used, while for the preferred width, the li width solution = intrinsic width of the img is used. These choices don't seem unreasonable to me, but I don't know of any part of the spec that requires them.

Assuming those values for your example, the width of the ol element is the available width, which is what you see.

Of course, the li and img widths cannot be rendered in multiple solutions, and there is nothing to constrain the width of the li elements to be proportionate to their container, so they render according to the img elements intrinsic widths, overflowing their ol container.

like image 158
Alohci Avatar answered Nov 14 '22 21:11

Alohci