5
<!DOCTYPE html>
<html style = 'height: 100%;'>
    <head>
        <title>test manual height calculations</title>
    </head> 

    <script type = 'text/javascript'>
        window.onresize = fixHeighs;

        function endsWith(str, suffix)
        {
            if (!str)
                return false;

            return str.indexOf(suffix, str.length - suffix.length) !== -1;
        }

        function fixHeighs(start_elem)
        {
            if (start_elem && start_elem.target) // if this is event, then make var null
                start_elem = null;            

            var curr_elem = start_elem ? start_elem : document.body; // determine what element we should check now
            var neededHeight = curr_elem.getAttribute("data-neededHeight"); // get data-neededHeight attribute

            if (endsWith(neededHeight, "%")) // if this attribute set
            {
                curr_elem.height = ((neededHeight.replace("%", "") * curr_elem.parentElement.offsetHeight) / 100) + "px"; // fix heights
                curr_elem.style.height = ((neededHeight.replace("%", "") * curr_elem.parentElement.offsetHeight) / 100) + "px";
            }

            for (var i = 0; i < curr_elem.children.length; i++)
                fixHeighs(curr_elem.children[i]); //do the same for children
        }
    </script>

    <body style = 'height: 100%; margin: 0px;' onload = "fixHeighs(null);">
        <table border = '1' width = '100%' data-neededHeight = '100%'>
            <tr>
                <td colspan = '2' height = '1px'>header</td>
            </tr>
            <tr>
                <td width = '40%' align = 'center' valign = 'middle' bgcolor = 'silver'>
                    <div data-neededHeight = '100%' style = 'width: 90%; border: dashed;'>should be 100% of silver cell</div>
                <td>text</td>
            </tr>
            <tr><td colspan = '2' height = '1px'>bottom panel</td></tr>
        </table>
    </body>
</html>

I wrote this "awesome" code, that fixes elements height for stupid browsers that calculate it wrong. It fixes height fine when user resize browser by holding it's borders with mouse or window maximizes, but once window getting restored, heights calculated wrongly and scroll bar appears. I need to know why and how to fix it.

Most likely you will want to ask "why the hell I doing that?!"

That's the explanation of the problem:
I need, I REALLY NEED to have page height at 100% of browser window.

This ultimate simple code:

<!DOCTYPE html>
<html style = "height: 100%;">
    <head>
    <title>test height</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta http-equiv = "Content-Type" content = "text/html; charset = windows-1251" />
    </head>

    <body style = "height: 100%; margin: 0px;">
        <table border = "1" width = "100%" height = "100%">
            <tr>
                <td colspan = "2" height = "1px">header</td>
            </tr>
            <tr>
                <!-- can add height = '100%' in this TD and then in IE8 - 10, Opera 12.17 inner div height will be 100% OF PAGE, instead of this cell--><td width = "40%" <!--height = '100%'--> align = "center" valign = "middle" bgcolor = 'silver'>
                    <div style = 'width: 90%; height: 100%; border: dashed;'>should be 100% of silver cell</div>
                </td>
                <td>text</td>
            </tr>
            <tr><td colspan = "2" height = "1px">bottom panel</td></tr>
        </table>
    </body>
</html>

Gives ultimate weird results in IE8 - IE10 and Opera 12.x The inner div height would be "minimal to fit content" or calculated based on window height, instead of that parent TD. enter image description here

enter image description here

IE11 is the only one browser that calculates height of inner div correctly. enter image description here P.S. If you can solve main problem for IE8 - 10, Opera 12.x height calculations without JS, would be even better.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Kosmo零
  • 4,001
  • 9
  • 45
  • 88
  • 2
    You should really use something else than a table based layout. Table based layouts are from the 90s. Look into something like http://getbootstrap.com – Kristian Barrett Aug 04 '14 at 13:33
  • 1
    I like tables, more than that, same story applies for divs height. – Kosmo零 Aug 04 '14 at 13:34
  • I have noticed that onresize doesn't always fire right when maximizing or restoring a window, I've also had trouble with that. Maybe that's the issue? – Liam Martens Aug 07 '14 at 07:39
  • try adding a jsfiddle, then we can play around with your code... – DoXicK Aug 07 '14 at 07:41
  • I don't know. It fires for me, some times even 2 - 3 times, but problem is at "Restore" content height after running my script becomes bad. – Kosmo零 Aug 07 '14 at 07:41
  • @DoXicK - I can't do that, because it says no need for html and meta tags, but I need those! The cause of bad div size is ` ` and `` those needed, but can't be inserted. – Kosmo零 Aug 07 '14 at 07:44
  • @Kosmos this might give you some explanation as to what is happening: http://stackoverflow.com/questions/1852751/window-resize-event-firing-in-internet-explorer . Since i'm not going to debug a page which uses table based layout (sorry, but that is just plain wrong. Nothing about preference, it's wrong.), i can't do much more for ya. – DoXicK Aug 07 '14 at 07:52
  • @DoXicK - Thank you, however, I just tested that statement and IE do not fire `onresize` when some element changes it's dimensions. I tried that: `document.getElementById('test_div').style.width = '91%';` No resize event were fired. – Kosmo零 Aug 07 '14 at 08:00
  • @haxxxton - There is no any CSS associated with it and jsfiddle doing things wrong. To test that *.html file should be created on your PC and tested. – Kosmo零 Aug 07 '14 at 08:11

