アクセシビリティとSEOに対応したHTMLマークアップ

## 経緯
日頃コーディングをしている中で、要件の実装やデザイナーからの指示への対応に注力しすぎるあまり、アクセシビリティやSEOについての対応を後回しにしてしまい、疎かになってしまっていることが何度かありました。

この記事では自戒の意味を込め、アクセシビリティやSEOへ対応されているHTMLマークアップのために必要な要素についてまとめてみたいと思います。

以下の要件を満たすことができればアクセシビリティやSEOへ対応されているHTMLマークアップと言えるのではないかと個人的に考えました。

## 要件
1. **セマンティックで正確なマークアップ**
    * 要素が意味的に正しく使われている
    * 見た目のデザインはCSSに任せ、HTMLは構造に集中
    <br>
    
1. **アクセシビリティ（A11Y）への配慮**
    * スクリーンリーダーなどの支援技術で正しく解釈される
    * 適切な `alt`属性、`aria-*`属性、`role`属性を使用
    <br>

1. **最適化されたパフォーマンス**
    * 必要最低限のコードで記述
    * 遅延読み込み（Lazy Load）や最適化されたリソースの利用
    <br>
1. **SEO対応**
    * 適切な `<title>`、`<meta>` タグ、見出し構造
    * 構造化データの適切なマークアップ

まだまだやれることは多そうですが、一旦上記についてまとめてみます。

## コーディング例
結論から述べると、上記の要件が満たされたHTMLは下記のようになりました。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="description" content="サンプルコードです。">
  <meta property="og:title" content="サンプルコード">
  <meta property="og:description" content="サンプルコードです。">
  <meta property="og:image" content="https://example.com/og-image.jpg">
  <meta property="og:url" content="https://example.com">
  <title>サンプルページ</title>
  <link rel="stylesheet" href="styles.css">
  <script defer src="scripts.js"></script>
  
  <!-- 構造化マークアップ（JSON-LD形式） -->
  <script type="application/ld+json">
  {
    "@context": "https://schema.org",
    "@type": "WebPage",
    "name": "サンプルページ",
    "description": "サンプルコードです。",
    "url": "https://example.com",
    "publisher": {
      "@type": "Organization",
      "name": "株式会社アンティー・ファクトリー",
      "logo": {
        "@type": "ImageObject",
        "url": "https://example.com/logo.png"
      }
    },
    "datePublished": "2024-12-03",
    "dateModified": "2024-12-03"
  }
  </script>
</head>
<body>
  <!-- ヘッダー -->
  <header>
    <div class="container">
      <h1>大見出し</h1>
      <nav aria-label="メインナビゲーション">
        <ul>
          <li><a href="#about">About</a></li>
          <li><a href="#features">Features</a></li>
          <li><a href="#contact">Contact</a></li>
        </ul>
      </nav>
    </div>
  </header>

  <!-- メインコンテンツ -->
  <main>
    <!-- Aboutセクション -->
    <section id="about" aria-labelledby="about-heading">
      <h2>見出し1</h2>
      <p>サンプルテキスト</p>
      <img src="/assets/img/image.jpg" 
           alt="サンプル画像" 
           loading="lazy" 
           width="600" 
           height="400">
    </section>

    <!-- Featuresセクション -->
    <section id="features" aria-labelledby="features-heading">
      <h2>見出し2</h2>
      <ul>
        <li>リスト</li>
        <li>リスト</li>
        <li>リスト</li>
        <li>リスト</li>
      </ul>
      <a href="/sample/" class="btn">詳しく見る</a>
    </section>

    <!-- Contactセクション -->
    <section id="contact" aria-labelledby="contact-heading">
      <h2>見出し2</h2>
      <form aria-label="お問い合わせフォーム">
        <label for="name">お名前</label>
        <input type="text" id="name" name="name" required aria-required="true">

        <label for="email">メールアドレス</label>
        <input type="email" id="email" name="email" required aria-required="true">

        <label for="message">メッセージ</label>
        <textarea id="message" name="message" rows="5" required aria-required="true"></textarea>

        <button type="submit" class="btn">送信</button>
      </form>
    </section>
  </main>

  <!-- フッター -->
  <footer>
    <div class="container">
      <p>&copy; 2024 株式会社アンティー・ファクトリー All Rights Reserved.</p>
      <button type="button" class="btn-secondary" aria-label="ページの先頭に戻る"</button>
    </div>
  </footer>
</body>
</html>
```

## 解説
**セマンティックで正確なマークアップ**
各HTMLタグには固有の意味があり、これらを正しく使うことで、ブラウザは**ページ構造を正しく解釈**することができ、検索エンジンは適切なコンテンツの優先順位付けが可能になります。

また、セマンティックで正確なマークアップを行うことで、コードの**可読性**や**保守性**の向上を図ることが可能です。

逆に**セマンティックではないコード**とはどういったものなのでしょうか？
以下はその例です。

**セマンティックではないコードの例**
```html
<div id="header">
  <div class="nav">
    <a href="#about">About</a>
    <a href="#features">Features</a>
  </div>
