デザインのあれやこれ
HTML5:セマンティックなセクショニング【後編】
HTML5で提唱される『セマンティックなマークアップ』は、要素の持つ意味や役割を定義するだけでなく、文書構造としての『アウトライン』も生成します。両者は関連性が深いので、まとめて『セマンティックなセクショニング』と称して、構造的なHTML文書の作成とその手法について紹介します。
前記事の続きになります。
HTML5アウトラインの構造
HTML5で生成されるアウトラインは、前編の例を引用すると下記のような階層構造になっています。
1.Watashi-Photo
1.メインメニュー
2.Photo
1.フォトグラファーWatashi
2.所属グループ
3.ご注意事項
4.Album
丁度、本の目次のような形になっているので、本の目次をイメージするとわかりやすいんじゃないかって思います。
まず最初に『Watashi-Photo』という大枠があり、これがHTMLアウトラインの最上階層のタイトルとなります。これをセクショニングルートと呼びます。
『Watashi-Photo』というセクショニング・ルートの中に、複数の下層セクションが存在します。この場合『メインメニュー』『Photo』という2つの階層、本でいえば1章・2章があります。
更に、『Photo』セクションの中には4つのセクションがあります。『Photo』が章であれば、その中のセクションは中見出しのようなものにあたります。(後述しますが、この場合『メインメニュー』はアウトラインとしては例外的な要素になります)
このように、ルートとなるセクションの中に複数のセクションを持ち、子セクション・孫セクション…と無数に連ねることができる階層構造になります。
殆どのサイトの場合、まずサイト名があり、その中に記事固有タイトルを持つ構造になるんじゃないかと思います。ブログサイトの場合、まずブログタイトルがあり、その中に記事が複数並んでいる感じですね。
1.Watashi-Blog
1.メインメニュー
2.撮影旅行に最適なバッグの選び方
1.大きいと大変!
2.目的に合ったサイズを使い分ける
3.私が持っているバッグの紹介
3.雨が降った時の私の対処法
1.…
4.私のおすすめレンズ
1.…
この場合、セクショニング・ルートは本屋さんのようなイメージになります。
セクショニング・ルートに本屋さんの名前(サイトタイトル)、下層の2〜4が本の名前(記事タイトル)、更に下層が各本の章(記事のセクション)という構成です。『メインメニュー』はお店の商品案内板みたいな役割ですね。
実際のHTML構文の組み立て方
では実際に、セマンティックなマークアップを意識したHTMLの書き方です。
<body>
<h1>Watashi-Blog</h1>
<nav>
<h1>メインメニュー</h1>
<ul>
<li>撮影旅行に最適なバッグの選び方</li>
<li>雨が降った時の私の対処法</li>
<li>私のおすすめレンズ</li>
</ul>
</nav>
<article>
<h1>撮影旅行に最適なバッグの選び方</h1>
<section>
<h1>大きいと大変!</h1>
(※省略)
</section>
<section>
<h1>目的に合ったサイズを使い分ける</h1>
(※省略)
</section>
<section>
<h1>私が持っているバッグの紹介</h1>
(※省略)
</section>
</article>
<article>
<h1>雨が降った時の私の対処法</h1>
<section>
(※省略)
</section
</article>
<article>
<h1>私のおすすめレンズ</h1>
<section>
(※省略)
</section
</article>
</body>
この場合、まずbodyがセクショニング・ルート=最上層のセクションとなります。このルートとなるセクションにh1で『Watashi-Blog』とタイトルを付けます。
メインメニューはnavでマークアップします。navはページの主となるナビゲーション(※注:ナビゲーション全てをマークアップするものではありません)であることを示します。このnavによって、ルート下層に新たなセクションが作られます。
(後述しますが、このbodyとnavのタイトルは仕様上必須ではありません。省略しても良いのですが、あったほうがわかりやすいので望ましい、といったもののようですね)
次に、記事となる部分をarticleでマークアップします。複数記事ある場合は、1つ1つをarticleで括ります。article直下にh1で記事タイトルを付けます。このarticleによって、先程のnavと同じ階層に新たなセクションが作られます。
記事の中の章にあたる部分をsectionでマークアップします。section内でもh1で見出しを付けます。このsectionは、articleの下層に新たなセクションを作り出します。
記事が複数ある場合は、先のarticleを終了させた後に新たなarticleを記述していきます。
各セクションにはheadingによるタイトルが必要
各セクションには、見出しとなるタイトルが必ず必要となります。セクション内で最初に登場したh1〜h6等のheading要素がそのセクションのタイトルとなりますサンプルのようにh1でなければいけないということは無く、h1〜h6どれを使っても大丈夫ですが、後述の暗黙的なセクショニングがある為、セクションのタイトルはh1で指定するのが良いでしょう。
また、bodyとnavもセクションにあたるのですが、仕様上これにはタイトルは必須ではありません。しかし省略してしまった場合、下記のように『Untitled Section』=名無しの不明なセクション、として捉えられてしまうので、特別な理由が無ければきちんとタイトルを付けてあげた方が良いでしょう。
1.Untitled Section
1.Untitled Nav
2.撮影旅行に最適なバッグの選び方
1.大きいと大変!
2.目的に合ったサイズを使い分ける
3.私が持っているバッグの紹介
3.雨が降った時の私の対処法
1.…
4.私のおすすめレンズ
明示的なセクショニングと暗黙的なセクショニング
ここがちょっと複雑で厄介なところです。
前述のように、article,nav,sectionは新しいセクションを現在の階層の下に生成します。『sectionが出てきた=新しいセクションになる』『/sectionが出てきた=今までのセクションが終わる』のように明示的ではっきりわかるので、これらを明示的なセクショニングと呼びます。
これに対し、暗黙的なセクショニングという要素が存在します。
h1〜h6のheading要素は、階層内の最初に出てきたheading要素を除き、先に出てきたheading要素と重さを比較して、暗黙的にセクションを生成します。
下記は、一番わかりやすいと思われるheading要素の暗黙的なセクショニング例です。
<body>
<h1>Watashi-Blog</h1>
<h2>撮影旅行に最適なバッグの選び方</h2>
<h3>大きいと大変!</h3>
<h3>目的に合ったサイズを使い分ける</h3>
<h3>私が持っているバッグの紹介</h3>
<h2>雨が降った時の私の対処法</h2>
<h2>私のおすすめレンズ</h2>
</body>
この場合の各headingの働きを見てみましょう。
まずh1は、セクショニング・ルートとなるbodyの一番最初に出てきたheading要素です。これは新たなセクションを生成することはなく、セクショニング・ルートのタイトルとなります。
続いてh2は、これより先に出てきたh1と重さを比較した結果、下位のheading要素になります。これは、h1で命名されたセクション=bodyの下層に新しいセクションを生成します。
次にh3は、これも先に出てきたh2と比較して下位のheading要素になるので、h2で生成されたセクションの下層に新たなセクションを生成します。更に同じh3が続きますが、これは先のh3と比較すると同じ重さのheading要素になるので、先のh3で生成されたセクションと同一階層にセクションを生成します。暗黙的に先のセクションを閉じ、同階層に新たなセクションを作り出すのです。
次に、再び出てきたh2は、先のh3と比較して上位のheading要素になるので、現在より1つ上の階層に新たなセクションを生成します。先のh3セクションを閉じ、また先のh2のセクションも閉じて、それと同じ階層にセクションを作り出すのです。
articleやnav,sectionは始まりと終わりがはっきりとわかる(=明示的)ですが、heading要素はこのように新たなheading要素が出てきた時に暗黙的にセクションを作り出していきます。
これにより、section等のセクショニング要素を使わずにアウトラインを生成することもできます。下記の2つのHTMLソースは同じアウトラインを生成します。
<article>
<h1>撮影旅行に最適なバッグの選び方</h1>
<section>
<h1>大きいと大変!</h1>
(※省略)
</section>
<section>
<h1>目的に合ったサイズを使い分ける</h1>
(※省略)
</section>
<section>
<h1>私が持っているバッグの紹介</h1>
(※省略)
</section>
</article>
<article>
<h1>撮影旅行に最適なバッグの選び方</h1>
<div>
<h2>大きいと大変!</h2>
(※省略)
</div>
<div>
<h2>目的に合ったサイズを使い分ける</h2>
(※省略)
</div>
<div>
<h2>私が持っているバッグの紹介</h2>
(※省略)
</div>
</article>
この暗黙的なセクショニングのややこしい点を挙げていきます。
まず、明示的にセクショニングされた要素の中で最初に出てきたheading要素は、そのセクションのタイトルとして扱われるので、新たなセクションを作り出すことはありません。
また、先に出てきたheading要素と比較をして上位にあっても、明示的にセクショニングされた要素と同等以上の階層を生成することはありません。
これらはどういうことかというと、下記の例を見てみてください。
<article>
<section>
<h4>セクションタイトル</h4>
<h3>第1章</h3>
<h1>第2章</h1>
</section>
<h5>article title</h5>
<h6>new section title</h6>
<h3>新しいセクションタイトル</h3>
</article>
このHTMLソースのアウトラインは、実際にはこのようになります。
1.article title
1.セクションタイトル
2.第1章
3.第2章
4.new section title
2.新しいセクションタイトル
まず、articleによって最初のセクションが明示的に作られます。次のsectionによって、articleの中に下層セクションが明示的に作られます。
この次のh4は、sectionで作られたセクションの中で最初に出てきたheading要素として扱われるので、sectionのタイトルとして扱われます。
次のh3は、先のh4より上位のheading要素となるので、sectionで作られたセクションと同位のセクションを暗黙的に作り出します。
その次のh1は、先のh3より2段階上位のheading要素ですが、sectionによって明示的に作られたセクションより上位の階層は作らないので、先のsection,h3と同位のセクションを暗黙的に作り出します。
そしてsectionが閉じられた後のh5は、上層のarticle内で最初に出てきたheading要素として扱われ、これがarticleのタイトルとなります。
次のh6は、articleのタイトルとなるh5と比較して下位のheading要素なので、先のsectionと同位のセクションを暗黙的に作り出します。
最後のh3は、先のh6と比較して上位heading要素になるので、articleと同位のセクションを暗黙的に作り出します。
このように、heading要素による暗黙的なセクショニングはかなり複雑な計算になってしまいます。
単純な数字の比較だけではなく、要素の出てくる順番、またsection等で明示的にセクショニングされた要素を超えないという特性があるので、これが複雑化の原因となります。公開後に見出しを追加したり、sectionをdivに差し替えたりしたら、アウトラインの構成が大きく崩れてしまうという事ですね。
このような問題の回避策としては、まずheadingによる暗黙的なセクショニングは極力避け、section等で明示的にセクショニングを行うのが良いでしょう。
セクションのタイトル付けはh1から使用し、後のheadingによる暗黙的なセクショニングが発生しても、上位>下位の流れがはっきりわかる形にします。
cssの側でも、sectionやheading要素そのものにスタイルを付けることは避け(デザインやレイアウト目的でセクショニング要素を選択する形にならないようにする)、classによりスタイルを付ける形にするのが良いでしょう。
アウトラインから除外されるセクション
セクションとして定義はされても、アウトラインには属さない要素があります。
navとasideはセクションを生成しますが、メインのアウトラインには属さないという特性があります。
navは先の例でも出てきましたが、ナビゲーションメニューを意味します。また、asideはコラムや広告等を意味します。これらは『文書との関係性はあるが、決して本文の一部とはいえないので、本文構造には含めないもの』として扱われます。これらの要素はHTML5 Outliner等で見るとセクションとして表示されるので、アウトラインの一部のようにも見えますが、意味合いとしては『本文とは異なるスルー推奨の要素』として扱われます。前述の例で挙げた、navでマークアップされた『メインメニュー』はアウトライン上では例外的な要素になるというのはこういう意味だったんですね。
また、アウトラインから完全に除外される要素もあります。これを区分化ルートと呼びます。
例えばblockquoteは引用を表す要素ですが、これは『文書を補足する外部要素であり、本文とは全く異なるもの』なので、本文のアウトラインからは除外されます。HTML5 Outliner等で見ても表示されません。
セマンティックなセクショニングに関わるタグ
HTML5で新たに定義されたものも含め、セマンティックなセクショニング(要素の意味が明確で、階層的な構造を持つ)に関わるタグをまとめてみます。
セマンティックでなく、セクションも生成しないもの
div
これはdivision(境界・仕切り)の略です。
最初に挙げましたが、これはセマンティックなセクショニングを意識するうえでは『使用してはいけない』タグとなります。
この要素は意味合いを持たず、アウトラインも生成しません。HTML4まではこれが構造を組み立てる箱として使われてきましたが、HTML5では他に適したアウトライン生成タグがある場合はそちらを使用し、divは極力使用しないことが推奨されています。逆に、レイアウト等のデザイン目的で他のアウトライン生成タグを使用することは非推奨とされ、デザイン目的の場合はdivを使用することが推奨されています。divはデザイン・レイアウト用タグとして捉えて使用すると良いかもしれませんね。
セクションは生成しないがセマンティックな要素
header
headとは異なるもので、そのセクション内のヘッダー区画を示すタグです。article,section等のセクション中にheaderを持つことができ(必須ではありません)、articleなら記事タイトルやアイキャッチ画像、sectionなら章の見出しなどが該当します。
headerはセクショニング・コンテンツではなく、アウトラインは生成しません。セクション内のヘッダー部分を指し示すだけの役割です。
footer
そのセクション内のフッター区画を示すものです。奥付や著作権情報などがこれに該当します。headerと同じくarticle,section等の中にfooterを持つことができ、また必須要素でもなく、新たなセクションも生成しません。これらheaderとfooterは要素の意味を示すだけのもので、アウトラインには影響を及ぼしません。
アウトラインを生成するセマンティックな要素
body
そのHTMLページの大元となる最上位のセクション=セクショニング・ルートを生成する要素です。
厳密には、bodyはblockquote等と同じ区分化ルートで、これは『独自のアウトラインを持ち、それより祖先(上位)のアウトラインに影響を及ぼさない』独立したアウトラインとなるものです。bodyの場合はそのページの独自のアウトラインとなり、blockquoteはページ外の独自アウトラインとなります。
article
記事を示すタグで、グロナビやサイドバー・フッターなどを除いた、記事の本体にあたるものを指します。判断基準としては、この部分だけを抜き出しても完結する一つの文書・資料として成り立つものが該当します。
articleはセクショニング・コンテンツで、新たなアウトラインを生成します。headingによるタイトル指定が必要で、省略した場合はアウトライン上で『Untitled Section』と表示されます。
section
汎用的な1つの区切りを示すタグです。例えばarticle内の記事を章に区切る際に使用したり、aside内なら『広告』『関連リンク』などをsectionで分けて定義します。
sectionは1つの意味を持った区切りとされます。sectionで区切る範囲の判断基準としては、例えばarticle内の記事なら『第一章:○○について』『第二章:□□について』、aside内なら『広告』『関連リンク』といった具合で、見出し(heading)が付けられるものが該当します。段落のような区切りは、1つの意味を持った区切りとしては成立しないので、sectionとしては非該当になります。
articleと同じように、heading要素によるタイトル指定が必要です。(見出しを省略した場合、アウトライン上では『Untitled Section』として表示されてしまいます。)
aside
余談や補足といった、記事の本体以外のものを示します。関連する記事の紹介や、広告、サイドバーなどがこれに該当します。
asideはセクショニング・コンテンツで、アウトラインを生成しますが、navと同じく『本文に関わるが、本文の一部ではないもの』という意味を示し、除外対象として判断されます。asideもheader,footerを持てます。
asideはセクショニング・コンテンツですが、navと同じように本文の一部ではないものとして捉えられる為、headingによるタイトル指定は必須ではありません。
nav
navigationの略で、ページ内の主要なナビゲーションを定義します。ページ内の主要なもの、グローバルナビゲーションのみ定義すればよく、記事内のリンクや『次/前の記事』などには使用しません。footer内の会社情報やプライバシーポリシーなども非該当となります。
navはセクショニング・コンテンツで、新たなアウトラインを生成します。headingによるタイトル指定は必須ではありません。(省略した場合、アウトライン上では『Untitled NAV』と表示されます。)
navはアウトラインを生成しますが、『本文に関係するが、本文の一部ではないもの』という意味を示します。
navもheader,footerを持てます。nav内の『メインメニュー』といった見出しがheaderに該当します。
h1〜h6
headingの略で、見出し・タイトルを指定します。
これらはセクショニング・コンテンツではありませんが、暗黙的に新しいアウトラインを生成します。
アウトラインから除外される要素
blockquote
引用ブロックを示す要素です。引用を示すタグはqとblockquoteの2種類がありますが、前者は文章内に埋め込める程度の短い引用を示し、後者は見出しの付く数行に渡る長い引用や、複数の引用のブロックを示すのに使用します。
blockquoteの内容はheading要素やsection等でセクショニング・アウトラインを構築することができますが、それらは引用であり本文の一部ではないものとされ、本体のアウトラインからは除外・独立したアウトラインとなります。
figure
図表・挿絵の意味で、本文に関わるが、それが無くても本文に影響を与えないものを示します。
HTML5から新たに追加された要素で、下記ソースのようにimgを梱包する要素として使用します。
<figure>
<img src="image.jpg">
</figure>
HTML4まではimgはpで梱包していたのに対し、HTML5からはfigureで梱包する…というイメージを持たれるようですが、要素の持つ意味は上記のように『それが無くても本文に影響を与えないもの』で、挿絵やイメージ画像のようなものはfigureが該当しますが、その画像が無いと本文が成立しないようなものは従来通りpで梱包して記述するのが適しています。
この要素もblockquoteと同じく、独立したアウトラインを持ち、本文のアウトラインには影響を与えません。
fieldset
HTML5から新たに追加された要素で、form内の複数の要素をグループ化する際に使用します。
この要素も区分化ルートで、本文のアウトラインには影響を与えません。
その他、区分化ルートに該当する要素としてはdetailsとtdがありますが、これらの使用感はpのようなテキスト要素に近く、アウトラインの意識には関わりづらいと思うので、この場では省略します。
以上、かなり駆け足で端折ってしまった感がありますが、セマンティックなセクショニングとアウトライン(要素の意味が定義された区分けと文書の概要)について紹介してみました。
Webグラフィックデザインのような見た目に関わる要素ではないので、なにかと軽視されがち…というか、かなり複雑で面倒くさい内容なので疎遠にされることも多いんじゃないでしょうか。
しかし、そもそもアウトライン=構造の整っていない文書というのは潜在的に問題を抱えているのではないでしょうかね。
アウトラインの整っていない文章はとても読みづらいと感じます。書き手側としても、アウトラインが整っていない状態では非常に書きづらいと感じます。書きづらく、読みづらい、そんなページをWeb上に公開したところで、受け手はどのように感じ、書き手はどんな効果を得られるか?決して良い結果が得られるとは考えにくいです。
構造化により、ここはどうしようか…と迷うこと無く、どうマークアップすればよいかハッキリと答えが出ているのも良い点です。ぐにゃぐにゃと曲がって定まらなかった背骨がピシっと綺麗に伸びたような感覚がします。
かなり大変な(本当に大変で面倒な)要素ではありますが、自身の畑を耕すものだと思って、構造的でセマンティックなHTMLの構築と整ったアウトラインについて意識をしてみませんか?