Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't the inline element inheriting height from its children?

Tags:

html

css

I'm trying to make a rather complicated grid of images and information (almost like Pinterest). Specifically, I'm trying to inline position one set of <ul>s right after another. I have it working but one aspect is causing issues so I'm trying to ask about this small piece to avoid the complication of the whole problem.

In order to horizontally align the images and their information we are using inline <li>s with other inline-block level elements inside of them. Everything works correctly for the most part except that the <li>s have almost no height.

HTML and CSS is in JSFiddle here if you want to mess with it in addition to below:

HTML:

<div>
<ul class="Container">
    <li>
        <span class="Item">
            <a href="#"><img src="http://jsfiddle.net/img/logo.png"/></a>
            <span class="Info">
                <a href="#">Title One</a>
                <span class="Details">One Point One</span>
            </span>
        </span>
    </li>
    <li>
        <span class="Item">
            <a href="#"><img src="http://jsfiddle.net/img/logo.png"/></a>
            <span class="Info">
                <a href="#">Title Two</a>
                <span class="Details">Two Point One</span>
            </span>
        </span>
    </li>
</ul>

CSS:

.Container {
    list-style-type:none;
}
.Container li {
    background-color:grey;
    display:inline;
    text-align:center;
}
.Container li .Item {
    border:solid 2px #ccc;
    display:inline-block;
    min-height:50px;
    vertical-align:top;
    width:170px;
}
.Container li .Item .Info {
    display:inline-block;
}
.Container li .Item .Info a {
    display:inline-block;
    width:160px;
}

If you check out the result in the jsfiddle link you can see that the grey background only encompasses a small strip of the whole <li>. I know that changing the <li> to display:inline-block solves this problem but that isn't feasible for other reasons.

So first of all, I'm just looking to see if anyone understands why the inline <li> element doesn't have any height. I can't find anything in the spec that explains this. I know I can't add height to an inline element but any explanation as to why this is happening that might enable me to fix would be great.

Secondly, if you inspect the elements using IE's Developer Mode you will see that although the background color is in the correct location, the actual location of the <li>'s bounding box is at the bottom of the container according to hovering over the element. I could deal with this problem if it was at the top in every browser but it apparently varies.

NOTE: I don't really care about older browsers in this case but I don't use HTML5 or JavaScript positioning.

Thanks.

like image 485
jbarz Avatar asked Jan 17 '23 03:01

jbarz


2 Answers

Inline elements don't have the option to set the height. Inline elements are elements that are on a line, and thus inherit height of the line. Block elements are elements that take up full width and can have assigned width, height, and other stuff that make them easier to style.

For a detailed explanation in the specs see: http://www.w3.org/TR/CSS2/visuren.html#inline-formatting

inline-block makes an element appear inline, but you can assign height and width to it, and it will expand with the content within. I didn't use inline-block very often because of it's buggy behaviour in IE, but those days are over now apperantly: http://www.quirksmode.org/css/display.html

Making the <li> using inline-block solves this, but you say this is not an option for you. Why not? Another solution is to make those li's block elements, and make them float to the left. If you have problems with overlapping content, use the overflow property on the whole ul to make sure the ul is pushing down other content.

ul.Container {
  list-style-type: none;
  overflow: hidden; /* so height expands with the floated content */
}

ul.Container li {
  display: block;
  float: left;
  ... more styling ...
}

Is this something that solves your puzzle?

like image 53
Justus Romijn Avatar answered Feb 01 '23 07:02

Justus Romijn


The relevant bit of the CSS 2.1 spec is section 10.6.1 Inline, non-replaced elements of section 10.6 Calculating heights and margins. It says:

The 'height' property does not apply. The height of the content area should be based on the font, but this specification does not specify how. A UA may, e.g., use the em-box or the maximum ascender and descender of the font. (The latter would ensure that glyphs with parts above or below the em-box still fall within the content area, but leads to differently sized boxes for different fonts; the former would ensure authors can control background styling relative to the 'line-height', but leads to glyphs painting outside their content area.)

The <li> element is styled inline, and it's content is a single inline-block object which can't span lines, so the content area of the <li> is only one line high. The height of the <li>'s content area is therefore the 1 x f(height of the font). See http://jsfiddle.net/dh8nU/1/ for a demonstration where an increase in the height of the font has made the grey area larger.

The section goes on to say:

The vertical padding, border and margin of an inline, non-replaced box start at the top and bottom of the content area, and has nothing to do with the 'line-height'. But only the 'line-height' is used when calculating the height of the line box. [my emphasis]

When you place larger inline-block elements in an inline element, the height of line box increases to contain the inline-block elements, but as per the text above, this does not increase the height of the containing inline element.

like image 22
Alohci Avatar answered Feb 01 '23 08:02

Alohci