SEO対策のためにHTMLのアウトラインと今一度真剣に向き合ってみた

デザイン部所属のフロントエンドエンジニア竹内美帆です。

アイスタイルでもSEO対策に色々な対策を講じています。
その中でもフロントエンドに関係するHTMLのアウトラインについて触れていきます。

SEO対策のためのHTML構造化

HTMLはそのページのコンテンツを適切な文書の役割、構造をつけることが理想としています。

アイスタイルのソースコードは長い年月を経て開発が行われており、いろんな人の思いがHTMLに込められています。
元々はきっときれいだった構造も、改修に改修を重ね、スタイルのためのdivやspan要素などが沢山ついたり、人によってHTML構造が違うため、何故ここにこのタグがとかよくあります。

すべてのHTMLを理想に直したいのはやまやまなのですが、時間がかかりすぎます。
SEO対策のためには、「HTMLのアウトラインをきちんとしたものにすることが重要」とのことと聞いたので、アウトラインをしっかり考え直すというところを企画、デザイナー含め検討しております。

今回の改修で出た問題点などの前にそもそもアウトラインって何なのか、どう実装すればよいのかを見ていきたいと思います。

アウトラインとは

アウトラインとは、HTML文書から見出し(h1~h6要素)だけを抜き出して、文書内のセクションとその階層を示したものです。

1. 見出しA
  1. 見出しB
  2. 見出しC
    1. 見出しD