</div>
<div id="content">
  <div class="title">このページについて</div>
  <div class="text">このページではセマンティックなHTMLを学びます。</div>
</div>
```
上記の例では、すべてのタグが`<div>`タグでマークアップされています。ヘッダー要素に`<header>`タグが使用されておらず、`<main>`タグや`<section>`タグがないため、ブラウザに正しく情報を伝えることができません。

**セマンティックなマークアップの実践方法**
セマンティックなマークアップを実践するポイントとしては下記について注意して行うことが大事だと思います。
1. **要素を意味で選ぶ**
    * 見た目ではなく役割に基づいて適切な要素を選ぶ
2. **適切な補足属性を付加**
    * 例: aria-*属性やalt属性を正しく使う 
3. **CSSで見た目を制御**
    * HTMLでは構造に集中し、デザインはCSSに分離する
4. **階層構造を守る**
    * 見出しやセクションの階層を守り、論理的な構造を作る


## アクセシビリティ（A11Y）への配慮
アクセシビリティ（A11Y）の向上とは、障害のある人々を含むすべてのユーザーがウェブページを利用しやすくすることを指します。これを実現するためには、適切なセマンティックマークアップを使い、支援技術（例: スクリーンリーダー）に情報を正確に伝えることが重要です。

**アクセシビリティ向上の具体的なポイント**
**1.支援技術による正しい解釈**
セマンティックな要素（例: `<header>`や`<nav>`）は、支援技術がページ構造を認識するのに役立ちます。以下はその例です。

* スクリーンリーダー
    * スクリーンリーダーはセマンティックな要素を元に、ページの構造や内容を音声で説明します。
    * 例: <main>要素は「ここから主要な内容が始まります」と認識されます。

* キーボード操作
    * セマンティックな要素を使用することで、支援技術がページのナビゲーションを適切にガイドできます。

**2.セマンティック要素とARIA属性の組み合わせ**
セマンティックな要素を使うだけでは不十分な場合、ARIA（Accessible Rich Internet Applications）属性を追加して補強します。
| セマンティック要素 | ARIA属性の例 | 効果 |
|:-:|:-:|:-:|
|  `<nav>` |  `aria-label="主なナビゲーション"` | スクリーンリーダーがナビゲーションメニューであることを認識します。  |
|  `<button>` | `aria-expanded="false"`  |  折りたたみメニューなどの状態を伝えることで、ユーザーが現在の状態を把握できます。 |
| `<form>`  | `aria-labelledby="form-title"`  |  フォームの目的や内容を明示的にラベル付けします。 |
|  `<section>` | `aria-labelledby="section-heading"`  | セクションに適切なタイトルを付けることで、内容の意味を伝えます。  |
|  カスタム要素 |  `role="button"` |  `<div>`など非セマンティック要素をボタンのように振る舞わせる場合に使用します。 |

**3.ラベルと説明を明確にする**
フォームやインタラクティブな要素には、ラベルや説明を適切に付けることが必要です。
* **フォームの例**
    フォームフィールドには、`<label>`要素で明確なラベルを付ける。スクリーンリーダーはラベルを読み上げます。
    ```html
    <label for="email">メールアドレス:</label>
    <input type="email" id="email" name="email" required aria-required="true">
    ```
    <br>
* **ボタンの例**
    ボタンの役割や状態を明確に説明する。
    ```html
    <button type="submit" aria-label="お問い合わせフォームを送信">送信</button>
    ```
    <br>
* **画像の例**
    画像には必ず`alt`属性を付け、内容を説明します。
    ```html
    <img src="example.jpg" alt="セマンティックHTMLを説明する図解">
    ```

**4.見た目ではなく機能を重視**
見た目のデザインを目的に要素を選ぶのではなく、その意味や機能を基準に要素を選ぶべきです。以下のように使い分けます。

* 見た目だけで`<div>`を使うのは避ける
    ```html
    <!-- 悪い例 -->
    <div class="button">クリック</div>
    ```
    <br>
    
    代わりに`<button>`を使用
    ```html
    <!-- 良い例 -->
    <button>クリック</button>
    ```
    <br>
**セマンティックなHTMLがアクセシビリティを向上させる具体例**

**ナビゲーションの例**
セマンティックな`<nav>`要素とARIA属性を組み合わせることで、ナビゲーションが明確になります。
```html
<nav aria-label="主要ナビゲーション">
  <ul>
    <li><a href="#home">ホーム</a></li>
    <li><a href="#about">私たちについて</a></li>
    <li><a href="#contact">お問い合わせ</a></li>
  </ul>
</nav>
```
**ランドマークの使用**
ランドマーク要素（`<header>`, `<main>`, `<footer>`）を使用すると、スクリーンリーダーがページの主要な部分を素早く特定できます。
```html
<header>
  <h1>大見出し</h1>
  <nav aria-label="トップナビゲーション">
    <ul>
      <li><a href="/about.html">About</a></li>
      <li><a href="/services.html">Services</a></li>
    </ul>
  </nav>
