0

I am trying for the life of me to make a simple page with a container that stretches to the bottom. The desired outcome:

  1. #Main is at least as tall as the viewport, but can stretch further if content is added.
  2. body is at least as tall as the viewport, but can stretch further if content is added.
  3. html is at least as tall as the viewport, but can stretch further if content is added.

I don't know why this is seemingly impossible. I've tried every combination of height, min-height, etc, but they all fail in one way or another. There is something about <body> where min-height doesn't work.

Here's a fiddle: https://jsfiddle.net/r51tvu2b/

Notice that body isn't honoring the min-height: 100% declaration. I am irritated beyond imagination right now.

Note: I've found solutions that "work", but when content is added the body remains at 100% the viewport height, which is not the desired outcome. That is, in my fiddle, the red line should extend to the bottom of the viewport, and if content is longer, to the bottom of the content.

JS_Riddler
  • 1,443
  • 2
  • 22
  • 32
  • 1
    Possible duplicate of [Child inside parent with min-height: 100% not inheriting height](https://stackoverflow.com/questions/8468066/child-inside-parent-with-min-height-100-not-inheriting-height) – Tyler Roper Oct 07 '19 at 03:11
  • So are you saying this isn't possible? WRT the possible duplicate, it keeps body height at viewport height -- that is, the red line will not move down on my fiddle. – JS_Riddler Oct 07 '19 at 03:13
  • Instead of doing `min-height` on the HTML element, just set it's `height` to 100% and it should work. In the jsfiddle at least. That might just be because of the sandbox it's in though. – Jesse Oct 07 '19 at 03:13
  • The key word here is 'percent'. 100% of *what*? You need a fixed-height ancestor to be able to inherit the height from. If you're looking to make a full-height ``, you want `100vh` (100% of the viewport height). Also, for that matter, why are you trying to put a border at the bottom of ``? Are you trying to create a sticky footer? If so, you'd want two separate elements inside of ``. – Obsidian Age Oct 07 '19 at 03:14
  • 1
    @JS_Riddler You're right, I see that now. I've deleted the suggestion. – Tyler Roper Oct 07 '19 at 03:14
  • @ObsidianAge I need the body to be at least the height of the document, and grow as content grows. I am putting a border so that the body's bottom is visible in the example. As per the why, it's so I can apply styles to the entire document (such as a fading cover) and not just the top portion. – JS_Riddler Oct 07 '19 at 03:16
  • @Jesse I tried changing `min-height` to `height` on `HTML` element. It indeed makes the body as tall as the viewport, but it does not cause `#Main` to stretch to that height, which is a requirement. – JS_Riddler Oct 07 '19 at 03:20
  • Yeah this part of HTML/CSS basically just truly sucks. But don't despair, there is a solution: https://stackoverflow.com/a/17555766/286685 – Stijn de Witt Sep 11 '21 at 11:17

4 Answers4

2

I have made 2 minor changes in CSS and i guess it does what you want now. check Code snippet

html {
  position: relative;
  margin: 0;
  padding: 0;
}
body {
  position: relative;
  background: gray;
  margin: 0;
  padding: 0;
  /* changed here */
  min-height: 100vh;
  border-bottom: 3px solid red;
}
#Main {
  /* changed here */
  min-height: 100vh;
  width: 50%;
  margin: 0px auto;
  background: white;
}
<div id="Main">
    I SHOULD BE AT LEAST AS TALL AS THE VIEWPORT.
    <hr>
    Let's review:
    <br>HTML is min-height: 100% -- it's as least as tall as the viewport.
    <br>BODY is min-height: 100% -- it's as least as tall as HTML.
    <br>*I* am height: 100% -- WHY AM I NOT TALL
    <hr>
    Another WTF: the entire background is gray, yet the BODY's bottom doesn't stretch to the bottom.
    <hr>
    One more thing, when my contents grow, so should the body.
    <button onclick="document.getElementById('content').style.display='block';">
      Click me to add content.
    </button>
    <div id="content" style="height: 600px; background: green; display: none;">
      big content.
    </div>
  </div>

Hope this helps.

  • its there is the css commented, all the talk about the height only. Easy to see whats changed. I put all the code so once can run the code snippet here and see the output –  Oct 07 '19 at 03:23
  • 1
    Ah, didn't see the comments in there. Thanks Saksham. – Tyler Roper Oct 07 '19 at 03:32
  • 1
    This does indeed work, but I'm using a flexbox solution because it has more support. https://caniuse.com/#feat=flexbox vs https://caniuse.com/#feat=viewport-units – JS_Riddler Oct 07 '19 at 03:43
  • 1
    Cool. I just tinkred in your code provided to show what you were doing wrong with heights. flexbox is indeed better. –  Oct 07 '19 at 03:46
