Asons
Asons

Reputation: 87211

How to make flex container not force scroll on body

In the code sample I did:

Now this gives me a scroll on the body even if the flex containers height + margin-top only sums up to 98%, so my question is, can't I use margin-top is this way and where does the extra space come from forcing the body to scroll?

Setting the body to overflow:hidden removes the scroll, but that feels more like a band-aid and not considered as a solution (unless this is a "behavior-by design" which needs that in this case).

Edit

Ways like remove the margin-top on the flex container and then set a padding-top: 2%; on the body or use position: relative; top: 2%; on the container or with absolute: position; I can make it work as expected though, but the case here is why margin-top: 2% doesn't do it.

* {
  box-sizing: border-box;
  padding: 0;
  margin: 0
}
html, body {
  background-color: gray;
  height: 100%;
}
.outer {
  display: flex;
  flex-flow: column;
  margin: 0 auto;
  height: 96%;
  width: 50%;
  margin-top: 2%;
}
.top {
  background-color: lightgray;
}
.middle {
  background-color: darkgray;
}
.the-rest {
  flex: 1 0 auto;
  background-color: lightgray;
}
<div class="outer">
  <div class="top">
    top
  </div>
  <div class="middle">
    middle
  </div>
  <div class="the-rest">
    content
  </div>
</div>

Upvotes: 1

Views: 1486

Answers (2)

zer00ne
zer00ne

Reputation: 43930

I usually use vh and vw on html and body. In this demo I applied vh only since it looked like a vertically oriented demo. I also make the body and html position: relative. With vw and vh there's a real measured length that other elements (children of ::root) can actually set their relative measurements of 100%. I use position: relative because it makes the html, body sit rigidly inside the view port and the viewport units keep the body, html on the edge at 100vh and 100vw.

UPDATE

I think this behavior is due to collapsing-margins So if there's an illogical margin-top behavior, keep that in mind. There are several very specific circumstances that result in this odd behavior and there are a few solutions as well. The solution for these circumstances are as follows:

  1. body, html { height: 100vh; } /* no relative or absolute positioning */
  2. .outer { min-height: 100%; margin-top: -2%; } /* It's explained that the positive numbered margin-top is not effective and yet the negative value works but not like a normal negative value!? o_0

* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
}
html,
body {
  position: relative;
  background-color: gray;
  height: 100vh;
}
.outer {
  display: flex;
  flex-flow: column;
  margin: 0 auto;
  min-height: 100%;
  width: 50%;
  margin-top: - 2%;
  border-top: 0;
}
.top- {
  background-color: lightgray;
}
.middle {
  background-color: darkgray;
}
.the-rest {
  flex: 1 0 auto;
  background-color: lightgray;
}
.marker {
  position: absolute;
  outline: 1px solid red;
}
<span class="marker" style="top: 0; left: 0;">top:0|left:0</span>
<span class="marker" style="top: 0; right: 0;">top:0|right:0</span>
<div class="outer">

  <div class="top">
    top
  </div>
  <div class="middle">
    middle
  </div>
  <div class="the-rest">
    content
  </div>
</div>
<span class="marker" style="bottom: 0; left: 0;">bottom:0|left:0</span>
<span class="marker" style="bottom: 0; right: 0;">bottom:0|right:0</span>

Upvotes: 1

Paulie_D
Paulie_D

Reputation: 115174

This is because percentage margins are based on the width of the containing block / element...in this case, the body.

W3C Spec

MDN

A <percentage> relative to the width of the containing block. Negative values are allowed.

Upvotes: 1

Related Questions