Three-row 模态与 header、底行和可滚动的中间行固定

Three-row modal with fixed with header, bottom row, and scrollable middle row

我正在尝试创建一个具有顶部、中间和底部的模式。顶部始终固定高度。

底部必须 "glued" 到底部并且可能会有所不同。其中的所有内容和元素都必须从底部构建。因此,如果只有一行文本,底部将是该行的高度。如果有3行或4行文字,底部会根据需要向上推。

中间需要全部填满,如果内容overflow-y必须显示滚动条且不干扰顶部或最后一行。

我该怎么做?我发现当我尝试 overflow-y: auto 时它不起作用,大概是因为没有高度,而是它将 table 推到 #wrap div 的范围之外。

这是一个 CodePen:https://codepen.io/sfullman/pen/XGZoJb

    body{
      font-family: Arial;
    }
    .table{
      display: table;
      height: 100%;
      width: 100%;
    }
    .row{
      display: table-row;
    }
    .cell{
      display: table-cell;
      width: 75%;
    }
    #top{
      background-color: burlywood;
      height: 41px;
    }
    #middle .cell{
      overflow-y: scroll;
    }
    #bottom{
      height: 15px; /* make this height less than expected height, table row/cell behavior will successfully exceed it an push content up */
      border-top: 1px solid darkred;
      background-color: rgba(0,0,0,.15);
    }
    #wrap{
      /* this div is designed to be a dialog/modal and will normally be abs. positioned */
      border: 1px solid darkred;
      width: 425px;
      height: 300px;
      position: absolute;
      top: 20px;
      left: 20px;
    }
    <div id="wrap">
      <div id="innerTable" class="table">
      <div id="top" class="row">
        <div class="cell">
        top
        </div>
      </div>
      <div id="middle" class="row">
        <div class="cell">
          middle<br>
          middle<br>
          middle<br>
          middle<br>
          middle<br>
          middle<br>
          middle<br>
          middle<br>
          middle<br>
          middle<br>
          middle<br>
          middle<br>
        </div>
      </div>
      <div id="bottom" class="row">
        <div class="cell">
        bottom<br>
        bottom<br>
        bottom<br>
        </div>
      </div>
    </div>
    </div>

我已经使用 flexbox 创建了一个示例:https://codepen.io/jgoncalves/pen/XGEqoj

.container {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
}

.main {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.content {
  flex: 1;
  display: flex;
  overflow: auto;
}

body {
  font-family: sans-serif;
  font-size: 20px;
  line-height: 50px;
  text-transform: uppercase;
  font-weight: bold;
}

.header {
  text-align: center;
  color: #fff;
  background: #444;
}

.footer {
  padding: 6px 20px;
  background: #004141;
  color: #fff;
}

.content {
  background: #ddd;
}
<div class="container">
 <div class="main">
      <div class="header">Main header Main headerMain headerMain headerMain headerMain headerMain headerMain header</div>
  <div class="content">
     Scroll me Scroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll meScroll me
  </div>
    <div class="footer">Footer end of page. Footer end of page. Footer end of page. Footer end of page. Footer end of page. Footer end of page. Footer end of page. Footer end of page. </div>
 </div>
</div>

中心行滚动,同时具有不同高度的固定页眉和固定页脚。

想法是使用 column flexboxmax-height 设置来填充其所在的容器 - 请参见下面的演示以了解全视口设置(这是基于 ):

body {
  margin: 0;
}
*{
  box-sizing: border-box;
}
.row {
  display: flex;
  flex-direction: column;
  max-height: 100vh;
}
.flex {
  flex: 1;
  overflow-y: auto;
}
.row, .row > * {
  border: 1px solid;
}
<div class="row">
  <div>some content</div>
  <div class="flex">This fills the available space</div>
  <!-- fills/grows available space -->
  <div>another content</div>
</div>

请注意,headerfooter 的高度可以在此处 动态变化 - 即使您没有固定高度,这也有效.对于更复杂的布局,但是较新的 CSS Grid layouts are preferred as flexboxes are 1D layouts while CSS Grid is a 2D layouting solution - see one example here


解决方案

现在我将根据您的代码进行调整 - 看看当 middle 部分中有很多内容时它是如何工作的:

body {
  font-family: Arial;
}

.table {
  display: flex;
  flex-direction: column;
  max-height: 100%;
  width: 100%;
}

.cell {
  width: 75%;
}

#top {
  background-color: burlywood;
}

