コンテンツがオーバーフローしているフレックスボックスをスクロールする


214

ここに画像の説明を入力してください

上記のレイアウトを実現するために使用しているコードは次のとおりです。

.header {
  height: 50px;
}

.body {
  position: absolute;
  top: 50px;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
}

.sidebar {
  width: 140px;
}

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

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

.column {
  padding: 20px;
  border-right: 1px solid #999;
}
<div class="header">Main header</div>
<div class="body">
  <div class="sidebar">Sidebar</div>

  <div class="main">
    <div class="page-header">Page Header. Content columns are below.</div>
    <div class="content">
      <div class="column">Column 1</div>
      <div class="column">Column 1</div>
      <div class="column">Column 1</div>
    </div>
  </div>
</div>

スタイリングに使用するコードは省略しました。あなたはそれをすべてペンで見ることができます。


上記は機能しますが、content領域のコンテンツがオーバーフローすると、ページ全体がスクロールします。コンテンツ領域自体をスクロールするだけなのでdiv に追加overflow: autoしましたcontent

これの問題は、列自体が親の高さを超えて拡張されないため、境界もそこで切り取られていることです。

これがスクロールの問題を示すペンです。

content子がcontentボックスの高さを超えている間に、領域を個別にスクロールするように設定するにはどうすればよいですか?

回答:


263

私はこれについてTab Atkins(フレックスボックス仕様の作者)に話しました、そしてこれは私たちが思いついたものです:

HTML:

<div class="content">
    <div class="box">
        <div class="column">Column 1</div>
        <div class="column">Column 2</div>
        <div class="column">Column 3</div>
    </div>
</div>

CSS:

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

.box {
    display: flex;
    min-height: min-content; /* needs vendor prefixes */
}

ここにペンがあります:

  1. 伸びる短い柱
  2. 長い列はオーバーフローしてスクロールします。

これが機能する理由align-items: stretchは、アイテムが固有の高さを持っている場合、はアイテムを縮小しないためmin-contentです。


3
これらは、親の高さがその子に一般的に依存しない場合に機能します。min-height:100%は、Firefoxのストレッチ(偶数列の場合は短い)の問題を実際に修正します(ただし、Chromeではできません)。それがChromeのバグなのかFirefoxのバグなのかはわかりません。
dholbert 2014

1
@dholbert-Tab Atkinsがこれを手伝ってくれました。回答を更新しました。
ジョセフシルバー

