そらのうきぶくろ

Blog - Permalink

CSSでcounter機能を使ってみよう!

こんな機能があったなんて知らなかった。便利過ぎて発狂しそう。
というわけで使い方を書いてみることにしたんだ。

※Internet Explorer 8.0ではsection要素を使っている表示例が崩れます。FirefoxやOpera、Google Chromeの最新バージョンを利用してください。

●最も単純な使い方

まず順番付きリスト(ol)と同じような見た目になるようにしてみる。

HTML:

<ol>
	<li>項目1</li>
	<li>項目2</li>
	<li>項目3</li>
</ol>
<ol>
	<li>項目2-1</li>
	<li>項目2-2</li>
	<li>項目2-3</li>
</ol>

CSS:

		ol{
			counter-reset: item;
		}
		li{
			list-style-type: none;
		}
		li:before{
			counter-increment: item;
			content: counter(item) ". ";
		}

表示例
list-style-type: none;によって、liタグのマーカーを削除しているにも関わらず、正常に番号が表示されている。
:before疑似要素のcontentプロパティによって、マーカー代わりとなる文字列が付加されているのだ。

カウンタ用の数値はどこから来ているかというと。
プログラミングを少しでもかじった人なら分かりやすいのではないだろうか。
上の例では、まずol要素が登場した時点でcounter-resetによって変数itemを定義し同時に値の初期化を行っている。
次に、counter-incrementで指定した変数の値を1増やす。
あとはその変数の値を、contentプロパティで表示させている。
counter-incrementはli要素が出現するたびに毎回呼び出されるので、カウントが順番に増えていくように見える。
また、ol要素が登場するたびにcounter-resetで値を初期化しているので、ol要素を複数使っていても安心というわけ。

●章番号を振る

上の例だと何の小細工も使わずにただol要素を使えばいいわけだけど、counter機能の本気はここから。
文書内で、1-1, 1-2, 1-3, … 2-1, 2-2, 2-3, …のような形の章番号を自動で振ってみることにしよう。
ol要素を普通に使っているとこのような表記はできない。

HTML:

<ol>
	<li>項目1</li>
	<li>項目2
		<ol>
			<li>項目2-1</li>
			<li>項目2-2</li>
			<li>項目2-3</li>
		</ol>
	</li>
	<li>項目3
		<ol>
			<li>項目3-1</li>
			<li>項目3-2</li>
			<li>項目3-3</li>
		</ol>
	</li>
</ol>

CSS:

		ol{
			counter-reset: item;
		}
		li{
			list-style-type: none;
		}
		ol li:before{
			counter-increment: item;
			content: counter(item) ". ";
		}
		ol ol{
			counter-reset: subitem;
		}
		li li:before{
			counter-increment: subitem;
			content: counter(item) "-" counter(subitem) ". ";
		}

表示例
もう一つのカウンタを利用した手法。
リストの子要素になっているリストには、更にsubitemという別のカウンタ変数を使うようにする。
そしてマーカー代わりとなる文字列には、親リストのカウンタ変数と子リストのカウンタ変数の値をハイフンで繋げたものを設定している。

でもこの方法だと子リストが増えていくたびに新しい変数を用意しなければならず面倒である。
実はこの場合はもっと簡単な書き方があるのだ。

HTML:

<ol>
	<li>項目1</li>
	<li>項目2
		<ol>
			<li>項目2-1</li>
			<li>項目2-2</li>
			<li>項目2-3</li>
		</ol>
	</li>
	<li>項目3
		<ol>
			<li>項目3-1</li>
			<li>項目3-2
				<ol>
					<li>項目3-2-1</li>
					<li>項目3-2-2</li>
					<li>項目3-2-3</li>
				</ol>
			</li>
			<li>項目3-3</li>
		</ol>
	</li>
</ol>

CSS:

		ol{
			counter-reset: item;
		}
		li{
			list-style-type: none;
		}
		li:before{
			counter-increment: item;
			content: counters(item, "-") ". ";
		}

表示例
countersを使う事でこんなに簡単に表すことができるのだ。もちろん子リストが沢山あっても大丈夫。
counters関数は、要素が入れ子の関係になっている場合に同名の変数を指定した文字列で区切って順番に出力するという機能を持つ。
上の例だと、itemは変数名、ダブルクォーテーションで囲まれたが区切り文字ということになる。

●応用 – 目次と本文中の見出しの章番号を同期

HTML5には、新たにセクションをグループ化するsection要素というものが追加された。
これを使うと、目次の章番号と本文の見出しの章番号を簡単に合わせることができる。

HTML:

<ol>
	<li>はじめに</li>
	<li>なんちゃらうにゃうにゃ
		<ol>
			<li>ぴよぴよ</li>
			<li>ぽっぽ
				<ol>
					<li>くるっぽー</li>
					<li>ちゅんちゅん</li>
				</ol>
			</li>
			<li>ぴいぽっぽ</li>
		</ol>
	</li>
	<li>おわりに</li>
