背景
flex の要素にスクロールバーを追加するため、overflow-y: scroll
を追加すると、スクロールバーは表示されるがスクロールしてくれない。
height
を指定すれば解決するが、flex 要素なのでやりたくない。
理想
現実
結論
スクロールバーを追加したい要素の親要素を overflow: hidden
としなければならない。
ソースコード
<div class="col" style="width: 320px; height: 240px;">
<div class="flex">
foo
</div>
<div class="flex row" style="overflow-y: hidden;">
<div class="flex scroll">
<div id="loongitem"></div>
</div>
<div class="flex">
bar
</div>
</div>
</div>
body{
font-family: monospace;
}
div{
margin: 1px;
padding: 1px;
border: 1px solid red;
}
.col{
display: flex;
flex-direction: column;
}
.scroll {
overflow-y: scroll;
}
.row{
display: flex;
flex-direction: row;
}
.flex{
flex: 1 1 auto;
}
# loongitem{
width: 40px;
height: 800px;
background-color: #7cf;
}
コメント
何が起きているのか、推測してみました。
デフォルトのvisibleの場合。
-
overflow:scroll
の付いた flex 子要素に、縦に長い要素をレイアウトする - flex 親要素は、
overflow:visible
なので、子要素を全て描画する - flex 親要素には高さ指定がされていないので、flex の計算値を無視して(?)子要素が全て描画されるような高さに調整する(?)
- 子要素の高さは、親要素の高さに追従する
- びよーん
hiddenの場合。
-
overflow:scroll
の付いた flex 子要素に、縦に長い要素をレンダリングする - flex 親要素は、
overflow:hidden
なので、子要素を全て描画しない - 全て描画する必要がないので、親要素の高さは子要素の高さに依存しなくなる
- 親要素の高さが依存するのは flex の計算値のみ
- 親は枠からはみ出ない
確かに、一般には要素の高さは親要素では無く子要素に依存しますよね。
依存が逆転するようなケースの場合、子要素の大きさの依存を明示的に断ち切る必要があって、それが今回の overflow:hidden
では?