前回 に引き続き、今回はfloatプロパティを利用した実用度の高いボックスの配置の実現方法を解説します。
練習用HTML
floatプロパティを利用したレイアウトの練習に複雑なHTMLを用意する必要はありません。ボックスの配置方法さえ理解してしまえば、その手法はあらゆる要素に適用でき、また、配置された各ボックスがどのような内容を持とうともレイアウトには影響しないからです。
サンプルとなるHTMLは以下の通りです。
HTMLソース
<div id="box-A">
<div id="box-B">
B
</div>
<div id="box-C">
C
</div>
<div id="box-D">
D
</div>
</div>
CSSを個別に指定できるように、各要素にはid(#box-AからD)を振りました。解説ではid名ではなく、単にボックスA, ボックスB...と呼ばせていただきます。
背景色を着けてボックスを確認
まずは、要素の生成するボックスを視覚的に把握しやすいように、それぞれに背景色を指定しましょう。
HTMLソース(サンプル:preview1.html )
#box-A {
background-color: #333;
}
#box-B {
background-color: #99CC00;
}
#box-C {
background-color: #993399;
}
#box-D {
background-color: #CC6600;
}
表示ではボックスAが見当たりませんが、3つのボックスの後ろに隠れています。
図1 背景色をつけてボックスを確認
ボックスBとCをフロート
次に、ボックスBとCに横幅(width)と寄せ(float)を指定しましょう。
HTMLソース(サンプル:preview2.html )
#box-A {
background-color: #333;
}
#box-B {
background-color: #99CC00;
width: 300px;
float: left;
}
#box-C {
background-color: #993399;
width: 300px;
float: left;
}
#box-D {
background-color: #CC6600;
}
ブラウザの表示を確認すると(大きめのウインドウサイズにして下さい) 、ボックスDにはfloatを指定していないにも関わらず、3つとも横に並んでいるように見えます。しかし、実際にはボックスDはフロートしたボックスAとBの後ろに重なるように配置されています。
図2 ボックスBとCをフロート
ついでに仕様を確認
ここで、以下の2点の仕様を確認してみましょう。
フロートするボックスの合計幅が包含ブロックの幅(内容領域)を超えた場合は、後にフロートするボックスから下に配置される。
フロートするボックスは包含ブロックの高さの算出から除外される
包含ブロックはフロートするボックスの親ボックス、つまり、ボックスAを指します。
カラム落ちの再現
先ほどのプレビュー: ボックスBとCをフロート を表示し、ブラウザのウインドウサイズ大きくしてから徐々に狭めてみてください。あるところでボックスCがカクっと下に落ちるはずです。包含ブロック(ボックスA)中で、複数のフロートするボックスが収まりきらなくなったところで、後にフロートしているボックスCが下に落ちる、これが1.の仕様を再現した表示で「カラム落ち(したー!) 」と呼ばれる状態です。
ボックスAの横幅をフロートする二つのボックスが収まりきらない値に設定しても同じ状態になります。
ボックスAに小さな横幅を指定してカラム落ちさせる
サンプル: preview3.html
図3 ボックスAに小さな横幅を指定してカラム落ちさせる
包含ブロックがフロートするボックスを高さの算出に用いない仕様の再現
この状態のときにもう一つ注目してほしいのは、文書の構造上、ボックスAの中にあるはずのボックスCは、表示の上ではボックスAの外に飛び出してしまっているところです。これが2.の仕様を再現した表示で、フロートするボックスの包含ブロック(ボックスA)の高さにフロートするボックスが含まれていことを表しています。このときのボックスAの高さの算出には、フロートしていないボックスDだけを仕様しています。
ためしに、ボックスBとDにそれぞれ違う値のheightプロパティを指定すると、ボックスAの高さはボックスDを基準に調整されます。
ボックスAの高さがボックスBを無視している状態
サンプル:preview4.html
図4 ボックスAの高さがボックスBを無視している状態
clearプロパティを指定
包含ブロックがフロートするボックスを高さに含めないと、後に続くボックスがフロートするボックスと重なり合ってしまうので、たいていの場合困った表示になります。
これを解決するためには、包含ブロック内のフロートするボックスの後続のボックスにclearを指定します。
HTMLソース(サンプル:preview5.html )
#box-A {
background-color: #333;
border: 5px solid #000; /*表示確認のために枠線を引いた*/
}
#box-B {
background-color: #99CC00;
width: 300px;
float: left;
}
#box-C {
background-color: #993399;
width: 300px;
float: left;
}
#box-D {
background-color: #CC6600;
clear: both;/*floatによる左右への流し込みを解除*/
}
図5 ボックスDにclearを指定
clearの指定されたボックスDはフロートしたボックスの下に回ることになり、ボックスAはボックスDまでを包み込むように表示します(結果的にフロートしているボックスB、Cも無事包み込みこみます) 。
clearを指定できるボックスが無いとき
文書構造によっては、clearを指定できるボックスが無い場合もあります。このようなときはclearfixと呼ばれる、:after疑似要素とcontentプロパティを利用したクリア方法をとります。
このテクニックに関してはここでは解説を省かせていただきますが、対象ブラウザによってさまざまな種類が考案され、解説サイトも多く存在します。もちろん『実践 Web Standards Design』でも、古いブラウザからモダンブラウザまでを対象としたclearfixを、その仕組みから細かく解説しています。
最後に
floatプロパティを利用したレイアウトの手法は、これまでにさまざまなものが考案されています。『 実践 Web Standards Design』では、それらを手法別に4つに分類し、それぞれ基本的な使い方から応用方法までを解説しています。今回は、その中の1つ「複数フロートの横並び」を簡単に解説したものになります。この手法はページのレイアウトからメニューのレイアウトまで、さまざまな場面で利用できます。
『実践Web Standards Design』の第6章「複合レイアウトで情報を整理したブログページの制作」では、文書のマークアップからCSSによるデザインまでを一通り解説していますが、ここでサンプルとして制作するサイト のレイアウトは基本的に今回解説した手法だけで実現しています。
図6 サンプルサイトのレイアウト
中央部分のコンテンツ領域をボックスAとしたとき、中のボックスB,Cをフロートして配置。
図7 包含ブロックAの中でボックスB,Cがフロート
上図、ボックスCを包含ブロックAとすると、中のボックスB,Cをフロートした後、Dでクリア。
図8 包含ブロックAの中でボックスB,Cがフロート、その後ボックスDがクリア
さらに、上図、ボックスDを包含ブロックAとすると、同じように中のボックスB,Cがフロートしています。
図9 包含ブロックAの中でボックスB,Cがフロート
この例でもわかる通り、複雑なレイアウトも単純なボックス配置の組み合わせで実現することができるのです。
floatプロパティのテスト問題集
以前、私の授業でに行ったfloatプロパティに関するテスト問題集を紹介しますので、興味のある方は解いてみてください。
今回解説した手法だけでは解答出来ない問題も含まれておりますが、全ての解答例はコメント欄に書いています。解説の方は長くなりますので、『 実践 Web Standards Design』の4章を熟読するように……と、今回は出版記念の連載らしく締めさせていただきます。