</ol>

<section>
	<h1>はじめに</h1>
	<p>本文A</p>
</section>
<section>
	<h1>なんちゃらうにゃうにゃ</h1>
	<p>本文A</p>
	<section>
		<h1>ぴよぴよ</h1>
		<p>本文B</p>
	</section>
	<section>
		<h1>ぽっぽ</h1>
		<p>本文B</p>
		<section>
			<h1>くるっぽー</h1>
			<p>本文C</p>
		</section>
		<section>
			<h1>ちゅんちゅん</h1>
			<p>本文C</p>
		</section>
	</section>
	<section>
	<h1>ぴいぽっぽ</h1>
	<p>本文B</p>
	</section>
</section>
<section>
	<h1>おわりに</h1>
	<p>本文A</p>
</section>

CSS:

		ol{
			counter-reset: index;
		}
		li{
			list-style-type: none;
		}
		li:before{
			counter-increment: index;
			content: counters(index, "-") ". ";
		}
		
		body{
			counter-reset: heading;
		}
		
		body>section>h1{
			counter-reset: heading2;
		}
		body>section>h1:before{
			counter-increment: heading;
			content: counter(heading) ". ";
		}
		body>section>section>h1{
			counter-reset: heading3;
		}
		body>section>section>h1:before{
			counter-increment: heading2;
			content: counter(heading) "-" counter(heading2) ". ";
		}
		body>section>section>section>h1:before{
			counter-increment: heading3;
			content: counter(heading) "-" counter(heading2) "-" counter(heading3) ". ";
		}
		
		section{
			margin-left: 2em;
		}

表示例
本文中には章番号を一切書いていないにも関わらず、目次通りの章番号が本文の見出しにも付いている。
これなら後から新たに章を追加する場合でも、他の見出しの文字列を修正する作業なんかが一切不要になる。便利でしょう?
ちなみにこういう場合は残念ながら見出しの方にはcounters関数を使う事ができない。

●応用 – 表番号・図番号

レポートか何かに表番号や図番号を振るのだって簡単だよ!

HTML:

<ol>
	<li>はじめに</li>
	<li>なんちゃらうにゃうにゃ</li>
	<li>おわりに</li>
</ol>

<section>
	<h1>はじめに</h1>
	<p>本文A</p>
	<table summary="適当な表">
		<thead>
			<caption>適当な表</caption>
		</thead>
		<tbody>
			<tr>
				<th>項目A</th><th>項目B</th><th>項目C</th>
			</tr>
			<tr>
				<td>1</td><td>2</td><td>3</td>
			</td>
		</tbody>
	</table>
</section>
<section>
	<h1>なんちゃらうにゃうにゃ</h1>
	<p>本文A</p>
	<div class="image">
		<img alt="マリルリさん" src="./test.png">
		<div>マリルリさん</div>
	</div>
	<p>本文A</p>
	<div class="image">
		<img alt="マリルリさん" src="./test.png">
		<div>マリルリさん</div>
	</div>
</section>
<section>
	<h1>おわりに</h1>
	<p>本文A</p>
	<div class="image">
		<img alt="マリルリさん" src="./test.png">
		<div>マリルリさん</div>
	</div>
	<p>本文A</p>
	<table summary="適当な表">
		<thead>
			<caption>適当な表</caption>
		</thead>
		<tbody>
			<tr>
				<th>項目A</th><th>項目B</th><th>項目C</th>
			</tr>
			<tr>
				<td>1</td><td>2</td><td>3</td>
			</td>
		</tbody>
	</table>
</section>

CSS:

		ol{
			counter-reset: index;
		}
		li{
			list-style-type: none;
		}
		li:before{
			counter-increment: index;
			content: counters(index, "-") ". ";
		}
		
		body{
			counter-reset: heading image table;
		}
		body>section>h1:before{
			counter-increment: heading;
			content: counter(heading) ". ";
		}
		
		div.image div:before{
			counter-increment: image;
			content: "画像" counter(image) ". ";
			font-weight: bold;
		}
		table caption:before{
			counter-increment: table;
			content: "表" counter(table) ". ";
			font-weight: bold;
		}
		table{
			border-collapse: collapse;
		}
		td, th{
			border: 1px solid black;
			padding: 6px;
		}

表示例
複数のカウンタを一度に初期化したい場合は、

		body{
			counter-reset: heading image table;
		}

このようにスペースで区切ればOK。
なんて簡単なんでしょう。

というわけで楽しいcounterライフを。

コンピュータのお話 | 君はコメントしてもいいししなくても良い

CSSでcounter機能を使ってみよう!へのコメント (0)

コメントを書く


You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>