第3章 Boxモデルによるページ・レイアウト

3-1. <div>タグによるページのレイアウトの概要

従来はウェブ・ページの中の要素をグールーピングするための枠造りには<Table>タグが使われるのが一般的でした。然しながら、<Table>タグには<th>や<tr>や<td>等の色々な子タブがあってCSSのルールで制御するのが難しいということもあって、最近では<Table>タグに替わって<div>タグがウェブ・ページの枠組みを作るBoxとして使われるようになりました。

そこで先ず、枠組みとなるBoxの性格をCSSのルールで制御する立場で説明すると次のような図で表せます。


一般に、<div>タグのみならず、Boxの性格を持ったタグの配置を規定するものとして次のものがあります;

3-2. <div>タグによるページのレイアウトの幾つかのSample

この節では色々なSampleを通してBoxモデルによるレイアウトに就いて学ぶことにします。

Sample-01
これは典型的なウェブ・ページのレイアウトの基本的な例で、ボーダーもマージンもパディングも、更にBoxの中の内容物も含まないサンプルです。作成してみますと、このようになります。

一見してみますと、これは全て予期した通りにレイアウトされているようですが、1箇所期待外れの所ががあります。それは#main Boxの現れ方です。#main Boxに現れている背景色は実は#container Boxの色です。高さを指定していない#main Boxに内容物が何もないので、#main Boxは無視されたのです。

Sample-02
そこで今度はSample-01の例に、#navi Boxと#main Boxの外側に2pxのボーダーを付してみると、このようになります。
どうです、今度は幾つかの問題点が顕在化しました。
先ず、#navi Boxと#navi Boxと#main Boxにボーダーを指定したために、各々のBoxの正味の横幅が増えて、親Boxの枠の中に2番目の子Boxの#main Boxが入らなくなり、下にはみ出してしまったのです。このような現象はレイアウトの乱れと呼ばれているようです。この乱れを解消するには、#navi Boxと#main Boxとの横幅を増えた枠線の幅だけ減らさなければなりません。即ち、#navi Boxの横幅を300-2=298pxにし、#main Box700-2=698pxにすることです。

次に、各々のBoxに中身が入ったために、各々のBoxの上枠と中身の間の隙間の距離が異なっていることに気付きます。これは、ホームページ・ビルダーやブラウザーが初期設定としてある種のパディングやマージンを設定しているために起こっているのです。上級者は自分で設定したCSSで完全に見栄をコントロールするために、このような初期設定をリセットするスタイル・ルールを設定します。

Sample-03
そこで、これらの問題点を直したサンプルがこちらです。即ち、問題のBoxの横幅を調整し、ソフトウェアの初期設定をリセットしたものです。各Boxのパディングの初期設定はリセットされ、内容物は一様に各Boxの上端に張り付いたことは確かですが、レイアウトの乱れは依然として存在します。

Sample-04
そこでFloat(回り込み)というスタイル・ルールで、#navi Boxと#main Boxが確実に左に回り込んで横並びになるように指示することが必要になってくるのです。Float:left: を規定したサンプルはこのようなものです。
残念ながら、#navi Boxと#main Boxは予期した通り横一列に並びましたが、また新しい問題が現れてきました。
それは、#footer Boxが#main Boxにつられて上にあがってくるという新しいレイアウトの乱れが現れたことです。

Sample-05
上のサンプルの問題の原因は、#footer Boxが#main Boxの Float:left:というスタイル・ルールを継承して起こる問題です。#footer Boxは#main Boxと同列の入れ子Boxではありませんので、この継承されたFloat:left:というスタイル・ルールをリセットしなければなりません。そこで、#footer BoxにClear: both; という新しいスタイル・ルールを適用したものがこのようなものです。このサンプルを見るとまだ#main Boxが最終的なレイアウトになっていませんが、これは#main Boxの内容物が増えた時点で#navi Boxの高さと同じに設定すれば解決されることで、一応所期のレイアウトの目的はこのサンプルで達成されたように思われます。

Sample-06
然しながら、現実的にはこれまでのサンプルでは各Boxの中に十分な内容物が入力されていませんし、それらの内容物を見栄えよく配置するパディングやマージンも適用されていません。そこで、もう少し内容物を入力し、パディングやマージンも適用してみましたのがこのようなものです。#navi Boxと#main Boxにパディングを入れたのに横幅を調整していなかったので、当然のようにレイアウトの乱れが生じています。

Sample-07
#navi Boxと#main Boxの中身を左枠線からそれぞれ20pxのパディングを入れたので、それぞれの横幅を20px縮小しました。その結果のこのサンプルをご覧ください。 見事にレイアウトの乱れは直り、これで完成です。

3-3.  ページ・レイアウトの乱れの解消法

インターネット上で「ページ・レイアウトの乱れ」に関する検索をしますと、過去に沢山の方々がこの問題で悩まされていることが判ります。筆者自身もこのBoxモデルに慣れるまで散々この種のページ・レイアウトの乱れに悩まされました。ある時はホームページ作成ソフト或いはブラウザー・ソフトのバグではないかと思ったこともありました。インターネット上でもそれらのソフトのバグ説が囁かれています。筆者の経験によりますとインタネット上で提示されている解決案は殆どがある時期の古いバージョンの関係ソフトに対する解決策であって、最新バージョンでは殆どが改善されているように思いました。

以下の解決策は前節のサンプルを通して学んだものを纏めたものです。

  1. 複数のBoxを入れ子にして横に並べる場合は、入れ子Boxの横幅の合計を親Boxの横幅以下にする:
    入れ子Boxの横幅とはスタイル・ルールで指定するサイズに横のパディングとマージンとボーダーの幅を合計したものであることを理解すべきです。
  2. 複数のBoxを入れ子にして横に並べる場合は、入れ子Boxの回り込み(Float)を統一してLeft(又はright)に指定する。
  3. 入れ子が終わったBoxにはBoxの回り込み解消(Clear: both)、を指定する。
  4. 入れ子Boxの中身の要素の横幅をその入れ子Boxの横幅サイズ以下に留める:
    中身の要素の横幅を明示的に指定していない場合は特に危険で、文字列の長さが変わったり、フォント・サイズを大きく変更した場合は、入れ子Boxの中身の要素の横幅は入れ子Boxの横幅を超過してレイアウトの乱れの原因になることが多い。
  5. 入れ子の子BoxがFloatしている場合、その親BoxにOverflow: auto;を指定する:
    入れ子の子BoxがFloatしている場合、その親Boxが子Boxを認識出来ずにそのBoxの中にFloatしている子Boxを包含出来ないことがあります。その場合、親Boxに「位置」カテゴリーの「はみ出した場合(Overflow)」の「自動(auto)」を指定して、子Boxを認識させることができる。但し、この指定で弊害が出ることがあるので、要注意。
  6. ホームページ作成ソフト或いはブラウザー・ソフトの初期設定を念のためにリセットしておく:
    各々のソフトのパディングやらマージンの初期設定は判りかねますので、その値が影響してレイアウトの乱れの一因になることがある。 単に、スタイル・ルールの中に * { margin : 0; padding:0; }を入れておけばよい。