3

The script purpose is to change some special divs size without using width and height CSS properties.

<html>
    <head>
        <title>Test resizer</title>
        <script type = 'text/javascript'>
            function endsWith(str, suffix)
            {
                if (!str)
                    return false;

                return str.toString().indexOf(suffix, str.length - suffix.length) >= 0;
            }

            function fixSizeFor(start_elem)
            {
                if (document && document.body)
                {
                    var curr_elem = start_elem ? start_elem : document.body;

                    var force_size = curr_elem.getAttribute("data-forcesize");

                    if (force_size && curr_elem.parentNode.style.position.toLowerCase() == "relative" && curr_elem.style.position.toLowerCase() == "absolute")
                    {
                        var needed_width_str = curr_elem.getAttribute("data-neededwidth");
                        var needed_height_str = curr_elem.getAttribute("data-neededheight");

                        if (endsWith(needed_width_str, "%"))
                        {
                            var n_w = needed_width_str.substr(0, needed_width_str.length - 1)
                            var calculated_w = (curr_elem.parentNode.clientWidth * n_w) / 100;

                            if (curr_elem.style.width != calculated_w + "px")
                                curr_elem.style.width = calculated_w + "px";
                        }

                        if (endsWith(needed_height_str, "%"))
                        {
                            var n_h = needed_height_str.substr(0, needed_height_str.length - 1)
                            var calculated_h = (curr_elem.parentNode.clientHeight * n_h) / 100;

                            if (curr_elem.style.height != calculated_h + "px")
                                curr_elem.style.height = calculated_h + "px";
                        }
                    }

                    for (var i = 0; i < curr_elem.children.length; i++)
                        fixSizeFor(curr_elem.children[i]);
                }
            }

            setInterval(function () { fixSizeFor(null); }, 100); //comment this and weird space gone
        </script>
    </head>

    <body>
        <table border = '1' style = "width: 100%; height: 100%;">
            <tr>
                <td style = 'position: relative;'>
                    <div data-forcesize = 'true' data-neededwidth = '100%' data-neededheight = '100%' style = 'position: absolute; top: 0px; left: 0px; overflow: auto; border: dashed;'>Why the hell there is some space under table border?!</div>
                </td>
            </tr>
        </table>
    </body>
</html>

enter image description here Weird space appears in IE7 - IE11 and MS Edge. Opera 15 and latest Chrome are fine.

How I can avoid this?

Kosmo零
  • 4,001
  • 9
  • 45
  • 88
  • 2
    you have a border on your table. so it's 100% + 2px high and wide. – Marc B Nov 17 '15 at 21:16
  • @MarcB - nothing will change if I remove borders. I set those just to show where they are. – Kosmo零 Nov 17 '15 at 21:17
  • 2
    `box-sizing: border-box` – Szabolcs Páll Nov 17 '15 at 21:18
  • @SzabolcsPáll - What should I do with it? I tried all 3 possible values in my div and nothing changed. – Kosmo零 Nov 17 '15 at 21:24
  • I meant `* { box-sizing: border-box; }`. – Szabolcs Páll Nov 17 '15 at 21:27
  • I added this `` into `head` section, but nothing changed. I did something wrong? – Kosmo零 Nov 17 '15 at 21:29
  • Can you recreate this problem in a fiddle? – wouter140 Nov 20 '15 at 08:21
  • @wouter140 - I don't know how to do this, but will try – Kosmo零 Nov 20 '15 at 08:22
  • @wouter140 - looks like it does not work in fiddle as expected https://jsfiddle.net/w3vnmspu/ So I never used it before. – Kosmo零 Nov 20 '15 at 08:24
  • okay, so i just created my own html page, copy and pasted your code in it. And i get the same result. Now is there a reason the `td ` has to be `relative` and `div` has to be `absolute`? – wouter140 Nov 20 '15 at 08:39
  • @wouter140 - This is to make scrolling inside TD. TD does not support scrolling, so I need to place div in it. Since I can't use CSS width and height properties `div` should be `absolute`, so I can !reduce! it's size after table being shrink. If position is not absolute, then table will stay same size as div. Like I can increase div's size to math TD size, but can't reduce it. – Kosmo零 Nov 20 '15 at 08:40
  • not on the fiddle, I created my own html page to test it. Now is there a reason the `td` has to be `relative` and `div` has to be `absolute`? – wouter140 Nov 20 '15 at 08:43
  • @wouter140 - To be able to reduce div's size when TD being reduced. If div is not `absolute` then I can't reduce it, because TD will not reduce it's size because it contains `div` of fixed size inside. – Kosmo零 Nov 20 '15 at 08:54
  • I can almost guarantee that this is a quirks issue. Is there a reason that you're doing this without a Doctype which is forcing the this into CSS1CompatMode? I highly suggest using ` ` as that will allow all modern browsers to go into the standard's compliant mode. – gregwhitworth Nov 21 '15 at 05:34
  • @coldcoder - Using standard doctype leads to another unsolved bugs that I described here http://stackoverflow.com/questions/25119868/why-my-heights-fixer-code-work-wrong-when-browser-window-restored-after-being-ma – Kosmo零 Nov 21 '15 at 09:06
  • Are you trying to make the `div` inside the `table td` fit the entire space of the document window? So when you resize the browser window the `div` fills `width` `100%` and `height` `100%` of the window space ? So the `height` is always `100%` and always touches the bottom? – Jonathan Marzullo Nov 25 '15 at 16:40
  • @JonathanMarzullo - Umm, all I need is to make `div` same size as `td`, no matter what `td` size is and when my script modifies `div` size some weird space appears. Just create html file on your PC, paste my example and test it in IE. – Kosmo零 Nov 25 '15 at 19:51

