如何使 flex 容器不强制滚动 body

How to make flex container not force scroll on body

在我做的代码示例中:

现在这让我在 body 上滚动,即使 flex 容器高度 + margin-top 总和只有 98%,所以我的问题是,我不能使用 margin-top 是这样吗?额外的 space 是从哪里强制 body 滚动的?

将 body 设置为 overflow:hidden 会删除滚动条,但这感觉更像是 band-aid 而不是解决方案(除非这是 "behavior-by design"在这种情况下需要它)。

编辑

例如删除 flex 容器上的 margin-top 然后在 body 上设置 padding-top: 2%; 或在容器上使用 position: relative; top: 2%;absolute: position; 虽然我可以让它按预期工作,但这里的情况是 margin-top: 2% 不这样做的原因。

* {
  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>

这是因为百分比边距是基于包含块/元素的 宽度...在本例中,是正文。

W3C Spec

MDN

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

我通常在html和body上使用vhvw。在此演示中,我应用 vh 只是因为它看起来像一个垂直方向的演示。我还制作了 body 和 html position: relative。使用 vwvh 有一个真实的测量长度,其他元素([​​=57=] of ::root)实际上可以将它们的相对测量值设置为 100%。我使用 position: relative 是因为它使 html、body 固定在视口内,而 viewport 单元保持 body、html 开启100vh 和 100vw 的边缘。

更新

我认为这种行为是由于 collapsing-margins 所以如果有不合逻辑的 margin-top 行为,请记住这一点。有几种非常特殊的情况会导致这种奇怪的行为,也有一些解决方案。这些情况的解决方法如下:

  1. body, html { 身高: 100vh; } /* 没有相对或绝对定位 */
  2. .outer { min-height: 100%; margin-top:-2%; } /* 解释说正数 margin-top 无效,但负值有效但不像正常的负值!? 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>