少しわかりにくいですが、こういう状態のことです。
この画像を見るとヘッダの背景色がコンテンツの端まで届いていないことがわかると思います。
原因
この現象はブラウザに横スクロールバーが出るときに発生します。
横スクロールバーはbodyの幅よりbodyの中の要素の幅の方が大きい時に発生します。
これはDeveloper Toolsで調べるとわかりやすいと思います。
(青い部分がbodyの位置と大きさを示している)
この場合bodyの幅自体がコンテンツの端まで存在しないためヘッダにwidth:100%を指定してもコンテンツの端までの幅にならないのです。
対処法
- bodyにmin-widthを指定する
- コンテンツの横幅がbodyの横幅より大きくならないようにする
- ヘッダを追従タイプにする
bodyにmin-widthを指定する
bodyの幅は何も指定しない場合はブラウザの横幅と同じになります。
body内のコンテンツの幅以上の値をbodyのmin-widthに指定することでこの問題に対処できます。
たとえばQiitaの場合だと内部のコンテンツの幅は大体1000pxより少し大きいぐらいですので、bodyにmin-width:1020pxを指定すると問題を解決できます。
ただしこの方法は内部のコンテンツの幅がわからないと使うことができません。
また、この対処法ではブラウザの幅を小さくしていくと横スクロールバーがでてきてしまいます。
(最近のサイトでは横スクロールバーを出さないことが主流?好みの問題かも。)
既存のサイトの問題を手っ取り早く解消するにはこれが一番楽だと思います。
コンテンツの横幅がbodyの横幅より大きくならないようにする
そもそも横スクロールバーを出さないようにするという解決方法です。
横スクロールバーが出てくるのはbodyの幅よりbodyの中の要素の幅が大きい場合が原因でしたので、これをどうにかして解決します。
そもそもなぜbodyの幅よりbodyの中の要素の幅が大きくなるかというと原因は以下のようなものです。
- widthを%以外で指定したブロック要素がありそのwidthがbodyの幅より大きい
- サイズの大きい画像(imgタグ)が存在する
- 途中で改行できない単語が入った文章がある
widthを%以外で指定したブロック要素がありそのwidthがbodyの幅より大きい
基本的にwidthを%以外で指定する(pxなどで指定)と横スクロールバーのでる原因になります。
どうしてもwidthを%以外の数値で指定しなければいけないときはbodyにmin-widthを付けるようにしましょう。
アイコンやボタンなどの小さいサイズならpxなどで指定しても問題になることは少ないと思います。
サイズの大きい画像が存在する
画像(imgタグ)のwidthは画像本来の幅と同じになってしまいます。
これは上記のwidthを指定した場合と同じような問題です。
widthに%で値を指定すると解決できますがそれだといろいろと面倒なので、max-widthに100%を指定しておくとうまくいくことが多いです。
途中で改行できない単語が入った文章がある
これは長い英単語やurlを文章内に使った場合に置きます。
具体的な例は以下のようなものです。
<h1>途中で改行できない例</h1>
<div style="width:50px; border:1px solid black">
http://qiita.com/
</div>
<h1>途中で改行できる例</h1>
<div style="width:50px; border:1px solid black">
We Are The World
</div>
解決策はword-wrapにbreak-word;を設定することです。
参考:word-wrap-スタイルシートリファレンス
ただしbreak-wordを指定すると、英単語が途中で改行してしまって読みにくくなることがあるので注意してください。
ヘッダを追従タイプにする
ヘッダをブラウザのスクロールに追従するタイプにすればそもそもこの問題は発生しません。
ヘッダのpositionにfixedを指定し、本来のヘッダの位置(ページの一番上)にヘッダの高さと同じ高さに指定したプレースホルダを置いておけば実装できます。
まとめ
PC向けのサイトを作るならbodyかヘッダにmin-widthをつけるのが一番手っ取り早く解決する方法だと思います。
実際PC版のgoogleの検索ページのヘッダにはmin-widthが設定されています。(この記事の編集時に確認)
しかし、スマホ向けで横にスクロールができてしまうというのは個人的に好きではないので、min-widthを指定する以外の方法で解決した方がいいと思います。
このほかにも解決方法としてJavaScriptを使うことでも対処できます。