CSSによる崩れない段組
ネットサーフィンをしていると、floatを使って段組しいていて、レイアウトが崩れているサイトを時々見かけます。 ほとんどの場合が、左のみwidthを指定しているが、右に指定していない場合です。これはWINのIEでのみ段組されて表示されますが、モジラ等では、右部分は下に回りこんで表示されます。 ということで、ここでは上下にヘッダーとフッターを置いたサンプルを使いながら、メイン表示部分を左右2段にスタイルシートで組む際の注意についてと、その応用の3段組 ( 3カラム ) について纏めてます。
スタイルシートで2段組のレイアウトを行う場合、大きく分けて2つの方法があります。 1つは、float:leftを使う方法で、1つはposition:absoluteを使う方法です。 それぞれ、メリット、デメリットがあります。
どういったサイトを作りたいのかという目的によって、どちらの方法を使うかが決まってきます。 それでは、サンプルを使いながら、どうしたら崩れる(ない)のか、何が出来るのかまずは見て見ましょう。
サンプルの基本のHTML
- まずは、サンプルの基本となるHTMLです。
HTMLのbody内は下記の通りです。<div id="my_body"> <div id="my_header">ヘッダー</div> <div id="my_main"> <div id="my_navigation"> ここにナビゲーション </div> <div id="my_contents"> ここにメインコンテンツ </div> </div> <div id="my_footer">フッター</div> </div>
- my_bodyはサイト全体の幅を変えたい時に使います。
センタリングには、margin:0 auto ; またはmargin-left:auto ; margin-right:auto; を使います。 text-align でセンタリングされるのはIEのみでバグですので気をつけて下さい。 - my_mainは真中のメインの部分に背景等を指定したい時に使います。
- 左ナビゲーション・ボックスのidにmy_navigation、右コンテンツ・ボックスのidにmy_contentsを指定。
CSSで主に変更するのはこの部分です。 - その外、ヘッダー、フッター共通部分のCSSは下記の通りです。
* { margin : 0 ; padding : 0 ; }
body { width : 100% ; }
#my_body { position : relative ; }
#my_header { width : 100% ; height : 50px ; }
#my_footer { width : 100% ; clear : both ; }
- 全ての要素のmargin、paddingは「0」です。
- bodyの幅は通常は指定しなくても問題ないです。 IEの領域(body)からはみ出す要素がないのに横スクロールバーが出た時のバグ対策です。
- ヘッダーの幅は100%、高さは50pxに指定してあります。
- フッターの幅は100%、でfloatに対してclearを指定してあります。
- my_bodyのposition:relativeはposition:absoluteを使ったレイアウト用です。position:absoluteでレイアウトする時に、親要素にpositionが指定されていないと、ブラウザによって、親要素からの位置になったり、body開いているウィンドウからの位置になったりとバラバラになります。 親要素にposition (relative, absolute等) が指定されていると、その子要素の位置は親要素から計算されます。
- 特に記述が無い場合のサンプルは、上記のHTML及び、CSSです。
- その他、サンプルでは其々のボックスの中にpaddinをとるためボックス要素を入れ、その中にコンテンツを置く等、細かい指定はありますがここでは省略します。
floatを使った段組サンプル。
TYPE A-1 サイト全体と左右のボックスの幅を絶対値で指定。幅 700px センタリング
サイト全体の幅をwidth:700px;でウィンドウの真中に表示。
#my_body { margin: 0 auto; width : 700px ; }
#my_navigation { float : left ; width : 150px ; }
#my_contents { float : left ; width : 550px ; }
ブラウザのウィンドウサイズを縮めて見ましょう。
レイアウトは崩れません。 サイトの幅を固定すると、小さめのモニターなどでは全画面表示にしなくてならない。また、横スクロールしないと閲覧できない事もあります。
TYPE A-2 左右のボックスの幅を絶対値で指定悪い例
左ボックスにfloat : left ;と、widthを絶対値で指定するが、右ボックスにfloat:left;と、widthを絶対値で指定する。
#my_navigation { float : left ; width : 150px ; }
#my_contents { float : left ; width : 550px ;}
#my_header, #my_footer{width:700px;}
悪い例といいますか、ブラウザのウィンドウサイズを縮めて見ましょう。
親要素(この場合body)の幅より左右のボックスの幅の和が大きくなると、右ボックスは左ボックスの下に回りこみます。
右ボックスを下に回り込ませたくない場合は、親要素も絶対値で指定しましょう。
TYPE B 左右のボックスともに相対値で指定お勧め出来ない例
#my_navigation { float : left ; width : 20%; }
#my_contents { float : left ; width : 80%; }
ブラウザのウィンドウサイズを縮めて見ましょう。
左右のボックスともに相対値のため、幅の狭いボックス(この場合my_navigation)が、ウィンドウサイズを狭くした時、狭くなりすぎる事があります。 また、weidthを指定した要素がボックスサイズより大きい場合はレイアウトが崩れる。例えば、widthが300pxの要素をmy_navigationに入れると、Win IEの場合、my_contentsが下に回りこむ。 Firefoxの場合はみ出た部分の要素が重なる。
子要素のサイズが親要素を上回れば、レイアウトが崩れるのは、このレイアウトに限らずですが、相対値で指定していると、子要素が親要素を上回るかどうかはウィンドウサイズに左右されるということです。
TYPE C-1 左ボックスを幅固定、右に相対値で指定悪い例
左ボックスにfloat : left ;と、widthを絶対値で指定するが、右ボックスにfloat:leftと、widthを相対値で指定する。
#my_navigation { float : left ; width : 150px ; }
#my_contents { float : left ; width : 80% ; }
ブラウザのウィンドウサイズを縮めて見ましょう。
このスタイルの場合、
左150px、右80%で、左150pxが、ウィンドウの幅の20%以下になると (この場合、
ウィンドウの幅が750px以下) 右のボックスが左のバックスの下に回り込んでしまいます。
TYPE C-2 左ボックスのみ幅固定。とても悪い例
左ボックスにfloat : left ;と、widthを絶対値で指定するが、右ボックスにfloat:leftのみ指定し幅を指定しない。
#my_navigation { float : left ; width : 150px ; }
#my_contents { float : left ; }
一言言うならば、最悪のパターンです。 Win IE以外のブラウザでも検証しましょう。
Win IEでは常に左右に段組されるが、それ以外のブラウザOpera7、Firefox1等では、 右ボックスは常に左ボックスの下に表示される。
TYPE C-3 左ボックスのみ幅固定。悪い例
左ボックスにfloat : left ;と、widthを絶対値で指定するが、右ボックスには何も指定しない。
#my_navigation { float : left ; width : 150px ; }
#my_contents {}
右ボックス部分が親要素一杯にベタで表示され、左ボックスと重なり、無指定のため左ボックスの後ろに回り込む。
上記、特にTYPE C-2とTYPE C-1の2つは、割と見かけますが、どのブラウザ見ても、ベタで重なって表示されるので、流石にこのTYPE C-3のようなCSSを書いているサイトはありません。 では何故わざわざ、ここでサンプルまで作ったのかといいますと、ここに崩れないCSSを書くヒントがあるからです。
TYPE C-4 左ボックスのみ幅固定。幅 : 100%
TYPE C-3の右ボックスに、左ボックスの幅分だけ、左マージンを取る。
#my_navigation { float : left ; width : 150px ; }
#my_contents {margin-left: 150px;}
これで、float:leftを使った崩れないレイアウトが出来ました。
TYPE C-5 左ボックスのみ幅固定。幅 : 80% センタリング
TYPE C-4をセンタリングして見ました。
#my_body { margin : 0 auto ; width : 80% ; }
#my_navigation { float : left ; width : 150px ; }
#my_contents {margin-left: 150px;}
TYPE C-6 右ナビゲーション幅 : 100%
TYPE C-4の左ボックスを右に配置。HTMLはそのまま、左ボックスをfloatで右に配置、右ボックスの右マージンを合わせる。
#my_navigation{float:right; width:150px;}
#my_contents{margin-right:150px; }
positionにabsoluteを使った段組サンプル。
ウィンドウの幅に合わせる。幅 : 100%
左ボックスをposition : absolute で固定、右ボックスの幅に合わせて左マージンを指定。
#my_navigation { position : absolute ; left : 0 ; top : 52px ; width : 150px ; }
#my_contents { margin-left : 150px ; }
ウィンドウの幅の80%に合わせる。幅 : 80% 左寄せ
#my_body{width:80%}
#my_navigation { position : absolute ; left : 0 ; top : 52px ; width : 150px ; }
#my_contents { margin-left : 150px; }
全体をセンタリングする。幅 : 80% センタリング
#my_body{width:80%;position:relative; margin-left:auto; margin-right:auto;}
#my_navigation { position : absolute ; left : 0 ; top : 52px ; width : 150px ; }
#my_contents { margin-left : 150px; }
幅を固定する。幅 : 600px 左寄せ
#my_body{width:600px}
#my_navigation { position : absolute ; left : 0 ; top : 52px ; width : 150px ; }
#my_contents { margin-left : 150px ; }
右ナビゲーション。幅 : 100%
HTMLはそのまま、左ボックスを右に配置、右ボックスの右マージンを合わせる。
#my_navigation { position : absolute ; right : 0 ; top : 52px ; width : 150px ; }
#my_contents { margin-right : 150px; }
position:absoluteを使ってレイアウトする際の注意と、メリット、デメリット。
position:absoluteで固定すると、そのボックスのサイズが計算されず(WinIE)、
左の固定したボックスが、コンテンツ部分より長い場合フッターに被ってしまうこともありえます。
右のメインコンテンツ部分が、左部分より長ければ問題はもちろんありませんし、
短かった場合は、または、短い事が予想される場合は、下マージン等で調節をするか、フッターを右ボックスの下部に入れて下さい。
またabsoluteは親要素からの位置ではなく、body(ウィンドウ枠)からの位置になるため、 親要素に合わせて移動させる事は出来ない為、サイト全体をセンタリングできません。
それなら、floatを使えば良いではないのでは? 何故position:absoluteを必要があるのか? メリットはあるのか?ということになります。
position:absoluteを使えば、htmlでは左ボックスをbody内の好きな所におけます。 PCブラウザでは横によっているので気になりませんが、携帯等から閲覧した場合、 毎回ナビゲーションをスクロールで飛ばしてからコンテンツに行くのは読み手にとって煩わしい事です。 そこで、ナビゲーションはコンテンツを見終わった一番下に持ってくる事が出来ます。
下記の様に左ボックスをフッターの下に記述しても、同じように表示されます。ヘッダーの前に記述する事も可能です。
<div id="my_header">ヘッダー</div> <div id="my_contents"> ここにメインコンテンツ </div> <div id="my_footer">フッター</div> <div id="my_navigation"> ここにナビゲーション </div>
floatによるレイアウトでも、メインコンテンツにfloat:right; ナビゲーションにfloat:left;を指定すれば、下記の様にHTMLにおいてメインコンテンツをナビゲーションより先に記述して左にナビゲーションを表示させる事が出来ます。 しかし、ヘッダーの前やフッターの後に置く事は出来ません。
また、IE以外のブラウザではdiv要素を入れ子にして、子要素をfloatで配置すると親要素はfloatされた子要素の高さを無視してしまいます。 子要素が全てfloatだとmy_bodyに指定した背景や枠線は表示されません。 <br style="clear:both">等で回避出来ますが、下に意図しない空白が出来てしまいます。また親要素に背景色を指定し幅を指定しないと親要素のテキストが消えてしまいます。
#my_contents { float : right ; }
#my_navigation { float : left ; }
<div id="my_body"> <div id="my_header">ヘッダー</div> <div id="my_contents"> ここにメインコンテンツ </div> <div id="my_navigation"> ここにナビゲーション </div> <div id="my_footer">フッター</div> </div>
さらに、コンテンツ部分をfloatで配置した場合、その中にある要素をfloatで配置し(例えば、画像にテキストを回りこませたり等)、その次の要素でfloatをclearすると、その親要素ごとクリアされてしまいます。といいますか、floatにはその他にも沢山(確認しきれない程)のマイナーなバグがあります。 Win IE6では、<hn>タグや、<p>タグやインライン要素以外のタグを多用すると、ウィンドウサイズを狭くすると、floatを指定していないメインコンテンツ部分が下に回りこむ等といったあります。
コンテンツに、画像や、その他ブロック要素を多用したり、入れ子にすること等があらかじめ分かっている場合は「position:absolute」を使ってレイアウトすることをお勧めします。 「position:absolute」の場合段組が崩れるのは左ボックスが、コンテンツ部分より長い場合に限られからです。
また、逆にBLOGや日記等テキストがメインで凝ったこともしない。いちいちmarginを設定したりするのは面倒だという場合はfloatによるレイアウトが向いているかもしれません。
3段組
ウィンドウの幅に合わせる。floatを使ったサンプル
- 左ボックスのidにmy_navi_1を指定。
- 右ボックスのidにmy_navi_2を指定。
- 中央のボックスのidにmy_contentsを指定。
- 記述の順番は、左右真中になります。
- 左右のボックスに幅を指定。
- 左ボックス(my_navi_1)に、float:left;を指定。
- 右ボックス(my_navi_2)に、float:right; を指定。
- 中央のボックスの左右に左右ボックスの幅分だけmarginを指定する。
<div id="my_header">ヘッダー</div> <div id="my_navi_1"> ここに左ナビゲーション </div> <div id="my_navi_2"> ここに右ナビゲーション </div> <div id="my_contents"> ここにメインコンテンツ </div> <div id="my_footer">フッター</div>
- CSSソース
#my_navi_1 {float:left; width:150px;} #my_navi_2 {float:right; width:150px;} #my_contents {margin:0 150px;}
ウィンドウの幅の80%に合わせ、センタリング floatを使ったサンプル
#my_body{width:80%; margin:0 auto;}
#my_navi_1 {float:left; width:150px; background-color:#d6d6bb;}
#my_navi_2 {float:right; width:150px; background-color:#d6d6bb;}
#my_contents {margin:0 150px ;background-color:#ddd6bb;}
position:absoluteを使ったサンプル
- 左ボックスのidにmy_navi_1を指定。
- 右ボックスのidにmy_navi_2を指定。
- 中央のボックスのidにmy_contentsを指定。
- 左右のボックスに幅を指定。
- 左ボックス(my_navi_1)に、position : absolute ; left:0; top : 50px;を指定。
- 右ボックス(my_navi_2)に、position : absolute ; right:0; top : 50px; を指定。
- 中央のボックスの左右に左右ボックスの幅分だけmarginを指定する。
- 左右のボックスはHTMLの任意のところに記述できます。
<div id="my_header">ヘッダー</div> <div id="my_contents"> ここにメインコンテンツ </div> <div id="my_navi_1"> ここに左ナビゲーション </div> <div id="my_navi_2"> ここに右ナビゲーション </div> <div id="my_footer">フッター</div>
- CSSソース
#my_navi_1 {position:absolute; left:0; top:50px; width:150px;}
#my_navi_2 {position:absolute; right:0; top:50px; width:150px;}
#my_contents {margin:0 150px;}
応用レイアウト その壱
リキッド・タイプで、左ナビゲーションを幅固定、コンテンツ部分を縦に分ける。
「position:absolute」による2カラムの方法でレイアウトしたコンテンツ部分の中で「float:left;」で段組する。
応用レイアウト その弐
サンプルをまとめて見る。
- フロート ( float:left ) を使ったサンプル
- デフォルト 左ナビゲーション
- 右にナビゲーションを置く
- アブソリュート ( position:absolute ) を使ったサンプル
- デフォルト 左ナビゲーション
- 右にナビゲーションを置く
- 3段組 ( 3カラム ) のサンプル
- フロートフロート ( float:left / right ) を使ったサンプル
- アブソリュート ( position:absolute ) を使ったサンプル
ダウンロードファイルは準備中です。