1

In the code sample I did:

  • reset all margins/paddings to 0
  • set body height to 100%
  • set flex container height to 96%
  • set flex container margin-top to 2%

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>
Brian
  • 3,850
  • 3
  • 21
  • 37
Asons
  • 84,923
  • 12
  • 110
  • 165
  • FYI, the `flex` tag refers to Apache Flex. For the CSS *flex* property use the tag `flexbox` instead. – Brian Nov 20 '15 at 16:36
  • Down voter, please comment if there is something I can clarify instead of just down vote. – Asons Nov 20 '15 at 16:38
  • It might be `collapsing-margins` see http://stackoverflow.com/a/33597266/2813224 and https://css-tricks.com/what-you-should-know-about-collapsing-margins/ – zer00ne Nov 20 '15 at 20:09

2 Answers2

1

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.

Paulie_D
  • 107,962
  • 13
  • 142
  • 161
  • Using `vh` units make it scroll as well, though the spec. is enough as the right answer as I interpret that wrong when read the MDN before, so drop your sample :), so i can accept this one. – Asons Nov 20 '15 at 16:55
  • `vh` *shouldn't* make it scroll but it seems you are right...odd. – Paulie_D Nov 20 '15 at 16:58
  • `padding-top` of `2vh` on the body works but I think the scroll with margin is the old "1st block with margin" issue. Yep - see http://codepen.io/Paulie-D/pen/jbRMdE – Paulie_D Nov 20 '15 at 17:00
  • I don't see my demo with any scrollbars in Chrome or Firefox, what do I need to do in order to reproduce that behavior? – zer00ne Nov 20 '15 at 17:54
  • @zer00ne Uncomment the `margin-top: 2%;` on the `.outer` and you will see the scroll. – Asons Nov 20 '15 at 18:30
  • Yeah that's the reason I commented out, so it won't scroll, so you need a margin for the `.outer` div? – zer00ne Nov 20 '15 at 18:34
  • @Paulie_D My I suggest an update about the `overflow: auto;` fix to the _1st block with margin_ issue together with using `vh` units. It would be good to have than just as a comment. – Asons Nov 20 '15 at 18:34
  • @zer00ne Yes, well kind of, was the problem, when using `margin-top`, not i.e. using `padding-top` on the parent. – Asons Nov 20 '15 at 18:36
1

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>
zer00ne
  • 41,936
  • 6
  • 41
  • 68