1

(This is a follow-up on my previous question if anybody is interested in the background story for entertainment purposes. It will probably not help you understand this question.)


Here are two elements <aside> and <main> who have got their width and height via JavaScript so that their combined width is the width of your screen (note that their display is inline-block). If you run this code in your web browser (a maximized browser so that the width of your browser equals the width of your screen) you might note that the body surprisingly does not properly fit the elements:

<!DOCTYPE html>
<html>    
<body> 

<aside></aside><!-- comment to remove inline-block whitespace

--><main></main>

<script>
  var h = screen.height/100;
  var w = screen.width/100;

  var e = document.getElementsByTagName("aside")[0].style;
  e.display = "inline-block";
  e.backgroundColor = "lightblue";
  e.width = 14*w + "px";
  e.height = 69*h + "px";
  e.marginRight = 0.5*w + "px";

  e = document.getElementsByTagName("main")[0].style;
  e.display = "inline-block";
  e.backgroundColor = "green";
  e.width = 85.5*w + "px";
  e.height = 69*h + "px";   

  e = document.getElementsByTagName("body")[0].style;
  e.margin = e.padding = "0";
  e.backgroundColor = "black";
</script>
</body>
</html>

If you however give the JavaScript a delay, the elements are rendered properly. This suggests that the body somehow "needs time" to figure out its correct width:

<script>
  setTimeout(function() {

    [...]

  }, 200);
</script>

It is also possible to give the body the specified width of screen.width instead of introducing the delay, by adding the following line. This supports the previous guess that the body does not immediately know its correct width (unless specified):

<script>

  [...]

  e.width = 100*w + "px";
</script>

Even though I have taken the freedom to throw wild guesses to explain this, I do not actually have a clue to what is going on.

Why are the elements not placed properly in the first place, and why do these two solutions work?


(Note: It is also possible to fix this by setting the whitespace of the body to nowrap with e.whiteSpace = "nowrap";, but I suspect this does not do the same thing as the other two. Instead of creating space for the elements inside the body, this simply forces the elements to be next to each other even though there is not enough room in the body.)

Community
  • 1
  • 1
RaminS
  • 2,208
  • 4
  • 22
  • 30

1 Answers1

0

You should wait for the DOM to be available before running your code, see here: pure JavaScript equivalent to jQuery's $.ready() how to call a function when the page/dom is ready for it. That is possibly why setTimeout works. Also you should assign seperate variable names for your different elements.

// self executing function before closing body tag
(function() {
   // your code here
   // the DOM will be available here
})();

Is there a reason you are using Javascript and not CSS to accomplish this task? I suggest giving your elements css ids ie id="aside", then set your css styles:

html,body {
  width: 100%;
  height: 100%;
}
#aside {
  display:inline-block;
  position: relative;
  float: left;
  width: 14%;
  height: 69%;
  background: blue;
}
#main {
  display:inline-block;
  position: relative;
  float: left;
  width: 86%;
  height: 31%;
  background: azure;
}
Community
  • 1
  • 1
  • The accepted answer to the question in your link states that it is good enough to have the JavaScript at the end of the body, which I have. – RaminS May 03 '16 at 23:37
  • To answer your second point, no CSS that I am aware of can style the HTML the same way as JavaScript styling with respect to `screen.width` and `screen.height`. % in CSS refers to the width/height of the web browser, not the screen. – RaminS May 03 '16 at 23:41
  • The accepted answer also says to execute your js after the DOM is ready by wrapping your code in a self executing function or using on ready code like jQuery does, try that and see how you go. –  May 03 '16 at 23:49
  • I have updated the answer now, let me know if that works for you. –  May 03 '16 at 23:55