LoginSignup
6
5

More than 5 years have passed since last update.

親要素からはみ出した子要素は、右側だけがスクロール表示される

Posted at

ネガティブマージン(margin に負の値)や position: absolute; を指定した要素が、親要素からはみ出した場合に、横スクロールが奇妙な現われ方をしたので調べてみた。
まずは簡略化したコードを用意。

<div id="wrap">
    <div class="left">左ブロック</div>
    <div class="right">右ブロック</div>
</div>
#wrap {
    margin: 0 auto;
    width: 300px;
}
#wrap .left {
    margin-left: -100px;
}
#wrap .right {
    margin-right: -100px;
}

#wrapの横幅は300pxなので、ブラウザのウインドウ幅が300px未満になったときに横スクロールが発生する。ところで、#wrapには子要素のブロック要素が二つあり、それぞれ左右に100pxだけ、親要素からはみ出ている状態にある。
この場合、ウインドウ幅を小さくしていくと、どのように表示されるだろうか。

はみ出した部分はスクロール幅に含まれるのか

結論からいうと、右側だけ含まれる。
文章だけでは分かりにくいので画像をどうぞ。

ウインドウ幅が広いとき

スクリーンショット 2013-11-18 6.45.32.png

ウインドウ幅を狭くしたとき

スクリーンショット 2013-11-18 6.55.50.png
画面下部に横スクロールが出ている。
スクロールバーは左端に達しているので、赤いブロックの左にはみ出た部分は見えなくなっている。
一方で、右には若干スクロールさせる余地が残っており、青いブロックの右にはみ出した部分は表示される。

横幅の小さい端末で閲覧した時に、左右アンバランス(左側に寄っているよう)に配置されて見えてしまう。
このとき、window, document, 親要素の幅を取ってみた。

console.log( $(window).width(), $(document).width(), $("#wrap").width());
// 400, 450, 300

ウインドウ幅を親要素の幅と同じにしたとき

スクリーンショット 2013-11-18 18.32.41.png
右側にはみ出た青い部分は全部見えるが、左側にはみ出た赤い部分は全く見えなくなる。
同じく、window, document, 親要素の幅を取ってみた。

console.log( $(window).width(), $(document).width(), $("#wrap").width());
// 300, 400, 300

なぜか右側にはみ出た長さ分だけ、documentは親要素より大きくなっていて、
左側にはみ出た分は無視され(documentの幅に含まれない)るため、横スクロールで右側だけ見える。

対処策

親要素のさらに外側をブロック要素で囲み、左右にはみ出た分も含めた幅をwidthに指定する。

<div id="outer">
<div id="wrap">
    <div class="left">左ブロック</div>
    <div class="right">右ブロック</div>
</div>
</div>
#outer {
    margin: 0 auto;
    width: 500px;
}

はみ出る長さを後で変えるかもしれない、というときは、
この要素の幅も変更しなければいけないので、やや気持ち悪い。

仕様か

以下のブラウザで同じ挙動を確認。(いずれもOS X)
- Google Chrome
- Safari
- Firefox

一見奇妙な挙動なので戸惑うが、主要ブラウザで同じところを見ると仕様なのだろうと思われる。
推測に過ぎないが、テキストが長くて親要素を突き出してしまうケースを想定して、
右側にはみ出た分だけはdocumentの幅に含めるようにしたのではないだろうか。
(右から左へ記述する言語を無視していることになるが)

W3Cの文書までは確認できていない。

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5