treecoder
treecoder

Reputation: 45081

Setting the "height" on child elements based on an absolutely-positioned parent

I have a parent element, and I want to set the height of an element within the parent. For example:

<div id="parent">
    <p id="child"></p>
</div>

Now we know that in order the set a height for the "child", we must have some value of height set on "parent" also. Otherwise there will be no effect of setting any height value on the "child" alone.

#parent { height: 200px; }
#child { height: 75%; }

This will set the height for the "child" to be 75% of 200px. If we remove the height on "parent", "child" won't have any height set.

Now, what I found out was that instead of setting a height, if we set the positioning of the "parent" to be absolute, we can get away without setting any height, and the height value on the "child" would still work:

#parent { position: absolute; top: 0; bottom: 0; }
#child { height: 75%; }

What I want to know is whether this is a standard behavior or something that just works by chance. Also, if it is standard, does this mean that giving an element a layout (by setting it's position) gives it some value for height implicitly?

Upvotes: 1

Views: 1519

Answers (2)

BoltClock
BoltClock

Reputation: 723438

The basic idea is this: for an absolutely-positioned element, if you set the offsets on opposite sides (e.g. left and right, or top and bottom) to zero, then the element will stretch to the width or height of its containing block respectively.

Not only is this a commonly-used trick, but it is also a standard behavior. The gory details are here in the spec; the key lies in this equation:

For absolutely positioned elements, the used values of the vertical dimensions must satisfy this constraint:

'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of containing block

(This is for calculating heights; there's a corresponding equation for calculating widths as well, which can be found here.)

So, assuming defaults for all other values, this means

0 + 0 + 0 + 0 + 'height' + 0 + 0 + 0 + 0 = height of containing block

The containing block of an absolutely-positioned element whose ancestors are all static is always the viewport (or the initial containing block), which is typically of the same height as a browser's viewing area (or the Results iframe in jsFiddle for example). This creates the effect I've just described.

Because you did not specify an explicit height for your parent element, this gives it an implicit height for calculating the height of your child element as a percentage:

The percentage is calculated with respect to the height of the generated box's containing block.

In fact, even if you set top and/or bottom to some non-zero value, the boxes will scale according to the above equation.

Note also that the "height of the generated box's containing block" does not refer to the specified or computed value of height for that block, but the used value, i.e. the height as it is calculated rendered on screen. This may have been the source of your confusion on why you can get away without setting height on the parent element, yet the browser still knows how to calculate the height of the child element based on some implicit height.

Upvotes: 4

Afshin Mehrabani
Afshin Mehrabani

Reputation: 34919

Of course, Yes. This is a standard behavior.

Always when you set the top: 0; and bottom: 0; for an absolute element, it means set the height to the parent height value. For example, consider an relative element with height: 400px;, if you have a absolute child element with top: 0; and bottom: 0;, the child element also will be height: 400px;

<div style='position: relative;height: 400px'>
    <div style='position: absolute;bottom: 0;top:0;'>
        ...
    </div>
</div>

Upvotes: 0

Related Questions