#middle {
  flex: 1;
  overflow-y: auto;
}

#bottom {
  border-top: 1px solid darkred;
  background-color: rgba(0, 0, 0, .15);
}

#wrap {
  border: 1px solid darkred;
  width: 425px;
  height: 300px;
  position: absolute;
  top: 20px;
  left: 20px;
}
<div id="wrap">
  <div id="innerTable" class="table">
    <div id="top" class="row">
      <div class="cell">
        top
      </div>
    </div>
    <div id="middle" class="row">
      <div class="cell">
        middle<br> middle
        <br> middle
        <br> middle
        <br> middle
        <br> middle
        <br> middle
        <br> middle
        <br> middle
        <br> middle
        <br> middle
        <br> middle
        <br> middle
        <br> middle
        <br> middle
        <br> middle
        <br> middle
        <br> middle
        <br> middle
        <br> middle
      </div>
    </div>
    <div id="bottom" class="row">
      <div class="cell">
        bottom
      </div>
    </div>
  </div>
</div>

现在看看当 middle 部分的内容非常少时它是如何工作的——注意 footer 部分是如何 到底部的:

body {
  font-family: Arial;
}

.table {
  display: flex;
  flex-direction: column;
  max-height: 100%;
  width: 100%;
}

.cell {
  width: 75%;
}

#top {
  background-color: burlywood;
}

#middle {
  flex: 1;
  overflow-y: auto;
}

#bottom {
  border-top: 1px solid darkred;
  background-color: rgba(0, 0, 0, .15);
}

#wrap {
  border: 1px solid darkred;
  width: 425px;
  height: 300px;
  position: absolute;
  top: 20px;
  left: 20px;
}
<div id="wrap">
  <div id="innerTable" class="table">
    <div id="top" class="row">
      <div class="cell">
        top
      </div>
    </div>
    <div id="middle" class="row">
      <div class="cell">
        middle<br> middle
        <br> middle
        <br> middle
        <br> middle

        <br> middle
        <br> middle
        <br> middle
        <br> middle
        <br> middle
        <br> middle
      </div>
    </div>
    <div id="bottom" class="row">
      <div class="cell">
        bottom
      </div>
    </div>
  </div>
</div>

在网上搜索后,我在 JS fiddle 上找到了一些东西,然后我修改它来创建解决方案 here

这里是 HTML:

<div id="body">
     <div id="head">
       <!-- if your have content larger than declared height here, it will simply roll under the bottom with no scrolling -->
        <p>Fixed size without scrollbar 1</p>
        <p>Fixed size without scrollbar 2</p>
        <p>Fixed size without scrollbar 3</p>
        <p>Fixed size without scrollbar 4</p>
    </div> 
    <div id="content">
        <!--
        add or remove these to see scrool/non-scroll behavior
        -->
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <!--
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        -->
    </div>
    <div id="foot">
      <!-- this content will build from the bottom, pushing the top wall up. #content's bottom will adjust up accordingly -->
        <p>Dynamic size without scrollbar 1</p>
        <p>Dynamic size without scrollbar 2</p>
        <p>Dynamic size without scrollbar 3</p>
    </div> 
</div>

和 CSS:

#body {
    position: absolute;
    top: 15px;
    left: 15px;
    height: 300px;
    width: 500px;
    outline: black dashed 1px;
    display: flex;
    flex-direction: column;
}

#head {
    /*border: blue solid 1px;*/
    background-color: rgba(0,0,255,0.25);
    height: 50px;
    flex-shrink: 0;
}
#content{
    /*border: red solid 1px;*/
    background-color: palegoldenrod;
    overflow-y: auto;
    height: 100%;
}

#foot {
    /*border: green solid 1px;*/
    background-color: whitesmoke;
    flex-shrink: 0;
}