汎用性の高い横並びdlリストを作る

例えば企業サイトのニュースリリースなどにはテーブル要素を使用していました。
しかしここ最近、dl要素を使用することが主流になってきました。
そこでdl要素を用いた場合のカスタマイズ方法を紹介します。

dlを用いて横並びリストを作成する最大の問題点は、IE6においてdt要素の高さよりはみ出したdd要素内の段は3pxほど左にずれるというバグです。一応、dd要素にIE独自のプロパティ「zoom:1;」を指定するとバグが直るというハックがあるのですが、それだけではデザインを自由に変えるのが難しい場合があります。

例えば、以下の記事の最後で紹介している「dt, ddを通してborderを入れる」というデザインにしたい場合、dd要素に「zoom:1;」を指定すると3pxのずれは直るのですが、意図したとおりに線を入れることができません。

CSS - dtをfloatする場合の注意点 | Try | d-spica

そこで、どんなデザインでも応用が効くように、HTMLファイルの構造を一部変更してみることにします。

<dl class="list">
   <dt><span>2008-05-14</span></dt>
   <dd>
      <div>
         あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんあいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんあいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん<br />
      </div>
   </dd>
   <dt><span>2008-05-14</span></dt>
   <dd>
      <div>
         あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん<br />
         あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん<br />
         あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん<br />
      </div>
   </dd>
</dl>

dt要素直下にはインライン要素の「span」、dd要素直下にはブロック要素の「div」を入れてみました。

spanおよびdiv要素は、ブラウザの初期設定にはdisplayプロパティしか指定されておらず、カスタマイズが容易なために選択しました。

dt要素にspanを選んだのは、dt要素には日付など一行程度のテキストしか入らないことを想定しています。またdd要素にdivを選んだのはIE6のバグ対応と、dd要素内にpタグなど自由にマークアップできるようにするためです。複雑なカスタマイズにしないのであればpタグは不要です。

続いてCSSを書きます。最低限のCSSの設定は以下のとおりです。

* html body dl.list dd div{
   display:inline-block;
}

dl.list dt {
   float:left;
   width:10em;
}

dl.list dd {
   margin-left:0;
   padding-left:10em;
}

dt要素、つまりリストの左側は必ず横幅を設定しておきましょう。そうでなければ、テキスト量が多い場合、dd要素内のテキストとかぶってしまう場合があるからです。

dd要素の位置は、「padding-left」あるいは「margin-left」で指定します。どちらを使用するかはデザインをどのようにするかに依存します。また、dt要素よりも大きい値を指定しないと、テキストがかぶってしまう場合があります。

IE6のバグ回避用に、IE6しか適用されない「* html body」ハックを使用して、「zoom:1;」あるいは「display:inline-block;」を指定します。IE6しか適用しないようにするのは、他のブラウザで意図しない動作をするのを防ぐためです。

なぜ、「zoom:1;」あるいは「display:inline-block;」でIE6における‐3pxのバグが解消されるかというと、少し難しい話になるのですが、要はhasLayoutがtrueになり、レイアウト情報が保持されるためです。

hasLayoutに関しては以下のサイトが参考になります。

ウノウラボ Unoh Labs:hasLayoutとは何か

そして、hasLayoutをtrueにするためのトリガーとして、ここで紹介している「zoom:1;」あるいは「display:inline-block;」があります。

ちなみに、「zoom:1;」は拡大を指定するプロパティでIE独自のものです。そのため、ソースコードチェッカーではエラーが出る場合があります。値を1にしておけば、拡大されて表示されることはありません。

また、「inline-block」は、指定した要素をinline-blockボックスとして表示できるものです。inline-blockというのは、インライン要素でありながらブロック的な動作をするというもの。例えば、今まで段組(カラム)はfloatを使用して回り込みをしていたと思うのですが、floatの代わりにinline-blockを使用することにより、横並びになるというわけです。

少しややこしい話をすると、IE5以降においてinline-blockをdisplayプロパティに指定すると、hasLayoutをtrueにするだけで、display の値は変わらないようです。つまり、block要素に「display:inline-block」を指定しても、値は「inline-block」ではなく「block」のままであるということ。

div要素はブロック要素なのでdisplayの値は変化せずブロック要素のままで、レイアウト崩れは起きず、ただhasLayoutがtrueになりレイアウト情報が保持され、謎の‐3pxのバグが解消されるというわけです。

IEにおけるinline-blockについては以下のサイトを参考にしました。ありがとうございます。