アウトラインをチェックするには、下記のようなツールがあります。

  • headingsMap(Chrome版 / Firefox版
    ブラウザのアドオンです。section、artcle、nav、asideまで出してくれて便利です。
  • HTML5 Outliner
    ちょっとしたサンプルコードとかだったらこれで見たほうが早いです。これもアドオンあります。

アウトラインを形成する要素

章や節を表すセクション要素

HTML4.01など古いHTML仕様では、hx要素を利用しdiv要素でグループ化したりしていました。
しかし、div要素はただのグループ化で意味を伝えるものではありません。
HTML5では章や節のようなまとまったセクションを示すための専用の要素が用意されました。

要素 説明
section 一般的なセクション
article 記事を表す、「それだけで全部/完結している」セクション
nav 主要なナビゲーション
aside 主題とは直接関係ないセクション

どれも基本はh1~h6要素をつけます。
nav、aside要素に関しては文脈的に見出しを付けることが難しい場合は、無理につける必要はないとされています。

<body>
<h1>見出しA</h1>
    <section>
    <h2>見出しB</h2>
    ~省略~
    </section>
    <section>
    <h2>見出しC</h2>
    ~省略~
        <section>
        <h3>見出しD</h3>
        ~省略~
        </section>
    </section>
</body>

上記のアウトラインはこんな感じになります。

1. 見出しA
    1. 見出しB
    2. 見出しC
        1. 見出しD

もし、section要素だけつけて、h1~h6要素がない場合はこんな感じのアウトラインになります。こうなったら、section要素をやめるか、きちんとh1~h6要素をいれましょう。

例:「<h3>見出しD</h3>」を削除したアウトライン

1. 見出しA
    1. 見出しB
    2. 見出しC
        1. Untitled Section

暗黙的アウトライン – セクション要素がない場合のアウトライン –

基本的にはh1~h6要素には対応するセクション要素を入れる必要があります。
もし入れない場合でもアウトラインは生成されますが、どこのセクション要素に入っているかによってアウトラインに影響を与え暗黙的にアウトラインが作られます。

セクション要素内の2つ目以降の見出しは、前の見出しと比較してランクが同じか高ければ、そこで前の見出しのセクションは終了し、新しい暗黙のセクションが開始されます。前の見出しよりランクが低い場合は、前の見出しのセクション内に含まれる暗黙のサブセクションが開始されます。

さらにセクション要素がつけられている場合は、階層構造が明確になるので、仕様上はどのhx要素を見出しに使っても構わないことになっています。HTML5でh1要素を同ページ内にいくつ使ってもよいというのはこのためです。

言葉だけだとすごい理解しずらいですね(汗

1つ例を見ていきましょう。
h1要素の下にsection要素挟まないでh2要素があり、その下にh3要素を含んだsection要素があるとします。

<body>
    <h1>見出しA</h1>
    <h2>見出しB</h2>
    <section>
        <h3>見出しC</h3>
    </section>
</body>

ここから皆さんが期待するアウトラインはこのようになるかとおもいますが、実際は異なります。

期待するアウトライン

1. 見出しA
    1. 見出しB
        1. 見出しC

実際は、見出しBと見出しCは並列になるんですね。

実際のアウトライン

1. 見出しA
    1. 見出しB // section要素ないが暗黙のセクションが開始する
    2. 見出しC  // section要素入っていてかつ前の見出しよりランクが低くh3だが、section要素で囲まれているので、ランクの数字は無関係になり新しいサブセクションができる

下記のようにきちんとh1~h6要素に対応したセクション要素囲めば意図したアウトラインになります。

<body>
    <h1>見出しA</h1>
    <section>
        <h2>見出しB</h2>
        <section>
            <h3>見出しC</h3>
        </section>
    </section>
</body>

セクション要素を入れるときはきちっと入れる、入れないなら入れないで統一しないとぱっと見と実際のアウトラインは違ってしまうので、ここも注意しましょう。

セクショニングルート

今までの例において、h1要素にsection要素がないのに気づいたかとおもいます。
body要素がセクショニングルートと呼ばれ、そのページ自体のアウトラインの開始になっています。
また、そのほかにもセクショニングルートになる要素があり、これらの中にh1~h6要素を置いたとしてもbodyのアウトラインには一切でてきません。
よって、そのページのアウトラインに入れたいものはセクショニングルートに入れないようにしましょう。

要素 説明
body ドキュメント
blockquote 引用
fieldset フォームのグループ
figure 図・図表・挿絵など
td 表のデータ
<body>
    <h1>見出しA</h1>
    <blockquote>
        <h2>見出しB</h2>
    </blockquote>
    <section>
        <h2>見出しD</h2>
        <section>
            <h3>見出しE</h3>
        </section>
    </section>
</body>

blockquoteをいれたHTMLのアウトラインを出してみると、blockquoteに入っているhxは無視されます。

1. 見出しA
   2. 見出しD
       3.見出しE

また、h1要素をsection要素で囲ってしまうと、bodyに対する見出しがないため下記のようになってしまいますのでお気を付けください。

<body>
  <section>
  <h1>見出し1</h1>  
  </section>
</body>

bodyに対するh1要素がないので、下記のようなアウトラインになってしまいます。

1. Untitled Section
   1. 見出し1

SEO対策で見受けられた問題点や気になった点

今回のアイスタイルのHTML構造見直しででてきた点について触れたいと思います。アウトライン含めHTML構造が理想な状態になっていないのはもちろん、下記のような問題点が見受けられました。これらに関してどういう方針にしたか書いてみます。

article要素が乱立している

アットコスメでは、過去の実装において、商品・記事などいろんなものに対してarticle要素をつけるようにとなっており。つける基準が人によって異なっていました。そのため、1ページ内にarticle要素が沢山ある状態になってしまいました。
今回のSEO対策で話した結果、悩むくらいだったら、仕様に書いてあるとおり、記事だけにつけるでいいのではとなりました。
ブログの詳細ページ、まとめ記事など本当の記事だけにつけます。SEO対策にはarticle要素でなくても、section要素できちんとアウトラインさえしっかりしていれば関係ないだろうとのことです。

h1要素がページ内に複数ある

HTML5で同ページ内に複数のh1要素が文法的に大丈夫になりました。汎用的なモジュールがどのページに出たとしても大丈夫なようにh1要素で実装していた時期があります。

HTML5の文法的には、全ての見出しにh1要素にしたとしても問題はないが、これはあくまでも文法的に間違いではないだけであって、見出しは階層に合わせたランクを利用し、セクションはきちんとセクションで囲むことがHTML的に推奨となっています。

推奨となっている理由としては、HTML5.1勧告でh1要素がページに1つに戻されるとのことです。将来を見越してと合わせて、CSSの破綻と音声ブラウザなどが複数h1要素に対応しておらずアクセシビリティにもよくないとのことです。

汎用的なモジュールは、ページによってh1~h6要素の出しわけをしたり、もしくはh1~h6要素を付けるまで重みが必要なのかを検討していこうかとおもいます。

デザイン的に見出しだけど、hx要素にするしないの判断

これは上記でも触れた汎用モジュールにも言えます。
ページの主題に対して、関連しているまたはSEO対策にヒットさせたいワードが入っているかどうかで判断することも必要とのことです。
同じモジュールが違うページで使いまわされている場合は、この画面では関連度は高いが、そのほかのページでは高くないと判断した場合出しわけが発生するので、実際の開発工数との兼ね合いなども考えて実装しないといけないです。

目に見えない暗黙的なグループ化したいけどできない

新着情報などをフィード的な見た目で並べているページがあり、できれば親になるh1~h6要素を入れてその下にまとめたいという場合があります。
スマホなどはスペースを取るし、タイトル振ってなくても最新ぽいなとか分かってしまうもの。hxをdisplay:noneなどで非表示にすることもできますが、SEO対策にはスパムに当たってしまうのでよくないです。なので、素直にちょっと気持ち悪いですが、h1要素 > フィードタイトル h2要素、フィードタイトル h2要素としていくことにしました。

意図したアウトラインを保持するために

もちろん1から書く場合も、ページ内の途中に何か追加したりする場合もこの流れは同じかとおもいます。

1. 理想のアウトライン、構造を設計する

企画、デザイナーも含めみんなでこの画面が何を伝えたいのか検討します。

2. HTMLだけ書く

もちろんツリー構造やタグの噛み合わせがおかしくないかも確認します。

3. CSSを書き、見栄えに関するdivやspan要素はスタイルを当てる時に最低限にする

ここはCSSの技術もかかわってきますが、いかに不要なHTMLを書かずにそのデザインを再現できるかのスキルも必要になってきますね。
ただ、メンテナンス性などもあるので、減らせたからと言っていいわけではなく、運用しずらくなるのもNG。

慣れてくれば同時にできなくはないのですが、初心者の方は構造とスタイル用のタグを同時に当てて理想的なHTMLにすることは困難なので、この方法でやってみることをおすすめします。

最後に

フロントエンド10年以上やっているとどうしても慣れたHTMLについてないがしろにしがちです。
個人的にはHTML好きなので、構造化に関しては好きですが、今回アウトラインの細かい部分きちんと理解できてなかたかもなと思いすごい勉強になりました。
webの基礎となるHTMLをないがしろにしないように、さらに気を付けていきたいとおもいます。

そして、HTMLをきちんと見直した結果、口コミなどのページが上位にアップし、情報を必要としている人にちゃんと届くことを祈るばかりです。
今まさにSEO対策のためにHTML構造見直してるよとか、アウトラインについて曖昧になっている方のお役に立てれば幸いです。

参考文献

デザイン部所属フロントエンドエンジニア。コーディング歴10年超え。ガリガリ実装より、環境の標準化ガイドライン作り、新卒・中途コーディング研修などに注力。HTML好きで結構前ですが、HTML5/CSS3コンテスト入賞経験もあり。でもたまにはJavaScriptやPHPでの実装もやりたくなる。2019年3月現在はwebpack-dev-serverでのサーバー起動などを勉強中。