3 Answers3

3

You don't need javascript or tables to achieve the layout you want.

box-sizing: border-box; can replace that javascript and is compatible with IE8+, FF, and Chrome. This is a good article on box-sizing.

New Example

Take this snippet and paste it into a new HTML document. This works in IE8, though we need to accommodate for it with height 99.8% on html,body using <!--[if IE 8]>.

This is the exact solution here.

HTML and CSS

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>


  <style type="text/css">
  * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html,body {
    height: 100%;
}
.wrap {
    height: 100%;
}
.header {
    height: 5%;
    border: solid 1px #000;
    border-bottom: none;
}
.table {
    display: table;
    height: 90%;
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
}
.cell {
    display: table-cell;
    border: solid 1px #000;
    vertical-align: middle;
    height: 100%;
}
.footer {
    height: 5%;
    border: solid 1px #000;
    border-top: none;
}
.tableTwo {
    height: 100%;
    display: table;
    width: 100%;
}
.cellTwo {
    display: table-cell;
    border: solid 5px #F00;
    vertical-align: middle;
}
  </style>

    <!--[if IE 8]>
    <style type="text/css">
        html,body {
            height: 99.8%;
    }
    </style>
<![endif]-->

</head>
<body>
    <div class="wrap">
        <div class="header">
            Header
        </div>      

        <div class="table">

            <div class="cell">

                <div class="tableTwo">

                    <div class="cellTwo">
                        I'm Vertically Centered!
                    </div>

                </div>

            </div>

            <div class="cell">
                I'm Vertically Centered!
            </div>

        </div>

        <div class="footer">
            Footer
        </div>      
    </div>      
</body>
</html>

Original Example

Here is a simple example featuring display: table; / display:table-cell;. It can be tweaked to give you the exact layout that you are looking for.

Have a jsBin example!

HTML

<div class="wrap">
    <div class="header">
        Header
    </div>      

    <div class="table">

        <div class="cell">
            I'm Vertically Centered!
        </div>

        <div class="cell">
            I'm Vertically Centered!
        </div>

    </div>

    <div class="footer">
        Footer
    </div>      
</div>

CSS

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}    
html,body {
    height: 100%;
}
.wrap {
    height: 100%;
}
.header {
    height: 5%;
    border: solid 1px #000;
    border-bottom: none;
}
.table {
    display: table;
    height: 90%;
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
}
.cell {
    display: table-cell;
    border: solid 1px #000;
    vertical-align: middle;
}
.footer {
    height: 5%;
    border: solid 1px #000;
    border-top: none;
}
misterManSam
  • 24,303
  • 11
  • 69
  • 89
1

Ok so after a little research, it appears this is really only capable of being done with JS as a companion. Research:

They led me to this awesome little CSS Tricks page. (requires jQuery, tested using 1.9.1 [should be IE8 compatible]). That helps to let div elements get position:absolute; within a td and not spill out.

As such, here is a link to a JSFiddle with your code as a base. It was necessary to position:absolute some elements, and others i added it to for cleanliness (as much as is possible with a table based layout).

Tested on IE8, IE9, IE10, and working as expected.

(If you right click on the output and view source, you should be able to see an html file that you can save and test with as a file outside of jsfiddle)

Community
  • 1
  • 1
haxxxton
  • 6,422
  • 3
  • 27
  • 57
  • Ugh, thank you for that, but this solution do not fit me because of two things - absolute positioning and external libs. I doing very sensitive thing. It's not site. I developing course creator software that creates courses in html. One of requests is no external libs. I still add +1 to you :P – Kosmo零 Aug 07 '14 at 09:17
  • 2
    thanks, all i can hope is that with it being built using `table`s that its not web development courses you're creating :P – haxxxton Aug 07 '14 at 09:20
  • @Kosmos can i ask why no absolute positioning.. i can create a version with no external libs – haxxxton Aug 07 '14 at 09:21
  • Well, courses maybe be for any theme. But sorry, I see many table "haters" around. How easy I can do same layout with divs? For example I want same layout. one upper panel, two panels of same width in middle and one bottom panel. Then I want to vertically center panels content. What should I do? – Kosmo零 Aug 07 '14 at 09:28
  • divs would be SO much easier :D.. but you would still probably need to have access `position:absolute`. Is there a reason you cant use that? – haxxxton Aug 07 '14 at 09:29
  • About absolute positioning. My cousre creator offers two types of elements positioning: absolute and static. The solution you provide could cause a huge mess if person creates all other elements with static positioning. I have a `controls` that user can put on page. It's combinations of different tags to provide ready to use menus, cool looking tables and etc. User can put one control into another. So the layout you see here can be actually put into 100x100 div with static positioning. BUT, having some of those tags position absolute will cause that layout be completely in wrong place! – Kosmo零 Aug 07 '14 at 09:29
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/58862/discussion-between-haxxxton-and-kosmos). – haxxxton Aug 07 '14 at 09:30
-1

I had the exact same issue working on a project. It ended up that the best trick to end up with a cross-browser solution was actually absolute positionning.

.wrap{background:pink;position:absolute;top:0;left:0;right:0;bottom:0}

You are allowed to be sceptical, but have a look at this jsfiddle ;)

http://jsfiddle.net/evomk0zu/

Marion LP
  • 142
  • 5