</header>
<main>
  <article>
    <h2>見出し</h2>
    <p>サンプルテキスト</p>
  </article>
</main>
<footer>
  <p>&copy; 2024 サンプルサイト</p>
</footer>
```

**最適化されたパフォーマンス**
**1.必要最低限のコードで記述**
ウェブページのコードをシンプルかつ効率的に書くことで、読み込み速度が向上します。

**不要なコードを減らす**
* **セマンティックなHTML要素を使う**
    * `<div>`や`<span>`を乱用せず、適切な要素（例: `<header>`, `<article>`, `<footer>`）を使用します。
    * 不必要なCSSクラスやインラインスタイルを減らします。

**最小限のリソース使用**
* **軽量なHTML**
    * 空白やコメントを適切に管理し、ファイルサイズを削減します。
    * 不必要な要素や属性を取り除きます。

例:
改善前
```html
<div class="header">
  <div class="title">ウェブサイトタイトル</div>
</div>
```
改善後
```html
<header>
  <h1>ウェブサイトタイトル</h1>
</header>
```
**2. 遅延読み込み（Lazy Load）**
遅延読み込みを活用することで、ユーザーが必要とするコンテンツのみを読み込み、初期ロードを高速化します。

**画像の遅延読み込み**
* ユーザーがスクロールするまで画像を読み込まないようにすることで、初期読み込みを軽くします。
    ```html
    <img src="placeholder.jpg" data-src="image.jpg" loading="lazy" alt="画像の説明">
    ```
**動画や埋め込みコンテンツの遅延読み込み**
* 大きなファイル（例: YouTube埋め込み動画）も遅延読み込みします。
    ```html
    <iframe src="https://www.youtube.com/embed/video-id" loading="lazy" title="動画タイトル"></iframe>
    ```

## SEO対応(セマンティックなマークアップの利点)
SEO（Search Engine Optimization: 検索エンジン最適化）は、検索エンジンでウェブページの順位を向上させるための一連の最適化手法です。セマンティックなHTMLを使うことは、検索エンジンがコンテンツの意味を正しく理解するのに役立ち、SEOの効果を高めます。

**1.適切な `<title>` と `<meta>` タグ**
`<title>`タグ
* ページの内容を簡潔に表すタイトルを設定します。
* 検索結果ページでタイトルとして表示されるため、クリック率（CTR）に影響します。

`<meta>`タグ
* `description`属性を使い、ページの簡潔な説明を記述します。検索結果に表示されるスニペットとして使われます。
例:
```html
<meta name="description" content="セマンティックHTMLの基本とSEOへの影響について詳しく解説します。">
```
**2.見出し構造の最適化**
* `<h1>` から `<h6>` を使い、論理的な見出し構造を作ります。
    *`<h1>`: ページ全体の主題（基本的に1ページに1回だけ使用）。
    *`<h2>`: 大きなセクションの見出し。
    *`<h3>`: 小さなセクションや補足情報の見出し。
```html
<h1>セマンティックHTMLの重要性</h1>
<h2>セマンティックHTMLとは</h2>
<h3>SEOへの影響</h3>
<h3>アクセシビリティへの配慮</h3>
```

**3.構造化データの活用**
* 構造化データ（Structured Data）を使うと、検索エンジンがページの内容をさらに詳しく理解し、リッチリザルト（例: 評価スター、レシピカード）として表示される可能性が高まります。

**JSON-LDを使用した構造化データの例**
例として、ブログ記事の構造化データを追加します。
```html
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "headline": "サンプルページ",
  "datePublished": "2024-12-01",
  "description": "サンプルページについて紹介",
  "mainEntityOfPage": "https://example.com/"
}
</script>
```
このコードにより、Googleなどの検索エンジンが記事の情報を構造化して解釈します。

**4.リンク構造の最適化**

**ナビゲーション**
* `<nav>`要素を使用して、主要なナビゲーションを検索エンジンが認識できるようにします。
    ```html
    <nav aria-label="主要ナビゲーション">
      <ul>
        <li><a href="/home.html">ホーム</a></li>
        <li><a href="/services.html">サービス</a></li>
      </ul>
    </nav>
    ```
**5.画像とメディアのSEO**
* `alt`属性: 画像に適切な説明を追加し、画像が何を表しているかを検索エンジンに伝えます。
    ```html
    <img src="semantic-html.jpg" alt="セマンティックHTMLを説明する図解">
    ```

## まとめ
セマンティックなHTMLを正しく活用することで、アクセシビリティへの配慮、パフォーマンス、SEO(検索エンジン最適化）といった重要な要素をカバーすることが可能になります。
これらの対応を疎かにしてしまうことが過去に何度かありましたので、今後のマークアップでは、この記事を作成するにあたって得た知識を反映し、隙のないHTMLマークアップができるように取り組んでいきたいです。