伸缩柱包装和伸缩基础100%的额外空间

时间:2019-10-07 16:41:09

标签: css flexbox

在下面的示例中,在桌面视图上,我要删除的.main-content元素底部有多余的空间。我觉得它与height: 100%flex-basis有关,但不确定。 flex-shrink不起作用,即使这样做也可能会干扰布局。

有人可以解释一下浏览器如何解释这种布局并创建额外的空间。

html,
body {
  height: 100%;
}

body {
  display: flex;
  flex-direction: column;
  margin: 0;
}

main {
  flex-grow: 1;
}

.container {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  height: 100%;
}

header,
footer,
[class^="sidebar-"],
.main-content {
  box-sizing: border-box;
  padding: 1rem;
}

header,
footer {
  background-color: lightgreen;
}

.sidebar-nav {
  background-color: lightblue;
}

.sidebar-content {
  background-color: lightyellow;
}

.sidebar-right {
  background-color: lightpink;
}

.main-content {
  background-color: lightgray;
}

@media( min-width: 48em) {
  .sidebar-nav,
  .sidebar-content {
    width: 26%;
    margin-right: 8%;
  }
  .main-content,
  .sidebar-right {
    flex-basis: 100%;
  }
  .main-content {
    width: 66%;
  }
  .sidebar-right {
    margin-left: 2rem;
    width: 20%;
  }
  .sidebar-right+.main-content {
    width: calc( 66% - ( 20% + 2rem));
  }
}


/* Ordering of Page Layout */

.sidebar-nav {
  order: 1;
}

.main-content {
  order: 2;
}

.sidebar-content {
  order: 3;
}

.sidebar-right {
  order: 4;
}

@media( min-width: 48em) {
  .sidebar-content {
    order: 2;
  }
  .main-content {
    order: 3;
  }
}
<header>
  Header
</header>

<main>
  <div class="container">

    <div class="sidebar-nav">
      Sidebar Navigation
    </div>
    <div class="sidebar-content">
      Sidebar Content
    </div>
    <div class="sidebar-right">
      Right Sidebar
    </div>
    <div class="main-content">
      Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br>      Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br>      Main Content<br> Main Content<br> Main Content
    </div>

  </div>
</main>

<footer>
  Footer
</footer>

1 个答案:

答案 0 :(得分:1)

解决方案

min-height: 0overflow: auto中添加main.main-content(它们基本相同)。

main {
  flex-grow: 1;
  min-height: 0; /* new */
}

.main-content {
  order: 2;
  overflow: auto;  /* new */
}

在Chrome,Firefox和Edge上进行了测试。

body {
  display: flex;
  flex-direction: column;
  height: 100vh;
  margin: 0;
}

main {
  flex-grow: 1;
  min-height: 0; /* new */
}

.container {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  height: 100%;
}

header,
footer,
[class^="sidebar-"],
.main-content {
  box-sizing: border-box;
  padding: 1rem;
}

header,
footer {
  background-color: lightgreen;
}

.sidebar-nav {
  background-color: lightblue;
}

.sidebar-content {
  background-color: lightyellow;
}

.sidebar-right {
  background-color: lightpink;
}

.main-content {
  background-color: lightgray;
}

@media(min-width: 48em) {
  .sidebar-nav,
  .sidebar-content {
    width: 26%;
    margin-right: 8%;
  }
  .main-content,
  .sidebar-right {
    flex-basis: 100%;
  }
  .main-content {
    width: 66%;
  }
  .sidebar-right {
    margin-left: 2rem;
    width: 20%;
  }
  .sidebar-right+.main-content {
    width: calc(66% - (20% + 2rem));
  }
}


/* Ordering of Page Layout */

.sidebar-nav {
  order: 1;
}

.main-content {
  order: 2;
  overflow: auto;   /* new */
}

.sidebar-content {
  order: 3;
}

.sidebar-right {
  order: 4;
}

@media(min-width: 48em) {
  .sidebar-content {
    order: 2;
  }
  .main-content {
    order: 3;
  }
}
<header>
  Header
</header>
<main>
  <div class="container">
    <div class="sidebar-nav">
      Sidebar Navigation
    </div>
    <div class="sidebar-content">
      Sidebar Content
    </div>
    <div class="sidebar-right">
      Right Sidebar
    </div>
    <div class="main-content">
      Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br>      Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br> Main Content<br>      Main Content<br> Main Content<br> Main Content
    </div>
  </div>
</main>
<footer>
  Footer
</footer>

jsFiddle demo


问题1:Flex最小尺寸算法

弹性项目不能小于其内容沿主轴的大小。 flex-direction: column中的弹性项目的默认设置为min-height: auto。您可以使用min-height: 0覆盖,也可以使用overflow: auto覆盖滚动条。

此处有完整说明:Why don't flex items shrink past content size?


问题2:不可靠地使用百分比高度

Per the spec,要使百分比高度正常工作,必须必须在父级上定义一个高度。例如,您的.container元素具有以下CSS:

.container {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  height: 100%;
}

但是,.container的父级main没有定义的高度。

main {
  flex-grow: 1;
}

这导致跨浏览器的不一致和不可靠的行为。

浏览器应根据规范在父级上未定义高度的情况下,使用默认设置height: auto渲染元素。

但是,实际上,不同的浏览器具有不同的渲染行为。有些人坚持规范。其他人则试图猜测作者的意图(称为intervention)。

此外,如今,某些浏览器也接受家长的弹性长度作为高度百分比孩子的适当参考。但是,这是不一致且不可靠的。

处理此设置的最佳方法是确保在父级上设置高度,以使具有百分比高度的子级具有清晰的参考点。并且还要确保使用height属性,因为flex-basis在某些浏览器/情况下并不总是可靠的。

此处有完整说明:Chrome / Safari not filling 100% height of flex parent