CSSだけで「横並び」と「縦並び」を切り替え可能なテーブルを,dl・dd・dtタグで作ろう (table要素を使わない,変更しやすい表組みレイアウトの実装方法)
HTML上で表組みを実装する際には,table要素を使うのが一番手っ取り早い。
しかし,tableで作った表組みは,変更しづらい。(メンテ性がよくない)
例を挙げよう。
下記のように,「項目名」と「項目の説明」が横並びで並んだ表組みがあるとする。
この表組み内の全セルを,縦並びに変更したいとする。
table要素でレイアウトした場合,このような変更はしんどい。
HTMLソースを書きなおして,テーブルの全行を2行ずつに分割する必要がある。
この変更作業において,「文書の構造」は変わっていないつもりだ。(それを表現するのはHTMLのはず)
ただ単に「見せ方」を変えたいだけなのだ。(それを表現するのはCSSのはず)
にも関らず,HTMLソースを全部書き直さないといけない。
おかしいと思わないか?
実は,tableタグを使わず,「DL」タグを使って表組みを実装すれば,
上記のような変更はCSSをちょっと書き変えるだけで実現できる。
つまり,「縦並び」「横並び」を柔軟に切り替えできるような,
変更しやすい表組みレイアウトを実現できるのだ。
そうすれば,HTMLは,純粋に「文書の構造」だけを表す。
CSSは「見せ方」を自由に切り替えるために使う。
なので,table要素で表組みする際の矛盾を避けられる。
このような表組みを,DL・DT・DDタグを使って実現するためのサンプルコード集。
全部デモページ付き。
(1)DL・DT・DDタグで,横並びのテーブルレイアウトを作ろう
まず,DL・DT・DDタグの正体を知る。
これらの要素の,基本的な用途を押さえておこう。
- dl:Definition List。定義リスト
- dt:Definition Term。定義の用語
- dd:Definition Description。定義の詳細の意
HTML 定義リスト dl dt dd 要素
http://gstyle.gotostyle.net/?eid=1133804
- dl dt dd要素は、イメージとして辞書のような表現をするために使われます
ではこれらのタグを使って,tableと同じ表組みレイアウトをコーディングしてみる。
下記に,横並びのテーブルのサンプルコードを掲載。
マークアップの原理や仕組みは,ソースのコメントに全部記載してあるので参照のこと。
yoko.html
<html> <head> <title>dl, dt, dd でテーブルレイアウトをするテスト</title> </head> <body> <!-- スタイル --> <style> dl, dt, dd { margin : 0; padding : 0; } dl { /* dlの背景色をdt用に使う。区切り線はdtの上部に持たせる */ background-color : yellow; /* dlの上部線はなくし,dtとddの上部線をdlの上部線のように見せる */ border-width : 0 1 1 1; border-style : solid; border-color : black; width : 40%; } dt { float : left; clear : both; width : 150px; border-width : 1 0 0 0; /* 上線だけ */ border-style : solid; border-color : black; font-weight : bold; padding : 5px; } dd { /* dtの幅だけ横にずらしておく */ margin-left : 150px; /* dlやdtとは異なった背景色を用いる */ background-color : white; border-width : 1 0 0 1; /* 上線と,dt・ddの左右間の区切り */ border-style : solid; border-color : black; padding : 5px; } </style> <!-- 定義リスト --> <dl> <dt>Windows</dt> <dd> 米マイクロソフト社が開発したOS。<br> 全OSシェアの90%を占める,デファクトスタンダードのオペレーティングシステム。<br> (※<a href="http://news.mynavi.jp/news/2011/01/04/029/index.html">2010年末時点</a>) </dd> <dt>Mac</dt> <dd> 米アップル社が開発したOS。<br> 全OSシェアの5%を占める。(出典は同上)<br> しかし,デザイナーやクリエイティブ系の業務においてはMacは必需品であり,決して侮ってはいけない。<br> (※<a href="http://q.hatena.ne.jp/1137545476">参考</a>) </dd> <dt>その他</dt> <dd> 色々あるでよ </dd> </dl> </body> </html>
下記でデモを閲覧できる。
http://name-of-this-site.org/coding/c...
参考:
[使える CSS テクニック] CSS で DL を float して表組みのように表現する
http://c-brains.jp/blog/wsg/08/06/09-...
- 背景画像などを細かく指定すれば、グラフィカルな表現も可能
Dotted Leaders - using a DL list / Recipe for success
http://www.pmob.co.uk/search-this/lis...
- dtを右側に持ってきて,本の目次のように見せている面白いサンプル。dtに「right:-1px」としている。
(2)DL・DT・DDタグで,CSSをいじるだけで,縦並びのテーブルレイアウトに変えよう
前項では横並びのソースを掲載した。
そのソースのCSSを少し変えるだけで,縦並びにできる。
HTMLは一切,変更していないという点がポイント。
前述のソースからの変更点は,コメントアウトによって示してある。
CSS内で「どこが差分なのか」に着目しつつ,ソースを読まれたい。
そこを変更するだけで,タテとヨコが切り替わるのだ。
縦並びのテーブルレイアウトのサンプル:
tate.html
<html> <head> <title>dl, dt, dd でテーブルレイアウトをするテスト</title> </head> <body> <!-- スタイル --> <style> dl, dt, dd { margin : 0; padding : 0; } dl { /* dlの背景色をdt用に使う。区切り線はdtの上部に持たせる */ background-color : yellow; /* dlの上部線はなくし,dtとddの上部線をdlの上部線のように見せる */ border-width : 0 1 1 1; border-style : solid; border-color : black; width : 40%; } dt { /* float : left; */ /* clear : both; */ /* width : 150px; */ width : 100%; border-width : 1 0 0 0; /* 上線だけ */ border-style : solid; border-color : black; font-weight : bold; /* paddingを設定するとdtがdlの横幅をはみ出すので,かわりにindentを使う */ /* padding : 5px; */ text-indent : 5px; } dd { /* margin-left : 150px; */ /* dlやdtとは異なった背景色を用いる */ background-color : white; /* border-width : 1 0 0 1; */ border-width : 1 0 0 0; /* 上線だけ */ border-style : solid; border-color : black; padding : 5px; } </style> <!-- 定義リスト --> <dl> <dt>Windows</dt> <dd> 米マイクロソフト社が開発したOS。<br> 全OSシェアの90%を占める,デファクトスタンダードのオペレーティングシステム。<br> (※<a href="http://news.mynavi.jp/news/2011/01/04/029/index.html">2010年末時点</a>) </dd> <dt>Mac</dt> <dd> 米アップル社が開発したOS。<br> 全OSシェアの5%を占める。(出典は同上)<br> しかし,デザイナーやクリエイティブ系の業務においてはMacは必需品であり,決して侮ってはいけない。<br> (※<a href="http://q.hatena.ne.jp/1137545476">参考</a>) </dd> <dt>その他</dt> <dd> 色々あるでよ </dd> </dl> </body> </html>
下記でデモを閲覧できる。
http://name-of-this-site.org/coding/c...
このように,CSSだけでタテ・ヨコを切り替えられるといった点が,
DL要素を使ったテーブルレイアウトの持つ1つの利点だ。
このテクニックはクロスブラウザで利用可能。
※念のため動作確認したブラウザ:
- IE (8)
- Firefox (10.0)
- Chrome (17.0)
- Safari (5.1)
では,この方法の弱点・欠点は何か?
(3)DL・DT・DDタグで作成したテーブルレイアウトの限界
DTタグの縦幅が,DDタグの縦幅よりも長い場合,横並びテーブルレイアウトの表示が崩れる。
DTタグの縦幅が固定の場合は,heightなんかを決め打ちで設定する事によって対処可能。
だが,DTタグが任意の高さを取る場合,対処は不可能。
ためしに,ddよりもdtタグの高さが高いような行を一つ追加してみよう。
下記のコードでは,前述の「横並びテーブルレイアウト」のソースに
「Linux」について説明する行を追記しただけのコードである。
他は何も変えていない。
dtの内容を意図的に長く,ddの内容を意図的に短くしてある。
崩れる様子のサンプル:
kuzureru.html
<html> <head> <title>dl, dt, dd でテーブルレイアウトをするテスト</title> </head> <body> <!-- スタイル --> <style> dl, dt, dd { margin : 0; padding : 0; } dl { /* dlの背景色をdt用に使う。区切り線はdtの上部に持たせる */ background-color : yellow; /* dlの上部線はなくし,dtとddの上部線をdlの上部線のように見せる */ border-width : 0 1 1 1; border-style : solid; border-color : black; width : 40%; } dt { float : left; clear : both; width : 150px; border-width : 1 0 0 0; /* 上線だけ */ border-style : solid; border-color : black; font-weight : bold; padding : 5px; } dd { /* dtの幅だけ横にずらしておく */ margin-left : 150px; /* dlやdtとは異なった背景色を用いる */ background-color : white; border-width : 1 0 0 1; /* 上線と,dt・ddの左右間の区切り */ border-style : solid; border-color : black; padding : 5px; } </style> <!-- 定義リスト --> <dl> <dt>Windows</dt> <dd> 米マイクロソフト社が開発したOS。<br> 全OSシェアの90%を占める,デファクトスタンダードのオペレーティングシステム。<br> (※<a href="http://news.mynavi.jp/news/2011/01/04/029/index.html">2010年末時点</a>) </dd> <dt>Mac</dt> <dd> 米アップル社が開発したOS。<br> 全OSシェアの5%を占める。(出典は同上)<br> しかし,デザイナーやクリエイティブ系の業務においてはMacは必需品であり,決して侮ってはいけない。<br> (※<a href="http://q.hatena.ne.jp/1137545476">参考</a>) </dd> <!-- この項目を追加 --> <dt> Linux<br> <span style="color:green"> ※Linuxと一口に言っても種類が非常にたくさんあり,それらのOSをまとめてLinuxと呼称している。<br> また,言うまでもなく,この欄に記述される文章をこのようにしてあえて増やしている理由は, HTMLのDTタグの縦幅が大きい場合のDDタグの挙動をテストするためである。 </span> </dt> <dd> リーナス・トーバルズ氏がオープンソースで開発したOSのカーネルのことを指す。<br> 私はLinuxについての説明を見つけたが,このDDタグはそれを書くには余りにも狭すぎる (<a href="http://ansaikuropedia.org/wiki/%E9%A9%9A%E3%81%8F%E3%81%B9%E3%81%8D%E8%A8%BC%E6%98%8E%E3%82%92%E8%A6%8B%E3%81%A4%E3%81%91%E3%81%9F%E3%81%8C%E3%81%9D%E3%82%8C%E3%82%92%E6%9B%B8%E3%81%8F%E3%81%AB%E3%81%AF%E4%BD%99%E7%99%BD%E3%81%8C%E7%8B%AD%E3%81%99%E3%81%8E%E3%82%8B">※1</a>, <a href="http://www.geocities.jp/ikuro_kotaro/koramu/fermat.htm">※2</a>)。 よって割愛。 </dd> <dt>その他</dt> <dd> 色々あるでよ </dd> </dl> </body> </html>
下記のURLから,見え方を確認できる。
http://name-of-this-site.org/coding/c...
なお,IEとFirefoxでは,レイアウトの崩れ方が異なる点に注意しよう。
なぜ異なった崩れ方をするのか?という理由については,下記の情報が参考になる。
(2−3)要素内の高さ位置と,要素の高さ
http://language-and-engineering.hatenablog.jp/entry/20110216/p1
ブロック要素の高さは,要素内部の内容が大きいと,挙動がブラウザ依存になるので注意。
- IEでは,要素の内容が優先される。
- IE以外では,要素の高さが優先される。要素より大きな内容は要素からはみ出す。
この挙動から,DL/DT/DDタグが下記のような性質を持っているという事がわかる。
- dtよりもddの高さが優先される。
- ddの高さが決まってしまうと,dtがその高さを超えた際に,レイアウトが崩れる。
- tableのように,行内の左右のセルの間で,高さを相互に調節しあってくれない。
dtの方が高いと崩れる件についての参考:
dt、dd要素で表組みを作る
http://www.sriproot.net/blog/001work/...
- 「この方法でいいところは、dd要素に長い内容が入っても、しっかりと表組みのように見えてること。逆にdt要素に長い内容が入ると崩れてしまいますけど…。」
dlのdt dd を横並びに(2006年の情報)
http://css-happylife.com/archives/200...
- dtの方がテキスト量が多くなった場合、ボーダーが途切れたり
dtよりもddのほうが高さがある場合は,うまく解決できる。
http://www.sriproot.net/blog/sample/d...
dtの高さを決め打ちにすれば解決できるという件についての参考:
dtの方が高さが有る時のdt dd を横並び(2007年の情報)
http://css-happylife.com/archives/200...
- ddがテキスト量などで高さがdtより多い場合は問題が無いんだろうけど、dtの方が高さがある場合、IE7だと上手い具合に回り込みが解決されない
- dtの方が高さがある場合。っていうのは今回の場合は画像にdtが来て、ソレを定義付ける説明がちょろっとあるようなイメージ。
floatさせたdtの内容が多い場合、ddの背景と高さが合いません
http://oshiete.goo.ne.jp/qa/4711232.html
- ddよりもdtのほうが高い場合,dt側の高さが決め打ちなら,height系の属性で対処できる
両者の比較と結論
結論として,table要素とdl要素のそれぞれが一長一短である,という点がわかる。
table要素で表組みする場合:
- メリット:書くのは楽。全体のコード量も少ない。セルの高さを行内で調節してくれる。
- デメリット:変更がめんどい。HTMLの本来の役目から外れている。
dl要素で表組みする場合:
- メリット:見せ方をCSSで切り替えやすい。HTMLとCSSで分業できている。
- デメリット:全体のコード量が多い。データ側の高さが変わる分にはいいが,定義側の高さが変わると困る。
HTMLとCSSの分業は,確かに大切だ。
しかし,それにこだわり過ぎると,実務が進まない。
セマンティクスや理論に執着し過ぎたせいで,その労力の費用対効果がおかしくなる。
ビジネスは,成果物を出してナンボなのだ。
実際的に考えると,
dl要素によるレイアウトは,選択肢(武器)として持っていればよい。
tableを使えばもっと簡単なのに。
という場合,table要素の利用をためらう必要はない。
そしてtableによる「付け焼き刃レイアウト」は,実務ではある程度許容すべきだろう。
もちろん,下記のような「CSSの中級セオリー」を理解した上での事だ。
なんとなくCSSを使っている人が,CSS中級者になるために (「崩れないレイアウト」のセオリー)
http://language-and-engineering.hatenablog.jp/entry/20110216/p1
table要素による表組みは,文書の構造だけでなく,見え方まで固定してしまう。
clear:bothのためのdiv要素を利用するのと同じく,本来は避けたいコードだ。
だがしかし,それが効率的で一般的なテクニックである以上,生産性を重視したほうがいいかもしれない。