IE 6, IE 7 の inline-block 考察 | ヨモツネット

カスタマイズ

長い長い前置きがありましたが、ようやく本題です。

dt要素内にspan、dd要素内にdivをマークアップすることにより、より柔軟なデザインにすることができました。dlリストのデザインを考えてみましょう。

以下で示すサンプルjは、Windows XPのFirefox2.0.0.14、Opera9.25、IE6、Safari3.1およびWindows VistaのIE7で動作確認済みで、どのブラウザでも見た目にほとんど差異はありませんでした。

テーブルの枠組みタイプ

それぞれの要素を線で囲んでテーブルみたいに見せてみましょう。

2008-05-14
あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんあいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんあいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん
2008-05-14
あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん
あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん
あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん
* html body dl.list dd div{
   display:inline-block;
}

dl.list {
   border:1px solid #999;
   border-top:0;
   background:#f1f1f1;
}

dl.list dt {
   float:left;
   width:10em;
   border-top:1px solid #999;
   padding-top:10px;
   padding-left:10px;
   padding-bottom:0;
   padding-right:0;
}

dl.list dd {
   margin-left:10em;
   padding:10px;
   border-top:1px solid #999;
   border-left:1px solid #999;
   background:#ffefff;
}

横線タイプ

dt部分(左側)とdd部分(右側)が横線でつながったように見せてみましょう。

2008-05-14
あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんあいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんあいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん
2008-05-14
あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん
あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん
あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん
* html body dl.list dd div{
   display:inline-block;
}

dl.list {
   border-bottom:1px solid #999;
}

dl.list dt {
   float:left;
   width:10em;
   border-top:1px solid #999;
   padding-top:10px;
   padding-bottom:0;
   padding-right:0;
}

dl.list dd {
   margin-left:10em;
   padding-top:10px;
   padding-bottom:10px;
   padding-right:10px;
   border-top:1px solid #999;
}

日付にワンポイントタイプ(1)

dt部分(左側)の日付にアクセントを加えてみましょう。

2008-05-14
あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんあいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんあいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん
2008-05-14
あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん
あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん
あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん
* html body dl.list dd div{
   display:inline-block;
}

dl.list {
   border-bottom:1px solid #999;
}

dl.list dt {
   float:left;
   width:10em;
   border-top:1px solid #999;
   padding-top:10px;
   padding-bottom:0;
   padding-right:0;
}

dl.list dd {
   margin-left:10em;
   padding-top:10px;
   padding-bottom:10px;
   padding-right:10px;
   border-top:1px solid #999;
}

日付にワンポイントタイプ(2)

dt部分(左側)の日付にアクセントを加えてみましょう。

2008-05-14
あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんあいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんあいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん
2008-05-14
あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん
あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん
あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん
* html body dl.list dd div{
   display:inline-block;
}

dl.list dt {
   float:left;
   width:10em;
   padding-top:10px;
   padding-bottom:0;
   padding-right:0;
}

dl.list dt span{
   position:relative;
   border-bottom:3px double #bf0f0b;
}

dl.list dd {
   margin-left:10em;
   padding-top:10px;
   padding-bottom:10px;
   padding-right:10px;
}

ここで気をつけないといけないのは、IE6において、高さが指定された要素内にあるインライン要素にpaddingやborderが指定されているとき、親要素をはみ出している部分が消えてしまう、という現象が起きることです。以下のサイトあるように、「position:relative;」を指定して、バグを回避します。

Internet Explorer (Windows) CSSバグリスト

[余談]別にテーブルを使っていけないわけでない。

ここ最近の傾向として、「できるだけテーブルタグは使わないようにしよう」っていう風潮があるようですが、そんなことはないです。問題なのは、そのマークアップの意味です。

セマンティック的観点(コンピューターが情報を得やすい形式であるかどうか)から言えば、例えばニュースリリースも「更新時間」という行と「内容」という列を持ったテーブルであるとも言えます。

タグを使用するのは、そのサイトを見ている人というよりも、コンピュータのためにあります。そういう意味ではマークアップは非常に難しいですね><

投稿日:2008年5月17日

トラックバック歓迎です。以下URLにて登録をお願いいたします。

このエントリーのトラックバックURL:

↓↓↓トラックバックしてくださった方々↓↓↓
※トラックバックされても管理人がスパムと判断したものは公開されません。

top