0

html {
  margin: 0;
  padding: 0;
}
body {
  position: relative;
  background: gray;
  border-bottom: 3px solid red;
}
#Main {
  min-height: 100vh;
  width: 50%;
  margin: 0px auto;
  background: white;
}
<body>
  <div id="Main">
    I SHOULD BE AT LEAST AS TALL AS THE VIEWPORT.
    <hr>
    Let's review:
    <br>HTML is min-height: 100% -- it's as least as tall as the viewport.
    <br>BODY is min-height: 100% -- it's as least as tall as HTML.
    <br>*I* am height: 100% -- WHY AM I NOT TALL
    <hr>
    Another WTF: the entire background is gray, yet the BODY's bottom doesn't stretch to the bottom.
    <hr>
    One more thing, when my contents grow, so should the body.
    <button onclick="document.getElementById('content').style.display='block';">
      Click me to add content.
    </button>
    <div id="content" style="height: 600px; background: green; display: none;">
      big content.
    </div>
  </div>
</body>

I believe what you should be using is 100vh which means 100% of the viewport height.

-1

I found a way for this to work using flexbox, which has near universal support. It appears that by setting HTML to be display: flex; min-height: 100%, the flexbox will be at least the size of the viewport. Body, a flexbox child, will "stretch" to fit the height of the flexbox. If bodys contents are taller than viewport, they will cause the html flexbox to grow taller as well.

I still have no idea why min-height: 100% on body does not work, as the HTML document clearly has height, when inspected. I tried setting actual heights, and got more results that make no sense -- for example the body would be as tall as the viewport, yet #Main would not be as tall as body, despite having height: 100% -- how is that possible?

It also makes no sense that the body background extends beyond the actual contents of the body itself.

I will stop my post now, because there is only so much BS I can take before I start writing an entire rant about how terrible CSS is.

html {
  min-height: 100%;
  display: flex;
  margin: 0;
  padding: 0;
}
body {
  flex-grow: 1;
  background: gray;
  margin: 0;
  padding: 0;
  border-bottom: 3px solid red;
}
#Main {
  height: 100%;
  width: 50%;
  margin: 0px auto;
  background: white;
}
<div id="Main">
    I SHOULD BE AT LEAST AS TALL AS THE VIEWPORT.
    <hr>
    Let's review:
    <br>HTML is min-height: 100% -- it's as least as tall as the viewport.
    <br>BODY is min-height: 100% -- it's as least as tall as HTML.
    <br>*I* am height: 100% -- WHY AM I NOT TALL
    <hr>
    Another WTF: the entire background is gray, yet the BODY's bottom doesn't stretch to the bottom.
    <hr>
    One more thing, when my contents grow, so should the body.
    <button onclick="document.getElementById('content').style.display='block';">
      Click me to add content.
    </button>
    <div id="content" style="height: 600px; background: green; display: none;">
      big content.
    </div>
  </div>
JS_Riddler
  • 1,443
  • 2
  • 22
  • 32
-1

You can use this code

html {
            height:100%
        } 
        body {
            min-height:100%;
            position: relative;
            background: gray;
            margin: 0;
            padding: 0;
            border-bottom: 3px solid red;
        }
        #Main {
            height: 100%;
            width: 50%;
            margin: 0px auto;
            background: white;
        }
<div id="Main">
    I SHOULD BE AT LEAST AS TALL AS THE VIEWPORT.
    <hr>
    Let's review:
    <br>HTML is min-height: 100% -- it's as least as tall as the viewport.
    <br>BODY is min-height: 100% -- it's as least as tall as HTML.
    <br>*I* am height: 100% -- WHY AM I NOT TALL
    <hr>
    Another WTF: the entire background is gray, yet the BODY's bottom doesn't stretch to the bottom.
    <hr>
    One more thing, when my contents grow, so should the body.
    <button onclick="document.getElementById('content').style.display='block';">
    Click me to add content.
    </button>
    <div id="content" style="height: 600px; background: green; display: none;">
    big content.
    </div>
    </div>
Piyush Teraiya
  • 739
  • 4
  • 7
  • 1
    This does not work, `#Main` does not stretch to the viewport height when it is too short. Even though `body` has a `min-height: 100%`, and is indeed as tall as the viewport (it's bottom border is even at the bottom of the viewport), for some reason `#Main` will not stretch. I'm sure some CSS apologist will come by and enlighten us with the inane rules deep from the CSS docs. – JS_Riddler Oct 07 '19 at 09:18