質問: ``` body { overflow:hidden; } ``` この記述を加えると、コンテンツ量に関わらずブラウザのスクロールバーが消えて、 スクロールができなくなるというのは、よく知られたテクニック?の1つかと思います。 私も簡単なモーダルを実装するときによく使っています。 ``` body.fixed { overflow:hidden; } ``` みたいな感じで、モーダルを出すときにbodyにclassを加えて`overflow:hidden;`にする簡単なものです。 何も考えずよく使っていたのですが、ふと疑問が湧きました。 **なぜbodyに`overflow:hidden;`が指定されていると、ページのスクロールが無効になるのか?** たとえば高さが3000pxにおよぶコンテンツがあったとして、その場合のbody要素の高さも3000pxです。 3000pxの要素に`overflow:hidden;`がかかっていたところで高さは3000pxのまま。 ブラウザwindowの中にその高さを超えるコンテンツものがあったら、スクロールできるのが当然のように思えるのですが、実際にはそうはなりません。 body要素の`overflow:hidden;`はブラウザwindowそのものに指定したのと同じことになるということでしょうか? これは別件で質問立てることなのかもしれませんが、 上記の方法で実装したモーダルで、特定の環境下のEdge*のみ、 モーダルを閉じたとき(overflow:hidden;を削除)に、 スクロール位置がページ下に落ちてしまう現象にぶつかりました。 それで実は`overflow:hidden;`のことをよくわかっていないことに気づき 投稿させてもらいました。 body に overflow:hidden; をあてるとなぜスクロールしなくなるのか? 詳しくわかる方がいたら教えてください。 よろしくお願いします。 *お客さんの閲覧環境でのみ発生していてどのような環境下のEdgeでそうなるのかわかっていません。
回答: `overflow`プロパティが`body`要素に対して設定された場合、その`overflow`プロパティの値は、**`html`要素 (ルート要素) に適用**されます。そして、ルート要素に設定された`overflow`プロパティの値は、**ビューポートへと適用**されます1。 > > ### 11.1.1 Overflow: the 'overflow' property > > > UAs must apply the 'overflow' property set on the root element to the > > viewport. When the root element is an HTML "HTML" element or an XHTML > > "html" element, and that element has an HTML "BODY" element or an > > XHTML "body" element as a child, user agents must instead apply the > > 'overflow' property from the first such child element to the viewport, > > if the value on the root element is 'visible'. > > > ビューポートとは、簡単にいえば、「ブラウザのウインドウに表示されている領域」を指します2。ここに`overflow: hidden`が適用されたことにより、`body`要素内に存在する内容は、ビューポートのサイズに合わせて切り取られ、スクロールバーが表示されなくなります。 ただし、`overflow: hidden`を設定したとしても、そのボックスは**スクロールコンテナ**であることに注意してください。スクロールコンテナであるため、依然として JavaScript を用いるなどの方法でスクロールが可能となります。 CSS Overflow Module Level 3 にて追加された`clip`値を使用すると、スクロールコンテナではないボックスとすることが出来ますが、 2019 年 4 月 25 日現在、`clip`値をサポートしているブラウザはありません3。 参考: * Cascading Style Sheets Level 2 Revision 2 (CSS 2.2) Specification - 11.1.1 Overflow: the 'overflow' property * Cascading Style Sheets Level 2 Revision 2 (CSS 2.2) Specification - 9.1.1 The viewport * Can I use... Support tables for HTML5, CSS3, etc - CSS overflow property