固定高さのボックス内に、テキスト上下センタリングで配置(複数行対応)したメニューを「縦並びで」作る

案件でこういうのが必要になって、コーダーから「出来ない」と報告を受けたけども「できるんちゃう」と思って実験したらできたのでメモ。
よくあるtable-cellを使うんやけども、縦並びなのはドンピシャな例が見つからなかったんで書いておきます。

デモ

» こちらから
コーポレートサイトの左右ナビに使いそうなやつです。

作り方

マークアップ方法です。display:table-cellを使います。

html

レイアウトのためとはいえ、(文書構造上)無意味なspanが入ってるのが気に食わんけど、どうしても外せんかったので無念。

<ul>
    <li><a href="#"><span>1行のパターン</span></a></li>
    <li><a href="#"><span>1行のパターン</span></a></li>
    <li><a href="#"><span>2行のパターン2行のパターン2行のパターン2行のパターン</span></a></li>
    <li><a href="#"><span>2行のパターン2行のパターン2行のパターン2行のパターン</span></a></li>
    <li>
        <ul>
            <li><a href="#"><span>よくある子階層がインデントしてるパターン</span></a></li>
            <li><a href="#"><span>よくある子階層がインデントしてるパターン</span></a></li>
        </ul>
    </li>
    <li><a href="#"><span>テキストがめっちゃ多くてボックスの高さを越える場合は成り行きで高くなりますテキストがめっちゃ多くてボックスの高さを越える場合は成り行きで高くなります</span></a></li>
</ul>

css

ul {
	width : 300px;
	margin : 0;
	padding : 0;
	}

ul li {
	display : table;
	width : 100%;
	border-bottom : 1px solid #ffffff;
	}
ul li ul li:last-child {
	border-bottom : none;
	}

ul li a {
	display : table;
	width : 100%;
	background-color : #666666;
	}
ul li ul li a {
	background-color : #888888;
	}

a:hover {
	background-color : #333333;
	}

ul li span {
	padding : 0 10px 0 25px;
	display : table-cell;
	vertical-align : middle;
	height : 50px;
	background : url(arrow.png) no-repeat 3px center;
	}
ul li ul li span {
	padding-left : 35px;
	background : url(arrow.png) no-repeat 18px center;
	}

今見たらspanの背景画像の記述が重複しててアホっぽいな。

要点

懐かしのテーブル組みの時に死ぬほどお世話になったvertical-align:middleを反映するためにcss3のdisplay:tableとtable-cellを使うわけですが。
li要素に直接table-cellを設定したら強制で横並びになるという現象が回避できませんでした。なので無駄にspanをかませて、それにtable-cellを適用しています。なんかもうちょっとシンプルにできるような気がしてならない。

ちなみにdisplay:table使うのでIE7以下は対応してませんが、こういうの使えば何とかなるかもしれません。
HTML5+CSS3で構築する際のIE9以下への対策

対応ブラウザ

  • Win 7 + chrome
  • Win 7 + Firefox
  • Win 7 + IE8以上
  • Mac + safari