3
Firefoxは現在、高さの値ではなく、幅の値の「min-content」のみをサポートしていることに注意してください。したがって、これは、Firefoxでは機能しません。(例:bugzilla.mozilla.org/show_bug.cgi
id

2
@dholbert-これらのペンの問題は、それらが公開されていたため、だれでも変更できることです。私はそれらの所有権を取得したので、ここに行きます:codepen.io/JosephSilber/pen/pmyHh
Joseph Silber

5
はい、これはIE11で壊れています
Steve

119

多くの試行錯誤の末、私はこの問題を非常にエレガントに解決しました。

私のブログ投稿をチェックしてくださいhttp : //geon.github.io/programming/2016/02/24/flexbox-full-page-web-app-layout

基本的に、フレックスボックスセルをスクロール可能にするには、そのすべての を作成する必要があります。そうしないとoverflow: hidden;、オーバーフロー設定が無視され、代わりに親が大きくなります。


11
これは私の場合にも機能しましたが、すごい、なぜ機能するについての説明を見たいです。ほとんどの場合、私はCSSの仕様がこの種のことについて完全に不可解であると思います。
markrian、2016年

2
あなたのブログ投稿から:「なぜそれが機能するのか私にはわかりません、そして仕様も何も言っていません」。だから、私はそれが機能する理由の説明を探しています。スペックをざっと読みましたが、あなたが言ったように、そこには何も飛びつきません。
markrian、

3
もう少し考えてみれば、理にかなっていると思います。デフォルトの動作では、各divが展開されてそのすべての子が含まれるため、リーフノードで非表示にするオーバーフローはありません。あなたはオーバーフローを強制する必要があります:DOMの上からずっと隠されているので、オーバーフローしてスクロールしたいノードに到達するまで、親は子に対応する機会がありません。
geon '11

3
それが本当にそれを説明しているのかわかりません。要素のオーバーフローを非表示に設定しても、要素のすべての子を含むように拡張することは停止しません、AFAIK。MDNによれば、「overflowプロパティは、コンテンツをクリップするか、スクロールバーをレンダリングするか、またはブロックレベルのコンテナーからオーバーフローしたときにコンテンツを表示するかを指定します。」また、目に見える以外にオーバーフローを設定すると、コンテキストをフォーマットする新しいブロックを作成します-しかし、フレックスコンテナはすでに自分のブロックの書式コンテキストを作成するので、それは、関連することはできません。developer.mozilla.org/en-US/docs/Web/Guideを/ CSS /…
markrian

1
私はあなたの説明が直感的に理解できることに同意することを付け加えておきますが、それは私が望むものである正確な技術的な説明ではないと思います。その理由を真に理解して初めて、解決策を思い出すことができます!
markrian

55

作業position:absolute;と一緒にflex

でフレックスアイテムを配置しposition: relativeます。次に、その中に別の<div>要素を追加します。

position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;

これは、要素をその相対位置の親の境界まで拡張しますが、拡張することはできません。内部でoverflow: auto;は、期待どおりに動作します。

  • 回答に含まれているコードスニペット-をクリックし、スニペットの実行ここに画像の説明を入力してください後にクリックしますOR全ページ
  • クリックしてここにするためにCODEPEN
  • 結果: ここに画像の説明を入力してください

.all-0 {
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}
p {
  text-align: justify;
}
.bottom-0 {
  bottom: 0;
}
.overflow-auto {
  overflow: auto;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" rel="stylesheet"/>


<div class="p-5 w-100">
  <div class="row bg-dark m-0">
    <div class="col-sm-9 p-0 d-flex flex-wrap">
      <!-- LEFT-SIDE - ROW-1 -->
      <div class="row m-0 p-0">
        <!-- CARD 1 -->
        <div class="col-md-8 p-0 d-flex">
          <div class="my-card-content bg-white p-2 m-2 d-flex flex-column">
            <img class="img img-fluid" src="https://via.placeholder.com/700x250">
            <h4>Heading 1</h4>
            <p>
              Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old...
          </div>
        </div>
        <!-- CARD 2 -->
        <div class="col-md-4 p-0 d-flex">
          <div class="my-card-content bg-white p-2 m-2 d-flex flex-column">
            <img class="img img-fluid" src="https://via.placeholder.com/400x250">
            <h4>Heading 1</h4>
            <p>
              Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old...
          </div>
        </div>
      </div>
      <div class="row m-0">
        <!-- CARD 3 -->
        <div class="col-md-4 p-0 d-flex">
          <div class="my-card-content bg-white p-2 m-2 d-flex flex-column">
            <img class="img img-fluid" src="https://via.placeholder.com/400x250">
            <h4>Heading 1</h4>
            <p>
              Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old...
          </div>
        </div>
        <!-- CARD 4 -->
        <div class="col-md-4 p-0 d-flex">
          <div class="my-card-content bg-white p-2 m-2 d-flex flex-column">
            <img class="img img-fluid" src="https://via.placeholder.com/400x250">
            <h4>Heading 1</h4>
            <p>
              Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old...
          </div>
        </div>
        <!-- CARD 5-->
        <div class="col-md-4 p-0 d-flex">
          <div class="my-card-content bg-white p-2 m-2 d-flex flex-column">
            <img class="img img-fluid" src="https://via.placeholder.com/400x250">
            <h4>Heading 1</h4>
            <p>
              Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old...
          </div>
        </div>
      </div>
    </div>
    <div class="col-sm-3 p-0">
      <div class="bg-white m-2 p-2 position-absolute all-0 d-flex flex-column">
        <h4>Social Sidebar...</h4>
        <hr />
        <div class="d-flex overflow-auto">
          <p>
            Topping candy tiramisu soufflé fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halva fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart.
            opping candy tiramisu soufflé fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halva fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart.
            opping candy tiramisu soufflé fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halva fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart.
            Pudding cupcake danish apple pie apple pie. Halvafruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halvafruitcake ice cream chocolate bar. Bear claw ice cream
            chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halvafruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halvafruitcake ice cream chocolate
            bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halva
        </div>
      </div>
    </div>
  </div>

幸運を...


2
このソリューションは、内部のコンポーネントにパディングが設定されている場合に特に役立ちます。これは、必要な場所に適切にロックされるためです。それははるかに簡単です。(はい、box-sizing: border-box代わりに設定することもできますが、特定のサードパーティコントロールではさらに複雑になる場合があります)。
Simon_Weaver

2
あなたは私の夜を救った!
Botea Florin

2
ありがとうございました。どういうわけかこれが必要だとは残念ですが、アドバイスに感謝します!
Mathias

9

少し遅れますが、これは役立つ可能性があります:http : //webdesign.tutsplus.com/tutorials/how-to-make-sensitive-scrollable-panels-with-flexbox--cms-23269

基本的には、配置する必要がありhtmlbodyheight: 100%; し、Aにすべてのコンテンツをラップ<div class="wrap"> <!-- content --> </div>

CSS:

html, body {
  height: 100%;
}

.wrap {
  height: 100vh;
  display: flex;
}

私のために働いた。それが役に立てば幸い


「高さ:100vh」はiOS SafariとAndroidで測定が異なるため、使用するときは十分注意してください。1つはURLバーの高さを考慮し、もう1つは考慮しません。
Sean Anderson

7

これを追加:

align-items: flex-start;

のルールに.content {}。これで、少なくとも私にとってはペンでそれが修正されます(FirefoxとChromeの両方で)。

デフォルトで.contentは、hasですalign-items: stretch。これにより、http://dev.w3.org/csswg/css-flexbox/#algo-stretchに従って、すべての自動高さの子のサイズが独自の高さに一致するようになります。対照的に、この値をflex-start使用すると、子は自分の高さを計算し、開始エッジに揃えることができます(オーバーフローして、スクロールバーをトリガーします)。



また、フレックスボックスの主な魅力の1つである、列の高さが同じではなくなります。
ジョセフシルバー、2014

OK。それが設計上の制約であるかどうかははっきりしませんでした-すみません。
dholbert 2014

素晴らしい提案
ヴラド

1

私が遭遇した1つの問題は、スクロールバーを使用するには、要素を(%ではなく)高さを指定する必要があるということです。

トリックは、各列内にdivの別のセットをネストし、列の親の表示をflex-direction:columnでflexに設定することです。

    html, body {
        height: 100%;
        margin: 0;
        padding: 0;
    }

    body {
        overflow-y: hidden;
        overflow-x: hidden;
        color: white;
    }

    .base-container {
        display: flex;
        flex: 1;
        flex-direction: column;
        width: 100%;
        height: 100%;
        overflow-y: hidden;
        align-items: stretch;
    }

    .title {
        flex: 0 0 50px;
        color: black;
    }

    .container {
        flex: 1 1 auto;
        display: flex;
        flex-direction: column;
    }

        .container .header {
            flex: 0 0 50px;
            background-color: red;
        }

        .container .body {
            flex: 1 1 auto;
            display: flex;
            flex-direction: row;
        }

            .container .body .left {
                display: flex;
                flex-direction: column;
                flex: 0 0 80px;
                background-color: blue;
            }
                .container .body .left .content,
                .container .body .main .content,
                .container .body .right .content {
                    flex: 1 1 auto;
                    overflow-y: auto;
                    height: 100px;
                }
                .container .body .main .content.noscrollbar {
                    overflow-y: hidden;
                }

            .container .body .main {
                display: flex;
                flex-direction: column;
                flex: 1 1 auto;
                background-color: green;
            }

            .container .body .right {
                display: flex;
                flex-direction: column;
                flex: 0 0 300px;
                background-color: yellow;
                color: black;
            }

    .test {
        margin: 5px 5px;
        border: 1px solid white;
        height: calc(100% - 10px);
    }
</style>

そして、これがhtmlです:

<div class="base-container">
    <div class="title">
        Title
    </div>
    <div class="container">
        <div class="header">
            Header
        </div>
        <div class="body">
            <div class="left">
                <div class="content">
                    <ul>
                        <li>1</li>
                        <li>2</li>
                        <li>3</li>
                        <li>4</li>
                        <li>5</li>
                        <li>6</li>
                        <li>7</li>
                        <li>8</li>
                        <li>9</li>
                        <li>10</li>
                        <li>12</li>
                        <li>13</li>
                        <li>14</li>
                        <li>15</li>
                        <li>16</li>
                        <li>17</li>
                        <li>18</li>
                        <li>19</li>
                        <li>20</li>
                        <li>21</li>
                        <li>22</li>
                        <li>23</li>
                        <li>24</li>
                    </ul>
                </div>
            </div>
            <div class="main">
                <div class="content noscrollbar">
                    <div class="test">Test</div>
                </div>
            </div>
            <div class="right">
                <div class="content">
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>End</div>
                </div>
            </div>
        </div>
    </div>
</div>

https://jsfiddle.net/LiamFlavelle/czpjdfr4/


0

この問題の解決策はoverflow: auto;、コンテンツラッパーをスクロール可能にするために.content に追加することです。

さらに、overflowedこのコードペンのようなFlexboxラッパーとスクロール可能なコンテンツと共に発生する状況があります

解決策は、overflow: hidden (or auto);大きなコンテンツを囲むラッパー(overflow:auto;で設定)の親に追加することです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.