display:flexを使用して、残りの垂直スペースをCSSで埋めます


194

3列レイアウトの場合:

  • 上の行はその内容に応じてサイズを調整する必要があります
  • 下の行はピクセル単位で固定された高さでなければなりません
  • 真ん中の行はコンテナを埋めるために拡大する必要があります

問題は、メインコンテンツが展開すると、ヘッダーとフッターの行が圧縮されることです。

屈曲不良

HTML:

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

CSS:

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; */
}

フィドル:

レガシーブラウザを無視して、CSSの最新かつ最高の機能を使用できるという幸運な状況にいます。flexレイアウトを使用して、最終的に古いテーブルベースのレイアウトを取り除くことができると思いました。どういうわけか、それは私が望むことをしていない...

記録のために、「残りの高さを埋める」に関するSOに関する多くの関連する質問がありますが、私がflexで抱えている問題を解決するものは何もありません。参照:


フィドルで期待どおりに機能しているようです。
Dayan

はい、<div>の残りのコンテンツのコメントを解除して、どのように機能しないかを確認する必要があります。多分私は壊れたバージョンをリンクするべきでした。ごめんなさい。
Zilk、2014

両方のバージョンを質問に追加しました。
Zilk、2014

私はあなたが今何を意味するかを理解しています。
Dayan

回答:


244

シンプルにする: デモ

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>


20
セクションの高さを100%にしたい場合はどうでしょうか?
Paul Totzke、2015

5
@PaulTotzke次に別の質問のように、高さを100%に設定するだけです。HTML、本体、セクション{高さ:100%;}部は、本体の直接の子であり、いつものように、親たちは、コード上は「NULL」例の古典的な100%持っている他、使用可能な高さのセットを/必要jsfiddle.net/を7yLFL / 445これにより、ヘッダーとフッターが修正されます。
G-キリルス

1
@GCyrillusありがとうございます。私は、html、body、およびラッパーがすべて設定されたサイズでなければならないことに気付きませんでした。
Paul Totzke、2016

1
「min-heightには目的があります」をありがとう。固定要素の高さを使用して、なぜそれが機能しないのかと思っていました。
Maciej Krawczyk 2016年

2
Firefoxでこのソリューションに問題がありました。に変更flex: 1して修正しましたflex-grow: 1。解決策をありがとう!
strange_developer 2018年

19

以下の例には、展開された中央コンポーネントのコンテンツがその境界を超えて拡張する場合のスクロール動作が含まれています。また、中央のコンポーネントは、ビューポートの残りのスペースを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>

3
これはhtml、セレクターから削除し、具体的にjsfiddle.net/pm6nqcqh/1height: 100vhbody
Dai

拡張可能な子のflex:autoとflex:1の違いに気付きました。flex:autoを使用すると、他の子は必要に応じて縮小するように見えますが、flex:1を使用すると縮小しません(Chromeの場合)
mvermand

7

より近代的なアプローチは、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>


1
CSSグリッドのサポートはかなり新しいものです。古いブラウザをサポートする必要がない限り、私はそれを使用しません。
adi518

4

flex-growプロパティをメインコンテンツdivに使用し、dispaly: 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>


この問題(に他の解決策がありsection、高さが固定されていない?)というよりも使用してはposition: absolute
ベン・

1
@ben要素の高さがわかっている場合。その後、の使用を回避できますposition: absolute;https://jsfiddle.net/xa26brzf/
Deepu Reghunath
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.