2 Answers2

2

Okay, Changing your html to this will resolve your "Weird space". You could fine tune this by changing your calculation of the width and height, or just changing your data-neededwidth and data-neededheight attributes like I did.

<html>
<head>
<title>Test resizer</title>
<script type = 'text/javascript'>
    function endsWith(str, suffix)
    {
        if (!str)
            return false;

        return str.toString().indexOf(suffix, str.length - suffix.length) >= 0;
    }

    function fixSizeFor(start_elem)
    {
        if (document && document.body)
        {
            var curr_elem = start_elem ? start_elem : document.body;

            var force_size = curr_elem.getAttribute("data-forcesize");

            if (force_size && curr_elem.parentNode.style.position.toLowerCase() == "relative")
            {
                var needed_width_str = curr_elem.getAttribute("data-neededwidth");
                var needed_height_str = curr_elem.getAttribute("data-neededheight");

                if (endsWith(needed_width_str, "%"))
                {
                    var n_w = needed_width_str.substr(0, needed_width_str.length - 1);
                    var calculated_w = (window.innerWidth * n_w) / 101;

                    if (curr_elem.style.width != calculated_w + "px")
                        curr_elem.style.width = calculated_w + "px";
                }

                if (endsWith(needed_height_str, "%"))
                {
                    var n_h = needed_height_str.substr(0, needed_height_str.length - 1);
                    var calculated_h = (window.innerHeight * n_h) / 101;

                    if (curr_elem.style.height != calculated_h + "px")
                        curr_elem.style.height = calculated_h + "px";
                }
            }

            for (var i = 0; i < curr_elem.children.length; i++)
                fixSizeFor(curr_elem.children[i]);
        }
    }

    setInterval(function () { fixSizeFor(null); }, 100); //comment this and weird space gone
</script>
</head>

<body>
<table id="table" border = '1' style = "width: 100%; height: 100%;">
<tr>
    <td style = 'position: relative;'>
        <div data-forcesize = 'true' data-neededwidth = '99%'  data-neededheight = '97.5%' style = 'position: relative; top: 0; left: 0; overflow: auto; border: dashed;'>Why the hell there is some space under table border?!</div>
    </td>
</tr>
</table>
</body>
</html>
wouter140
  • 255
  • 2
  • 12
  • Thank you for your efforts, but this is not accurate. If I remove borders and add `background-color` to div, and resize the page to around the half it is clearly seen that `table` has greater size than window and both scroll bars appears, while there shouldn't be any. More than that, I need a generic solution, not hacky one for this case. I have a lot of other places like this with different needed sizes and can have those unlimited amount, because it's all dynamic. – Kosmo零 Nov 20 '15 at 09:33
  • You could fine tune this by changing your calculation of the width and height, or just changing your data-neededwidth and data-neededheight attributes like I did. – wouter140 Nov 20 '15 at 14:53
1

Sometimes with IE you have to be specific with your heights since it is really strict when it comes to calculated height.

What about this:

http://codepen.io/jonathan/pen/qOzbMa/

I added in the CSS for html and the body tags height: 100%. Which allows its descendants (children) in the DOM to extend their height to the bottom of their parent.

html, body {
  height:100%; /* important to allow children to inherit */
}

I removed position relative off of the td since tables and position relative are buggy in IE. Its better to just nest another div tag as the parent for your absolutely position div.

<table border="1" style="width: 100%; height: 100%;">
  <tr>
    <td>   
       <!-- 
       height 100% on both relative and absolute positioned
       elements to extend their height to bottom of their parent.
       that is why the html and body tag have their height 100%
       which allows its children to inherit the height 100%
       -->                 
       <div style='position: relative; height: 100%;'>     
          <div style='width: 100%; height: 100%; position: absolute; top: 0px; left: 0px; overflow: auto; border: dashed;' data-forcesize='true' data-neededwidth='100%' data-neededheight='100%'>Why the hell there is some space under table border?!</div> 
      </div>
    </td>
  </tr>
</table>

I also added height:100% to the div with position: relative, so it extends its height to the bottom of its parent. I also added width:100% and height:100% to your div with position: absolute, so the div extends its height to the bottom of its parent.

Tables in IE are buggy with height, especially if you use position relative on a td (table-data cell), since it's display property is set to table-cell. Unlike a div tag's default display property which is block.

Jonathan Marzullo
  • 6,879
  • 2
  • 40
  • 46
  • Thank you for the answer. Sadly, this relay on `width` and `height` CSS properties. You showed me my previous solution that forced me to code the junk JS you saw in answer. In some cases double div solution is not working in IE8. Inner div's simply doesn't react to height 100% and stays invisible with all it's content. I will perform more tests and show you this. I can't do this now because already migrated to junk JS code solution. – Kosmo零 Nov 26 '15 at 11:08
  • @Kosmos I'm unsure why you can't use width and height CSS properties? .. since the browser page renders using CSS. And you are also using and setting CSS via your JS resizer script. would there be a reason why you don't want to use CSS width and height, just curious? .. I look forward to seeing your test example! Thanks – Jonathan Marzullo Nov 26 '15 at 17:26
  • My script setting `px` values that should work no matter what, while `%` values set in tag does not work in some cases. Look at this http://pastebin.com/CwTKgcV7 example. I ripped it from my project and set search points for you. `search point 1` and `search point 2`. That double divs simply looks like horizontal line. – Kosmo零 Nov 26 '15 at 18:49