JeffreyFrancesco.org 公開日 タグ Tag Permalink 現在地 Facebook page Twitter RSS feed

ツイッターでも書いたのですが、preの背景をブラウザの幅いっぱいに拡大する というエントリ読んでて「ほうほう :before/after 疑似要素を使う手もあるか…」と感心しつつトラックパッドでスクロールさせたら、突然コンテンツが消えてしまって深夜に「うぎゃー!」とかなっておったのです(注: これ書いてる今は直ってます)

まあ pre に限らず、基本的に幅固定で中央寄せだけど、内側にある特定のブロック要素の背景はブラウザ幅いっぱいに広げたいという場合、広げたいブロック要素に大きめ(10000pxとか)のパディングを付けて左右に広げ、それと同じだけのネガティブマージンを付ける事で背景部分を外側にはみ出させる手法は割とよく使われる手法ではないかと思うのですが、左右に大きなパディングが付く分当然 body の幅を超えて横スクロールバーが出るので、そのはみ出た部分を隠すために、

body {
    width: 100%;
    overflow-x: hidden;
}

と指定するのを思い付く訳ですが、実際にやってみるとこれがあまり上手くいかない訳です。

実際にやってみたサンプルを置いておくので開いて試していただきたいのですが、bodyoverflow-x: hidden; で確かに横スクロールバーは出なくなりますけど、マウスホイールやカーソルキーを使ってスクロールは出来てしまうのですよね。

例えば Mac のマルチタッチトラックパッドで2本指スクロールが有効な場合、うっかり斜め方向にスワイプしてしまったがために、スクロールした瞬間にコンテンツが消滅したように見えてしまう(実際にははみ出た部分が見えてしまうのですが、スクロールバーが無いのでずれたのかどうかよく分からない)という現象が Safari では時たま発生してしまいます(発生しない事もあるのでこれがまたよく分からない…)その他の Firefox や Opera ではそこまで酷い事にはなりませんが、どちらにせよ斜め方向にスワイプしてしまった場合には横側方向にもズレてしまう事に変わりありませんです。

という訳で、最終的には body の直下にひとつ幅100%のボックスを置いて全体(ではなくてもいいけど、とにかくはみ出させる要素を包括している幅固定されたボックス)をラップして、そのボックスに overflow-x: hidden; を指定する(サンプル)しか、今のところ方法がないように思っております。例えば、

<body>
  <div id="header"></div>
  <div id="content"></div>
  <div id="footer"></div>
</body>

のような、よくある3ブロックからなる構造の場合に、もう一つ外側に全体を包括する div を置く方法もあるし、宗教上の理由(?)で外側に余計なボックスを加えたくない…という場合は、逆に上記の #content を幅100%にして、その内側の要素に幅指定してセンタリングすればよろしいかと。

<body>
  <div id="header"></div>
  <div id="content"><!-- 幅100%で overflow-x:hidden; するボックス -->
    <div class="entry" id="entry-1"><!-- 幅指定してセンタリングするボックス -->
      <!-- いくつかの内容… -->
      <pre><!-- pre の中身 --></pre><!-- はみ出させる要素 -->
    </div>
    <div class="entry" id="entry-2"></div>
    <!-- 以下いくつかの要素… -->
  </div>
  <div id="footer"></div>
</body>

上はひとつの例ですけど、まあこんな感じでとにかく、

  1. body 直下にあって width: 100%; overflow-x: hidden; を指定するボックス
  2. width 指定して margin: 0 auto; でセンタリングするボックス
  3. パディングとネガティブマージンを指定してはみ出させる要素(ボックス)

の3要素が入れ子関係になっていればよい訳で。もちろんこの関係を作れない場合は今のところ諦めるしかないとは思いますが、特にブログなどの場合だともう一つエントリ全体を囲む div 要素なり article 要素なりがあって、まず直下に pre 要素を書く事は少ないんじゃないかなあという気がする…まあ pre じゃなくてレイアウト用のボックスとかの場合は考えないといけないですけどね。

とりあえず以上のように body 要素ではなく直下の幅100%の要素に overflow-x: hidden; を指定する事で、先に挙げた横スクロールの問題は解除する事が出来ます。ただしこれはこれでまた、幅指定したボックスよりウィンドウ幅が狭い場合にも横スクロールが出来なくなってしまうという問題がある訳で、これを回避する方法を(例えばメディアクエリ使ってウィンドウ幅に応じてレイアウト変えるとか)工夫しないといけないのですが。汗

要するに、もっと上手い方法があるんであれば私も知りたいです。涙