Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

element with height 100% and overflow

Tags:

html

css

overflow

What I basically need to achieve is to have an element (div, span, table, whatever) to consume 100% of its' parent height and show scrolls if it's content is taller.

The problem is, only chrome and IE in quirks work OK with height:100%; overflow: auto;. Firefox, Opera and IE in standards (any IE 7+, any "standards") just ignore the overflow and stretch the html element below the parent size. If I set fixed height it works, but I can't determine the available height before rendering, there are multiple possible values.

Simplified example (jsFiddle for this):

<body>
    <div id="parent">
        <table id='container'>
            <tr>
                <td>
                    <div id='element-in-question'>
                        <!--Content long enough to stretch the div-->
                    </div>
                </td>
            </tr>
            <tr>
            <td id='footer-cell'>
                <div id='footer'>I'm footer<div>
            </td>
            </tr>
        </table>
    </div>
</body>

Css:

#parent { height:500px; width:500px; position:absolute; }
#container { height: 100%; width:100%; }
#element-in-question { height:100%; width:100%; overflow: auto; }
#footer-cell { height:30px;}
#footer { height: 30px; }

In real app all this stuff runs in an iframe, table is used to render header and footer and so on. Please do not suggest stop using tables, it's legacy application with 100+ places that need attention. CSS only solution would be ideal.

One more point: it should work in Chrome, IE10 standards mode. FF, Opera and Safari are not supported, IE9 and below handled differently.

Update: there are about ten footers with different heights, ideally the solution should not depend on fixed footer height.

like image 604
J0HN Avatar asked Mar 06 '13 20:03

J0HN


People also ask

What does HTML height 100% do?

Conclusion. With no height value provided for the HTML element, setting the height and/or min-height of the body element to 100% results in no height (before you add content). However, with no width value provided for the HTML element, setting the width of the body element to 100% results in full page width.

How do you make a div 100 height?

Syntax: To set a div element height to 100% of the browser window, it can simply use the following property of CSS: height:100vh; Example: HTML.

How do I change the full page height in CSS?

In your CSS use: #your-object: height: 100vh; For browser that don't support vh-units , use modernizr.

What is element overflow?

In CSS, overflow refers to any content that is too big for an element's box. This occurs when a block element has a specified height that's too small for the content it contains. You can use the CSS overflow property to control what happens to the overflow.


1 Answers

Here you go:

Updated fiddle.

The problem is that height: 100%; is going to fill the next defined container. For whatever reason, tables aren't seen as a valid container for that purpose. So what we need to do is utilize some of the quirkiness of how tables are laid out.

position: absolute;
top:5px; left:5px;
right: 5px;
bottom: 40px;
overflow: auto;
border: 1px solid green;
background-color: #eee;

No need for relative positioning on the td. Don't ask me why, perhaps someone more knowledgable than I can chime in.

Regardless, with this we can force it to expand to fill a set amount of space, while still allowing:

  1. The footer to be visible.
  2. The padding to be present (even if it's not technically padding.)
  3. This solution to work in a cross-browser environment.

Really hope this helps; if it doesn't, I'd be more than happy to give it another shot.


Update

You said that javascript isn't how you'd like to do it, but here's a short solution using jQuery which would actually solve the problem:

Updated Fiddle

$('td > div').each(function() {
    var t = $(this);
    var text = t.html();
    t.hide();
    t.height(t.parent().height());
    t.show(text);
});

Why this works:

The div needs its parent to have a defined height before 100% height works, however that's not an option for you as you've already stated that this is all dynamic content. No problem. We just need the jQuery to push the calculated height to the div after the browser has already rendered it. Simple enough, right?

Well, not so fast. Divs aren't meant to be bounded by table cells, at least not ideally. We already have something that serves as a logical, separate container in the td, and the div doesn't much care what the td's height is if it has a boatload of content that's spilling over its borders already. And when we go to query the height of that td, no matter what it actually is, it's going to report that it's larger than the elements which it contains. So, if you look on the fiddle after commenting out the lines where we empty the div, you'll see that the td is erroneously reporting itself to be almost 900 pixels tall.

So what do we do?

Well, we take that content away from the div. Now it's just a husk, and it's going to be smaller than its container in every circumstance. That means that the td isn't going to lie about misreport its size when we query it, since it's confidently containing its children.

And once we get the truth from the TD, we tell the div that the size its parent has reported is the size that it needs to be, and give it back its content.

Voila. You've got a div that actually respects its parent now. If only real children were that easy.

like image 112
Josh Burgess Avatar answered Sep 28 '22 08:09

Josh Burgess