在三行布局中:

顶部行应该根据其内容调整大小 底部一行应该有一个固定的像素高度 中间的行应该扩展以填满容器

问题是,当主要内容展开时,它会压缩页眉和页脚行:

section { display: flex; flex-flow: column; align-items: stretch; height: 300px; } header { flex: 0 1 auto; background: tomato; } div { flex: 1 1 auto; background: gold; overflow: auto; } footer { flex: 0 1 60px; background: lightgreen; /* fixes the footer: min-height: 60px; */ } <section> <header> header: sized to content <br>(but is it really?) </header> <div> main content: fills remaining space<br> x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> <!-- uncomment to see it break - -> x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> <!-- --> </div> <footer> footer: fixed height in px </footer> </section>

小提琴:

http://jsfiddle.net/7yLFL/1/(工作,内容不多) http://jsfiddle.net/7yLFL/(破碎,内容较大)

我很幸运,我可以使用最新最好的CSS,而不用考虑传统浏览器。我认为我可以使用flex布局,最终摆脱旧的基于表格的布局。出于某种原因,它没有做我想要的……

为了记录,在SO上有许多关于“填充剩余高度”的相关问题,但没有任何问题可以解决我使用flex时遇到的问题。参考文献:

用一个div填充剩余屏幕空间的高度 填充剩余的垂直空间-只有CSS 当与另一个div共享时,有一个div来填充容器的剩余高度/宽度? 使嵌套div伸展到剩余容器div高度的100% 如何使我的flexbox布局占100%垂直空间? 等


简单点:演示

section { display: flex; flex-flow: column; height: 300px; } header { background: tomato; /* no flex rules, it will grow */ } div { flex: 1; /* 1 and it will fill whole space left if no flex value are set to other children*/ background: gold; overflow: auto; } footer { background: lightgreen; min-height: 60px; /* min-height has its purpose :) , unless you meant height*/ } <section> <header> header: sized to content <br/>(but is it really?) </header> <div> main content: fills remaining space<br> x <br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> <!-- uncomment to see it break --> x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> x <br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> x <br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> x <br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> <!-- --> </div> <footer> footer: fixed height in px </footer> </section>

全屏版本

section { display: flex; flex-flow: column; height: 100vh; } header { background: tomato; /* no flex rules, it will grow */ } div { flex: 1; /* 1 and it will fill whole space left if no flex value are set to other children*/ background: gold; overflow: auto; } footer { background: lightgreen; min-height: 60px; /* min-height has its purpose :) , unless you meant height*/ } body { margin: 0; } <section> <header> header: sized to content <br/>(but is it really?) </header> <div> main content: fills remaining space<br> x <br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> <!-- uncomment to see it break --> x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> x <br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> x <br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> x <br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> <!-- --> </div> <footer> footer: fixed height in px </footer> </section>


下面的例子包含了如果展开的中心组件的内容超出了它的边界时的滚动行为。此外,中心组件占用视口中100%的剩余空间。

关于这个课题jsfiddle

html, body, .r_flex_container{
    height: 100%;
    display: flex;
    flex-direction: column;
    background: red;
    margin: 0;
}
.r_flex_container {
    display:flex;
    flex-flow: column nowrap;
    background-color:blue;
}

.r_flex_fixed_child {
    flex:none;
    background-color:black;
    color:white;

}
.r_flex_expand_child {
    flex:auto;
    background-color:yellow;
    overflow-y:scroll;
}

可以用来演示此行为的html示例

<html>
<body>
    <div class="r_flex_container">
      <div class="r_flex_fixed_child">
        <p> This is the fixed 'header' child of the flex container </p>
      </div>
      <div class="r_flex_expand_child">
            <article>this child container expands to use all of the space given to it -  but could be shared with other expanding childs in which case they would get equal space after the fixed container space is allocated. 
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc,
            </article>
      </div>
      <div class="r_flex_fixed_child">
        this is the fixed footer child of the flex container
        asdfadsf
        <p> another line</p>
      </div>

    </div>
</body>
</html>

更现代的方法是使用grid属性。

section { display: grid; align-items: stretch; height: 300px; grid-template-rows: min-content auto 60px; } header { background: tomato; } div { background: gold; overflow: auto; } footer { background: lightgreen; } <section> <header> header: sized to content <br>(but is it really?) </header> <div> main content: fills remaining space<br> x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> </div> <footer> footer: fixed height in px </footer> </section>


对主要内容div使用flex-grow属性,并给出如下显示:flex;到它的父;

body { height: 100%; position: absolute; margin: 0; } section { height: 100%; display: flex; flex-direction : column; } header { background: tomato; } div { flex: 1; /* or flex-grow: 1 */; overflow-x: auto; background: gold; } footer { background: lightgreen; min-height: 60px; } <section> <header> header: sized to content <br>(but is it really?) </header> <div> main content: fills remaining space<br> x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> </div> <footer> footer: fixed height in px </footer> </section>


下面是演示解决方案的代码:

演示-使用display:flex用CSS填充剩余的垂直空间

重要的亮点:

all containers from html, body, ... .container, should have the height set to 100% introducing flex to ANY of the flex items will trigger calculation of the items sizes based on flex distribution: if only one cell is set to flex, for example: flex: 1 then this flex item will occupy the remaining of the space if there are more than one with the flex property, the calculation will be more complicated. For example, if the item 1 is set to flex: 1 and the item 2 is se to flex: 2 then the item 2 will take twice more of the remaining space NOT TRUE: the item 2 will be twice larger than the item 1 check more about the concept of the remaining space: https://developer.mozilla.org/en-US/docs/Web/CSS/flex-grow Main Size Property depends on the value of the flex-direction property in our case height is just a preferred size it will be overwritten in the presence of flex property: https://www.w3.org/TR/css-flexbox-1/#propdef-flex When a box is a flex item, flex is consulted instead of the main size property to determine the main size of the box min-* and max-* will be respected


这是我能想到的最简单的例子。关键是

父级为display:flex 儿童有弹性生长:1 父节点必须指定高度。如果你在父div上指定了height:100%,那么记住,父div存在于<body>中,你会看到body不是100%,除非你在body上也添加了height:100%。

http://jsfiddle.net/Ljbzsmvf/2/

div#父{ 身高:300 px; 显示:flex; flex-direction:列; } div#孩子{ 边框:细实红色; flex-grow: 1; } < div id =“父”> 父 < div id =“孩子”> 孩子 < / div > < / div >