Webサイトの横幅100%表示は、実は結構難しい
公開日:
こんにちは。x-fitチーム・エバンジェリストの渡辺です。
PCサイトでは、Webサイトの横幅について、9:16のモニタも多いため、横幅いっぱいというサイトデザインはあまりありませんが、スマートフォン向けWebサイトでは、その小さい画面を有効に利用するため、画面幅いっぱいにコンテンツを配置することが多くあります。サイトでの横幅いっぱいの表示というと、CSSでwidthプロパティを指定すればOKと思われがちですが、実は、そう簡単にはいかないものです。ちょっとまとめてみましょう。
横幅100%のイメージ
ここでいう横幅100%は、次のような状態を示しています。
- 左右のすき間なく指定したコンテンツが収まっている状態。
- ブラウザの横スクロールバーは出ない。
指定の方法と、実際の結果
次に示すようなHTMLで実際の表示結果を確認してみます。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <title>Content Width Sample</title> <style type="text/css"> .full{ text-align:center; display:block; background:#aaaaaa; height:40px; line-height: 40px; } </style> </head> <body> <div id="container" class="full">CONTAINER</div> </body> </html>
単にCSSでwidthを100%指定する。
CSSに以下を追加してみます。
width : 100%;

コンテンツの横にすき間が見られます。100%と指定するだけでは、解消できません。
borderを入れる。
このようなブロック要素には、枠線をCSSで入れることもありますので、以下のようなプロパティを追加してみます。
border:#A80000 1px solid; box-shadow: 1px 1px 2px 1px #666; -webkit-box-shadow:1px 1px 2px 1px #666;

左右のすき間は解消されません。しかも、左右にすき間の差がみられるようになりました。
borderを厚めにする。
サイトデザインによっては、枠線や、影付けなどを行って、見栄えを調整することもありますので、以下のような装飾をして、borderを厚めにしてみます。
border:#A80000 7px solid;

相変わらず左右のすき間は解消されず、若干ですが、横にスクロールするようになってしまいました。
一体何がいけないのか
このような表示なってしまうのは、大きく2つの理由があります。
ユーザエージェントデフォルトスタイルが効いている
Webページには、何も指定しなくても、ユーザエージェントデフォルトスタイルというものが適用されています。CSSでなにも指定していないのに、h1やh4といったタグの見た目が異なるのは、このデフォルトスタイルが適用されているためです。
先ほどまで見てきた「左右のすき間」ですが、これはbodyタグに適用されているmarginやpaddingスタイルによるものです。したがってこのすき間を取り除くには、bodyタグに対するデフォルトスタイルを取り除く、いわゆる「CSSリセット」をする必要があります。
CSSリセットの例
body{ padding: 0; margin: 0; }
先ほどの表示に、CSSリセットのみを適用した例

padding・border・marginは、横幅の指定に含まれないという仕様

HTMLには、ボックスモデルという考え方があります。コンテンツと、それを取り囲むpadding・border・marginについてのルールです。ボックスモデルでは、コンテンツの周囲を囲むpadding・border・marginは、コンテンツの幅には含まれないと規定されています。
そのため、ボックスモデルという考えでは、borderなどの枠線を含んだ表示に際して、コンテンツ幅を100%指定するのは間違いで、画面幅からborderなどの枠線分を差し引いた幅を指定する必要があります。
とはいえ、どんな解像度のどんな端末がアクセスしてくるのかわからない以上、差し引いた値を固定値で指定することは難しいと言えるでしょう。
100%幅にしたいならどうすべきなのか
box-sizingプロパティを変更する
CSS3で、ワーキングドラフト段階のプロパティに、box-sizingがあります。このプロパティで、コンテンツ幅の指定に、paddingとborderの幅を含めるかどうかを指定できます。
box-sizing : border-box;
こうすることで、borderとpaddingについては、widthで指定した値に含まれるようになるため、今回の例のような、左右にmarginがなく、ぴったり表示したいという場合には有効に機能します。marginが0でない場合は、marginはコンテンツの幅に算入されませんので、うまく表示されません。このプロパティはいくつかのスマートフォンで動作しないことも確認されていますので、これだけで完全対応とはいかない状況です。
横にborder/padding/marginをつけないデザインにする。
ボックスモデルの仕様は、border/padding/marginはコンテンツ幅に含まれないというものですから、横方向に対してborder/padding/marginを使用しなければ、コンテンツ幅100%でぴったりの表現ができる、ということでもあります。こういうデザインはjQueryMobileのテンプレートを使用した場合によくあります。

このようなデザインは、ぱっと見た時、コンテンツが左右ともに途中で切断されているように感じられます。結果として、全部が見えていないのではないか、という印象につながりやすく、デザインを重視するサイトの場合、制約として受け入れがたい場合があるかもしれません。
viewportのwidth属性を固定値にして、すべてをpx単位で指定する
解像度の低い端末に合わせてviewportを固定値(たとえば320pxなど)で設定し、幅をすべてピクセルで合わせる方法です。この場合、端末を回転させても固定値となるため、端末を横にした場合に画面を最大限活用することができなくなるという問題が出てきます。また、国内のいくつかの端末は、viewportの設定自体が利かないものも確認されており、完全な策とは言えません。

JavaScriptで幅を測ってスクリプトで動的にスタイル調整する
実際の端末の画面幅をJavascriptで取得し、動的に、CSSプロパティを調整する、というものです。以下に一例を示します。
<script type="text/javascript"> var x = document.body.scrollWidth; //実際の幅はborderの分差し引く var contentWidth = x - (3*2); var container = document.getElementById('container'); container.setAttribute("style", "width : "+ contentWidth +"px;") </script>
表示例

きちんとやれば、100%幅表示が可能になります。ただし、Javasciript動作には機種依存が存在するため完全な方法ではありません。また、端末回転時などにも適用する必要があること、CSSの調整が即スクリプトの修正に直結するため、テストや運用の手間が増大する、という可能性もあります。
こうしてみると、画面幅いっぱいにコンテンツを表示するということは、簡単なように見えて、意外と考慮すべき点があり、簡単ではないことがおわかりいただけるかと思います。