CSS - How to force elements to 100% of remaining/available space of parent element without extending beyond it?
Asked Answered
D

2

11

This seems like a really amateur question, in my opinion, but nonetheless it's still a frustrating anomaly.

This is actually the 2nd part of a 2 part problem. The first part is a rather common one, involving getting an element to stretch to 100% height of its parent object. In my demo, I have the following HTML:

<body>      
<div id="sbcontainer">
    DIV 1
    <div id="sbcontent">
        DIV 2
        <table id="sbmaintable" cellspacing="0">
            <tr>
                <td>
                    TABLE
                </td>
            </tr>
        </table> <!-- END MAINTABLE -->
    </div> <!-- END CONTENT -->
</div> <!-- END CONTAINER -->
</body>

I want each element here to fill all vertical space within its parent element. I tried used the following style on each of the elements (Please note that BODY and HTML are also set to 100% height in my demo):

min-height: 100%; 
height: auto !important; 
height: 100%; 

The result was as follows: enter image description here

As you can see, the outermost DIV followed the 100% height property but the rest did not. As implied in the image note, but not actually shown in this image, I tried setting the 2nd DIV (red border) to a static height of 400px to see if the TABLE within would stretch to 100% height, and it still did not.

I then found that if I removed height:auto; from each of the elements, they would follow the 100% height property, but with an unwanted side effect:

enter image description here

As you can see in the image, each element is now truly 100% the height of its parent element, forcing the bottom to extend beyond the boundaries of its parent. (Even in my first example, the outermost DIV with the green border extended farther than desired because there is another sibling DIV above it on the page). NOTE: After looking more carefully, I can see that the blue TABLE element is not actually the same height as its red DIV parent, but it still extends beyond its boundary. I'm not sure if this means anything, but I do notice it.

One would think that this would be an easy thing to solve, but despite my efforts, I've had no success.

If I keep only height:auto; and remove the 100% properties, this does not stretch them at all.

I have searched for solutions on this via Google and StackOverflow, and although many sites covered 100% height issues, I still haven't found an actual solution.

I am currently testing this in Firefox.

Disposition answered 15/10, 2011 at 14:8 Comment(2)
You're results are to be expected. The height: 100% means the "height of the parent element." When you add content to the parent element, it shifts the child element (which still has the height of the parent) down appropriately (see: jsfiddle.net/blineberry/rtC9H). We can probably help you better if you explain the effect you're trying to get at by using height: 100%. Is it for images? Colors? There may be another way to achieve it. Also, see: #90678Spectroheliograph
@Spectroheliograph - I realize why it happens. That was never a mystery to me. What I'm looking for is a way to avoid it. I'm looking for a proper way to force an element to extend enough to fill the rest of the remaining space within its parent element without using static figures. Also, my question was general, meaning there isn't really anything specific I am currently trying to build that needs this. Actually, not totally true. I do have a project that might need this. It will likely be structured like the example in my post (DIV>DIV>TABLE).Disposition
S
14

You can use absolute positioning.

#b {
    width: 40em;
    height: 20em;
    position:relative;
    background: red;
}
#c {
    position: absolute;
    top: 1em;
    bottom: 1em;
    left: 1em;
    right: 1em;
    background: blue;
}

<div id="b">
    <div id="c">
    </div>
</div>
Sommers answered 15/10, 2011 at 18:32 Comment(3)
Genius. Of course. In the past I always thought absolute tore an element away from any other element, but I learned recently that it's actually absolute within its parent element. Setting position:absolute with bottom:0px did exactly what I wanted for each of the nested elements. Thank you so much.Disposition
Could you please answer #10141648 ?Walhalla
This doesn't work well on elements that are using the display:table,display:table-row,display:table-cell properties, including tables.Iago
U
0

I believe the proper solution to something like this is using a flexbox. Flexbox has great support the lately with all modern browsers.

Use following for the parent

.stretch-items {
  display: flex;
  flex-direction: column;  
}

And for the item that should grow

.stretch-items .stretch {
   flex-grow: 1;  
}

Here is a codepen demonstrating it https://codepen.io/giorgosk/pen/NWWaqPO

Undulant answered 29/10, 2019 at 17:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.