【问题标题】:Force flexbox element not to take all vertical space强制 flexbox 元素不占用所有垂直空间
【发布时间】:2018-01-10 11:57:37
【问题描述】:

TL;DR:带有flex-direction: row 的弹性元素占据所有垂直空间并阻止其子元素中的滚动条。


first fiddle 显示了我想要实现的 UI 类型:它是一个横向和纵向延伸到整个屏幕的页面。它包含一个标题和一个主要的<div>,这是一个可滚动的项目列表。因此容器是一个column flexbox。注意它的宽度和高度都很好。

现在我想在主要内容中添加一个侧边栏,而 flexbox 似乎也很适合这个。我只是在flex-direction: row 中再添加一个<div id='main'>:见second fiddle。侧边栏显示正常,但这是一个问题。新的<div id='main'> 占据了所有垂直空间,因此项目列表永远不会有滚动条。

我试图限制高度<div id='main'>,它似乎有效。但是在代码方面很不方便,因为头部是一个单独的组件,所以一般来说它的高度对于主组件来说是unknown,我在设置height: calc(100vh - ...)之前已经计算过了。

有没有一种纯 CSS 方法来告诉 flexbox 容器 垂直增长?或者我应该回到好的旧表 html 吗?

【问题讨论】:

  • overflow-y: auto; 添加到main 将显示滚动条。这就是你所追求的吗?如果我在这里错过了标记,请道歉。
  • 您的#container 拥有overflow hidden。你的.items 有它应该有的高度(在所有项目中),但#containers overflow hidden 削减了它。这意味着您必须更改 .items 的高度
  • @sconner87 对我不起作用

标签: html css flexbox


【解决方案1】:

我会这样做(css中的cmets关于我改变了什么):

* {
    box-sizing: border-box;
}

body {
  margin: 0;
  padding: 0;
}

#container {
  padding: 10px;
  background: #fefefe;
  display: flex;
  flex-direction: column;
  max-height: 100vh;
  overflow: hidden;
  /*remove flex grow and shrink - as parent is not flex, these have no effect*/
}

#header {
  padding: 10px;
  background: #e1eaec;
}

#items {
  flex-grow: 1;     /* change the width and height for flex grow */
  background: #eee;
  padding: 10px;
  overflow: auto;
}

.item {
  background: lightyellow;
  padding: 20px;
}

/* New */

#main {
  display: flex;
  flex-direction: row;
  flex-grow: 1;            /* remove flex-shrink and set grow to 1 */
  /* height: 300px; */
}

#sidebar {
  flex-basis: 20%;
  padding: 10px;
}
<div id='container'>
  <div id='header'>
    <h1>Header</h1>
  </div>
  <div id='main'>
    <div id='items'>
      <div class='item'>Lorem Ipsum</div>
      <div class='item'>Lorem Ipsum</div>
      <div class='item'>Lorem Ipsum</div>
      <div class='item'>Lorem Ipsum</div>
      <div class='item'>Lorem Ipsum</div>
      <div class='item'>Lorem Ipsum</div>
      <div class='item'>Lorem Ipsum</div>
      <div class='item'>Lorem Ipsum</div>
      <div class='item'>Lorem Ipsum</div>
      <div class='item'>Lorem Ipsum</div>
      <div class='item'>Lorem Ipsum</div>
      <div class='item'>Lorem Ipsum</div>
    </div>
    <div id='sidebar'>
      Sidebar
    </div>
  </div>
</div>

【讨论】:

  • 完美!我觉得我尝试了这个变体,但是#items 从其中一个课程中得到了height:100%,我没有注意它。您的解决方案让我思考:原来关键规则是height: initial; 谢谢!
【解决方案2】:

如果您想拥有具有完整可用高度、固定标题和可滚动内容的侧边栏,您可以使用下面的代码。

body {
    margin: 0;
}

section {
  display: flex;
  flex-direction: column;
  height: 100vh;
}

header {
  flex: 0 0 auto;
  background: red;
  font-size: 2em;
  padding: .5em;
}

main {
  display: flex;
  flex: 1 1 auto;
}

content {
  flex: 1 1 auto;
  overflow-y: scroll;
}

aside {
  flex: 0 0 auto;
  padding: 20px;
  background: green;
}

div {
  border: 1px solid red;
  padding: 1em;
}
<section>
  <header>header</header>
  <main>
    <content>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
      <div>div</div>
    </content>
    <aside>sidebar</aside>
  </main>  
</section>

【讨论】: