ウェブ今昔物語 第3話 tableレイアウトからfloat段落ち地獄編
ホームページ制作がまだ「tableタグで枠を組む」時代だった頃、CSSという新しい風が吹き始めた。見た目のデザインをHTMLと切り離してコントロールできる――それは当時の制作者にとって希望の光だった。しかし、その中でも「float」によるレイアウトは、救世主であると同時に“段落ち”という新たな苦しみを生んだ。floatで横並びにしたつもりが、少しの差で要素が落ちていく…。そして気づけば、clearfixやIEハックとにらめっこする日々が始まった。
今回は、そんなCSSレイアウト初期の試行錯誤とfloatとの格闘の歴史を振り返りながら、いまでは当たり前となったflexやgridの便利さを、あらためて噛みしめてみたい。
目次
ウェブ制作にレイアウトという概念が求められた時代
1990年代後半から2000年代のはじめにかけて、ウェブサイトには見やすさや整理された構成といった視点が求められるようになり、文章をただ並べるだけでは足りず、どこに何を置くかといったレイアウトの考え方が少しずつ制作現場に根づきはじめていたが、当時のHTMLにはレイアウトを組むための機能がほとんどなく、制作者たちは見た目を整えるためにあの手この手を駆使してなんとか対応していた。
改行タグを大量に入れたり、インデントを調整したり、透明の画像で無理やり余白を作ったりと、いま考えれば強引な方法ばかりだったが、それが当たり前でもあり、そんな中で登場したtableレイアウトは、見た目を表で組む手法として一気に浸透し、ページ全体をtableで構成するスタイルがごく普通のものとして受け入れられていった。
次は、そのtable全盛期の実態と限界について振り返ってみよう。
tableレイアウト全盛期
CSSによる自由なレイアウトがまだ一般的でなかったころ、ウェブ制作の現場ではtableタグを使ってページ全体の構成を組む方法が主流だった。ヘッダーやフッター、サイドバー、メインコンテンツといった各領域を表のセルで分割し、視覚的に整ったレイアウトを実現していた。
多くのサイトが3カラム構成や2段組みをtableで作り、入れ子構造を何層にも重ねて対応するのも珍しくなかった。デザインを崩さずに構築できる安心感はあったが、その反面、HTMLが極端に複雑化して、更新作業が面倒になるという弱点もあった。
ちょっとした調整でも、複数のセルをまたぐrowspanやcolspanを慎重に調整しないとレイアウトが崩れるため、制作には常に神経を使う必要があった。それでも当時は、「HTMLだけでレイアウトが完結する方法」として、多くの制作者にとってこのスタイルが最適解だったのである。
参考までに、当時よく使われていたtableレイアウトの典型例を紹介する。ヘッダーやフッターにはcolspanを使い、本文とサイドバーを2カラムで構成していた。
当時よく使われていたtableレイアウトの典型例
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td colspan="2" bgcolor="#cccccc">
<!-- ヘッダー -->
<h1>サイトタイトル</h1>
</td>
</tr>
<tr>
<td width="200" valign="top" bgcolor="#eeeeee">
<!-- サイドバー -->
<p>ナビゲーション</p>
</td>
<td valign="top">
<!-- メインコンテンツ -->
<p>本文エリア</p>
</td>
</tr>
<tr>
<td colspan="2" bgcolor="#cccccc">
<!-- フッター -->
<p>© 2003 Example Inc.</p>
</td>
</tr>
</table>このように、表組みで全体構造を実現するという考え方は当時の標準であり、レイアウトという概念そのものがまだHTMLに深く結びついていた時代だった。
CSSの登場と期待、でもまだ自由じゃなかった
HTMLだけでページの構造も装飾もすべて管理していた時代に、スタイルを外部に切り出せるCSSはまさに画期的な技術だった。文字の色やサイズ、背景色、余白の調整などをCSSで一元管理できるようになったことで、コードの見通しも良くなり、再利用性も高まった。
多くの制作者が、「これでtableレイアウトから解放される」と感じたはずだ。しかし、CSSの黎明期は装飾の制御こそ得意でも、レイアウト全体を自在に組むには機能が不十分だった。特に複数カラムの構成やブロック要素の並列表示にはまだ課題が多く、結局のところtableレイアウトから完全に脱却できないサイトも多かった。
さらに、ブラウザによる解釈の違いが大きく、同じCSSでも表示結果が異なることが頻発した。制作者たちはスタイルの調整を行うたびに、複数ブラウザで表示を確認しながら、微調整を重ねていく必要があった。
CSSの可能性には大きな期待が寄せられていたが、当初はまだ、レイアウトの主役というには頼りない存在だったのが正直なところである。
float登場で段落ち地獄のはじまり
CSSでのレイアウトが本格的に模索されはじめた頃、多くの制作者が注目したのがfloatだった。もともと画像の回り込み用に設計されたプロパティだったが、これをブロック要素に適用することで、CSSだけで横並びのレイアウトが実現できるように思えた。
tableタグを使わずにレイアウトが組めるというのは、それまでの苦労を思えば革命的だったが、実際に運用すると多くの問題に直面することになる。なかでもやっかいだったのが、ちょっとした幅の計算ミスや余白のズレで要素が下に落ちる「段落ち」という現象だった。
「float:left」を指定して2カラムにしようとしても、幅の合計が親要素を少しでも超えると下に回り込む。しかも当時のブラウザでは、要素のpaddingやborderが幅に含まれるかどうかが曖昧で、意図したとおりに並ばないことが多かった。
この頃のCSSにはまだbox-sizingという便利な仕組みもなく、デフォルトではpaddingやborderを含まない「content-box」で幅が計算されるため、見た目と実際のサイズがズレやすかった。制作者たちは1px単位で微調整しながら、どうにか横並びを成立させようと苦労していた。
paddingで落ちるwidthの罠
floatで横並びレイアウトを組もうとしたとき、一番やっかいだったのがpaddingやborderが幅に含まれないというCSSの仕様。当時のルールでは、要素の「幅」は中身だけを対象に計算されていて、paddingやborderはあとから“追加”される扱いだった。
たとえば、左右50%ずつにしたい要素にpaddingを足すと、その分だけ全体の幅が100%をオーバーして、意図せず下に回り込んでしまう(=段落ち)。見た目ではぴったり並んでいるように見えても、1pxでもオーバーしていれば、レイアウトは容赦なく崩れる……算数できないと泣きます。
これを防ぐには、paddingやborderの分を自分で引いてwidthを調整するか、pxでガチガチに固定するしかなかった。でも、それってものすごく面倒だし、保守性も悪い。しかも、ブラウザによって解釈がズレるので、環境ごとにレイアウトが違って見えるなんてこともよくある話。
「見た目どおりに並ばない」「1pxずれて落ちる」そんなトラブルは、floatレイアウトでは日常茶飯事の世界。
IEだけレイアウトが崩れるfloat地獄のエンドレス
floatを使って要素を横並びにすると、今度は親要素の高さがゼロになるという新たな問題に悩まされるようになる。子要素を全部floatで指定すると、親が「中身がない」と判断されて、背景が消えたり、下の要素がせり上がってきたりで、レイアウトが一気に崩れる。
この高さゼロ問題に立ち向かうために登場したのがclearfix。空の要素を入れてclear: both;をかけたり、擬似要素:afterでブロックの終わりをマークしたりと、さまざまなやり方が試された。
それでも、当時のIE(特にIE6〜7)はそう簡単には言うことを聞いてくれない。clearfixが効かない、そもそも擬似要素が認識されない、表示がバグる…というトラブルは日常茶飯事!
そこで使われたのが、IEだけにCSSを分けて読み込む条件付きコメントや、* html や _padding といったIE特有のハック記法。きれいなスタイルシートの下に、IE用の裏コードがずらっと並ぶのはよくある光景だった。ウェブ業界のツワモノたちが次々とIE対策を編み出したものだ。僕もこの頃はどれだけ助けられたことか…(笑)
floatを使えばレイアウトは柔軟になる…はずだったのに、崩れたらとりあえずclearfix、効かなきゃIE対策。
そんな、出口の見えないfloat地獄ループに、多くの制作者がずっと足を取られていた。
floatはレイアウト用じゃなく画像の回り込みが本職
CSSにfloatが登場した当初、よく紹介されていたのは画像や短い要素を左右に寄せて、文章を回り込ませるという使い方。たとえば、新聞や雑誌の記事のように、写真を左に置いて、その右側に本文が自然に流れ込むようなレイアウトがfloat本来の役割に近いかな(W3Cではそういう認識:以下参照)。
“The ‘float’ property specifies whether a box should float to the left, right, or not at all. It may be set for any element, but only applies to elements that generate boxes that are not absolutely positioned.A floating box is positioned within the current line box. It is shifted to the left or right until it touches the containing block edge or another float. Inline content flows around the floated element.”
公式仕様ページ(W3C) – CSS 2.1 §9.5
けど、当時のCSSにはflexもgridもなく、ブロック要素を横並びにする明確な手段がなかったから、floatで横並びが「なんとなくできそう」ってことで、カラム構成やメインコンテンツの並列配置に使われたってこと。手段がなかったんだから仕方ないよね・・・(笑)
段落ち、親の高さゼロ、clearfix、IEバグ……数々のfloatの副作用に悩まされながらもみんなが使っていたっていうのが事実だけど、それは、本来の想定を超えた使い方だったとも言えるかな。
今のウェブ制作では、flexやgridといった様々なレイアウトの方法がある。floatは、画像や装飾的な要素を回り込ませたいときに使うのがちょうどいい。私も、今では画像の横に説明文を添えたいときなどに使う程度。苦労して無理やりレイアウトを組んでいたあの頃はかなりつらい時期だったけど、ま、それが今の私を作った土台にもなってるのかも・・・。
まとめ:CSSレイアウトの前夜にいたウェブ業界
HTMLやCSSに今のようなレイアウト機能がなかった時代、ウェブ業界は限られた手段の中でなんとか見た目を整える工夫を続けていた。段組を組むためにtableタグを使い、横並びを実現するためにfloatを無理やりレイアウトに転用し、崩れたらclearfixで直し、IEだけズレたらハックで対応する。そんな時代だった。
今となっては非効率で遠回りなやり方にも見えるけれど、そうした時代があったからこそ、今のflexやgridのありがたみが実感できるとも言える。ウェブ業界が試行錯誤の中で積み重ねてきたノウハウは、今もどこかに受け継がれている。
次回は、そんな混沌の時代を経て、ようやく登場する“現代的なCSSレイアウトの幕開け”、flexboxの話へと続いていく。
ウェブ今昔物語シリーズ
ウェブ今昔物語 第1話 HTML構造とブロックエディタの進化をめぐる編
ウェブ今昔物語 第2話 ガラケー時代の奇妙な冒険編

