Elements do not find enough space inside the body - JavaScript style

Relevant Information:

The page contains two elements:

  • And <aside> left.

  • A <main> to the right.

( Note: In this column, heights are for completeness, but not important for creating this problem.)

All heights, widths and margins are set relative to var w = screen.width/100; (and var h = screen.height/100; ) so that the page essentially looks the same in any screen resolution. And they are set so that the width is <aside> and <main> , and the difference between them is up to screen.width .

For example:

 var w = screen.width/100; document.getElementsByTagName('main')[0].style.width = 85.5*w + "px"; document.getElementsByTagName('aside')[0].style.width = 14*w + "px"; document.getElementsByTagName('aside')[0].style.marginRight = 0.5*w + "px"; 

(85.5 + 14 + 0.5 = 100)

Problem:

<main> for unknown reasons falls below <aside> . I can only think of a semi-sensitive hypothesis to explain this behavior somewhat.

However, if I set the font size of the body to 0 and reduce the scale (so that the elements take up less space) and increase the scale again, this is fixed (I don’t know why and I’m not asking how I found it).

What is the reason for this behavior and what is the correct fix?

Hypothesis (may be omitted):

The browser seems to be thinking, “What happens if I show the scroll bars even if they aren’t needed?” And then notices that the scroll bars are> 0 wide, which means that <aside> and <main> take up more space than what is available (since they are set to 100% of the screen width, and now there is a scroll bar competing for space). Therefore, the browser decides to move <main> under <aside> and destroy the design.

And now, since <main> is located under <aside> , elements no longer fit inside the screen , and scrollbars are actually needed now and therefore remain, although they are the reason for their own existence (as far as this hypothesis goes).

Additional Information:

  • I don’t use a CSS stylesheet: all my style is JavaScript (for the simple reason that I want the sizes to depend on screen.width and screen.height ).

  • Elements have display = "inline-block"; . Using float creates horrific behavior when the browser has nothing but the maximum size.

Here is the code to reproduce the problem:

 <!DOCTYPE html> <html> <body> <aside></aside> <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> 
+7
javascript html css responsive-design
source share
7 answers

Update after editing a question

The reason your main falls under aside is because you have invisible space, in your case a line break, but it could also be a simple space between your elements in your markup, which the size actually adds along with the elements, which make it more than 100% wide, so create a scroll bar.

This space, which exists for inline elements (which are not positioned absolute or fixed or floating), must be taken into account together with the size of the elements when calculating their width in order to match the width of their parents (in this case, body / viewport).

Here you can learn more about this and how to get rid of it or make it size 0 (if you save the inline elements).

Other ways to align elements side by side is to use display: flex or display: table-cell , both with similar behavior and with built-in elements (in the sense of laying horizontal as opposed to block elements that flow vertically), although it does not suffer from white space in the same way when it comes to its fixed size compared to the actual size.

To clarify, i.e. if the value on the flex element is 14.5%, it is 14.5% and no more, unlike the built-in, which is 14.5% plus a space (where the size of the free space actually depends on the font size set)

display: flex example display: flex (recommended)

 * { box-sizing: border-box; } html, body { margin: 0; height: 100%; } body { display: flex; height: 100%; } aside { width: 14%; margin-right: 0.5%; background-color: #f66; } main { width: 85.5%; background-color: #66f; } 
 <aside> aside </aside> <main> main </main> 

display: table-cell example display: table-cell (for older browsers)

 * { box-sizing: border-box; } html, body { margin: 0; height: 100%; } body { display: table; width: 100%; height: 100%; } aside { display: table-cell; width: 14%; background-color: #f66; } main { display: table-cell; width: 85.5%; background-color: #66f; } .margin { display: table-cell; width: 0.5%; } 
 <aside> aside </aside> <div class="margin"></div> <main> main </main> 

Note:

Other ways to make the difference between aside and main when using display: table is to use cell fill, border width, etc.


With your existing code, and since you are not using a regular thread, absolute positioning may be an option.

 <!DOCTYPE html> <html> <body> <aside></aside> <main></main> <script> var h = screen.height/100; var w = screen.width/100; var e = document.getElementsByTagName("aside")[0].style; e.position = "absolute"; /* changed */ 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.position = "absolute"; /* changed */ e.backgroundColor = "green"; e.width = 85.5*w + "px"; e.height = 69*h + "px"; e.left = 14.5*w + "px"; /* added */ e = document.getElementsByTagName("body")[0].style; e.margin = e.padding = "0"; e.backgroundColor = "black"; </script> </body> </html> 

Update 2

The problem with your code is that it starts until the DOM completes completely, so create scrollbars. Try the example below, where I added a delay, and you will see that it works (when the browser works as much as possible).

 <!DOCTYPE html> <html> <script> function runOnLoad() { setTimeout(function() { 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"; e.fontSize = "0"; }, 200) } </script> <body onload="runOnLoad();"> <aside></aside> <main></main> </body> </html> 
+6
source share

The scroll hypothesis is correct. Here is the solution: How to get the width of the screen without (minus) scrollbar? . I tested it and using document.body.clientWidth solves the problem. Another problem is that the elements of the inline block must be joined together without spaces or newlines (to avoid unwanted fields).

 <body><aside></aside><main></main></body> 
+3
source share

The problem is the gap between your aside and main , taking up some space, because inline-block is used for display.

The answer from @Shah Abaz Khan is right, you need to get rid of this gap.

This can be done by deleting it as suggested:

 <aside></aside><main></main> 

But you want to keep your html indent, you can also use html comments <!-- --> :

 <aside> //stuff </aside><!-- --><main> //other stuff </main> 
+2
source share

An almost complete explanation:

The following works (but there are other ways to do this):

  • Change the body font size to 0 so that the gaps between the elements of the inline block become 0 (or use any other method). This is explained in detail in other answers.

  • Give the body a fixed width. In this case, screen.width . The reason why this works is a bit complicated. Please note: if not specified, the body will occupy the entire width of the browser (not necessarily the screen). There are two scenarios:

    • ( Warning: This part is closer to the hypothesis than the correct answer.) When the browser is maximum (the width of the screen and the browser are the same), the body will have the maximum width of screen.width (if necessary), so the elements do not take up too much space. However, since the body does not immediately know how wide it should be, it seems that it is not "ready", so the elements ultimately take up too much space. This is why giving the body its width in advance corrects this problem (there are other ways around this - see Other Answers).

    • When the browser is not maximized, the maximum body width is the width of the browser window, not the screen. The combined width of the elements is now greater than the width of the body, hence this behavior. Giving the body a fixed width of screen.width is a fix, but there are other solutions (like setting a white space in no-wrap).


Here is the code after the proposed changes:

 <!DOCTYPE html> <html> <body> <aside></aside> <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"; e.fontSize = "0"; //this line e.width = 100*w + "px"; //and this line have been added </script> </body> </html> 
+1
source share

I don’t use a CSS stylesheet: all my styles are done using JavaScript (for the simple reason that I want the sizes to depend on screen.width and screen.height).

Elements have display = "inline-block";

You should know that these are the special units you deal with:

  • vh: viewport height
  • vw: viewport width

Example

Note: you can ignore the section "Visual Material"

 /* VISUAL STUFF */ aside { background-color: hsl(0, 85%, 65%); } main { background-color: hsl(180, 85%, 65%); } /* SIZING STUFF */ body { /* I guess you don't need it */ margin: 0; /* prevent white space display */ font-size: 0; /* better keep*/ white-space: nowrap; } aside,main { /* your constraint */ display: inline-block; /* Set font size back to normal */ font-size: initial; /* if you want the height to fit sreen */ /* this means "height = 100% of viewport height" */ height: 100vh; } aside { /* 14% of viewport width */ width: 14vw; /* and so on ... */ margin-right: 0.5vw; } main { width: 85.5vw; } 
 <!DOCTYPE html> <html> <body> <aside>aside</aside> <main>main</main> </body> </html> 
+1
source share

This is a simple css solution

 body { white-space: nowrap; } aside, main { white-space: normal; } 

but since you are trying to completely eliminate the use of a style element, alternatively, you can use equivalent JavaScript stylists.

 <!DOCTYPE html> <html> <body> <aside></aside> <main></main> <script> var h = screen.height/100; var w = screen.width/100; var e = document.getElementsByTagName("aside")[0].style; e.whiteSpace = "normal"; 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.whiteSpace = "normal"; 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.whiteSpace = "nowrap"; /*additional precaution*/ e.overflow = "visible"; e.backgroundColor = "black"; </script> </body> </html> 

However, I notice that your calculations depend on the size of the screen, which is most likely the source of the original problem.

Sincerely.

+1
source share

I found a reason!

Change your html to

 <aside></aside><main></main> 

There is no space between the tags because the visible inline elements of the block occupy the gap between them. Remove this by removing the spaces between them or adding empty comments between them.

This is not a “mistake” (I don’t think so). This is just a way to adjust elements on the line. Do you want the spaces between the words you entered to be correct? The spaces between these blocks are just spaces between words. This does not mean that the specification cannot be updated to say that the spaces between the elements of the inline block should be nothing, but I am sure that this is a huge possibility of worms that is unlikely to ever happen.

More details here.

Here is the JS FIDDLE demo

+1
source share

All Articles