本文へジャンプ

アクセシビリティー

Web アクセシビリティー(a11y としても知られます)とは、障害のある人、回線速度が遅い人、古かったり壊れたハードウェアを使用している人、単に芳しくない環境にいる人など、誰でも利用できる Web サイトを作成することを指します。例えば、ビデオに字幕をつければ、耳の不自由なユーザーも、大音量の中で電話の音が聞こえないユーザーも、どちらも便利になります。同様に、テキストのコントラストが低すぎないようにすることで、弱視のユーザーにも、明るい日光の下で携帯電話を使おうとしているユーザーにも役立ちます。

始めたいけどどこから始めたらいいか分からない?

World Wide Web Consortium (W3C) が提供する Web アクセシビリティーの計画と管理ガイドを確認してください。

各ページの上部にメインコンテンツに直接アクセスできるリンクを設け、ユーザーが複数の Web ページで繰り返されるコンテンツを読み飛ばせるようにする必要があります。

通常、これは App.vue の上部に置かれ、すべてのページで最初にフォーカス可能な要素になります:

template
<ul class="skip-links">
  <li>
    <a href="#main" ref="skipLink" class="skip-link">Skip to main content</a>
  </li>
</ul>

フォーカスされない限りリンクを非表示にするには、以下のようなスタイルを追加します:

css
.skip-link {
  white-space: nowrap;
  margin: 1em auto;
  top: 0;
  position: fixed;
  left: 50%;
  margin-left: -72px;
  opacity: 0;
}
.skip-link:focus {
  opacity: 1;
  background-color: white;
  padding: 0.5em;
  border: 1px solid black;
}

ユーザーがルートを変更したら、スキップリンクにフォーカスを戻します。これは、スキップリンクのテンプレート参照でフォーカスを呼び出すことで実現できます(vue-router の使用を想定しています):

vue
<script>
export default {
  watch: {
    $route() {
      this.$refs.skipLink.focus()
    }
  }
}
</script>
vue
<script setup>
import { ref, watch } from 'vue'
import { useRoute } from 'vue-router'

const route = useRoute()
const skipLink = ref()

watch(
  () => route.path,
  () => {
    skipLink.value.focus()
  }
)
</script>

メインコンテンツへのスキップリンクに関するドキュメントを読む

コンテンツ構成

アクセシビリティーの最も重要な要素のひとつは、デザインがアクセシブルな実装をサポートできることを確認することです。デザインは、色のコントラスト、フォントの選択、テキストサイズ、言語だけでなく、アプリケーションの中でコンテンツがどのように構成されているかも考慮する必要があります。

見出し

ユーザーは、見出しを頼りにアプリケーションを移動することができます。アプリケーションの各セクションに説明的な見出しがあれば、ユーザーは各セクションの内容を容易に予測することができます。見出しに関しては、推奨されるアクセシビリティーの実践方法がいくつかあります:

  • 見出しをその順番通りにネストさせる: <h1> - <h6>
  • セクション内の見出しをスキップしない
  • テキストにスタイリングすることで見出しのような外観を与えるのではなく、実際の見出しタグを使用する

見出しについてもっと読む

template
<main role="main" aria-labelledby="main-title">
  <h1 id="main-title">Main title</h1>
  <section aria-labelledby="section-title-1">
    <h2 id="section-title-1"> Section Title </h2>
    <h3>Section Subtitle</h3>
    <!-- コンテンツ -->
  </section>
  <section aria-labelledby="section-title-2">
    <h2 id="section-title-2"> Section Title </h2>
    <h3>Section Subtitle</h3>
    <!-- コンテンツ -->
    <h3>Section Subtitle</h3>
    <!-- コンテンツ -->
  </section>
</main>

ランドマーク

ランドマークは、アプリケーション内のセクションへのプログラムによるアクセスを提供します。アシスティブ・テクノロジー(支援技術)に依存するユーザーは、アプリケーションの各セクションに移動し、コンテンツをスキップすることができます。これを実現するために、ARIA ロールを使用できます。

HTMLARIA ロールランドマークの目的
headerrole="banner"第一の見出し: ページのタイトル
navrole="navigation"ドキュメントや関連ドキュメントを辿るためのリンク集
mainrole="main"ドキュメントの主要な、または中心となる内容。
footerrole="contentinfo"親文章に関する情報: 脚注/著作権情報/プライバシーステートメントへのリンク
asiderole="complementary"メインコンテンツをサポートしつつ、独立して意味を持つコンテンツ
searchrole="search"アプリケーションの検索機能を含むセクション
formrole="form"フォームに関連する要素のコレクション
sectionrole="region"関連性がありユーザーが移動したくなるであろうコンテンツ。この要素にはラベルを付ける必要がある

ヒント:

HTML5 のセマンティック要素をサポートしていないレガシーブラウザーとの互換性を最大化するために、冗長なランドマークロール属性を持つランドマーク HTML 要素を使用することが推奨されています。

ランドマークについてもっと読む

セマンティックなフォーム

フォームを作成する際、次の要素を使うことができます: <form><label><input><textarea><button>

ラベルは通常、フォームフィールドの上部または左側に配置されます:

template
<form action="/dataCollectionLocation" method="post" autocomplete="on">
  <div v-for="item in formItems" :key="item.id" class="form-item">
    <label :for="item.id">{{ item.label }}: </label>
    <input
      :type="item.type"
      :id="item.id"
      :name="item.id"
      v-model="item.value"
    />
  </div>
  <button type="submit">Submit</button>
</form>

form 要素に autocomplete='on' を記述すると、フォーム内のすべての入力欄に適用されることに注意してください。各入力欄に対して異なる autocomplete 属性の値 を設定することもできます。

ラベル

すべてのフォームコントロールの目的を説明するため、ラベルを用意しましょう。forid をリンクします:

template
<label for="name">Name: </label>
<input type="text" name="name" id="name" v-model="name" />

Chrome デベロッパー ツールでこの要素を検査し、Elements タブ内の Accessibility タブを開くと、入力欄がどのようにラベルから名付けられているか確認できます:

Chrome デベロッパー ツールが、入力欄がラベルから得たアクセシブルな名前を表示している

注意:

このように入力フィールドをラップするラベルを見たことがあるかもしれません:

template
<label>
  Name:
  <input type="text" name="name" id="name" v-model="name" />
</label>

一致する id を持つラベルを明示的に設定する方が、アシスティブ・テクノロジーでより良くサポートされます。

aria-label

aria-label で入力欄にアクセシブルな名前を与えることもできます。

template
<label for="name">Name: </label>
<input
  type="text"
  name="name"
  id="name"
  v-model="name"
  :aria-label="nameLabel"
/>

Chrome DevTools でこの要素を検査し、アクセシブルな名前がどのように変更されたか確認できます:

Chrome デベロッパー ツールが、入力欄が aria-label から得たアクセシブルな名前を表示している

aria-labelledby

aria-labelledbyaria-label と似ていますが、ラベルテキストが画面上に表示されている場合に使用されます。他の要素とは id で対になっており、複数の id をリンクさせることができます:

template
<form
  class="demo"
  action="/dataCollectionLocation"
  method="post"
  autocomplete="on"
>
  <h1 id="billing">Billing</h1>
  <div class="form-item">
    <label for="name">Name: </label>
    <input
      type="text"
      name="name"
      id="name"
      v-model="name"
      aria-labelledby="billing name"
    />
  </div>
  <button type="submit">Submit</button>
</form>

Chrome デベロッパー ツールが、入力欄が aria-labelledby から得たアクセシブルな名前を表示している

aria-describedby

aria-describedbyaria-labelledby と同じように使われますが、ユーザーが必要とするかもしれない追加の情報を含む説明を提供します。これはどのような入力欄に対しても、その基準を記述するために使用することができます:

template
<form
  class="demo"
  action="/dataCollectionLocation"
  method="post"
  autocomplete="on"
>
  <h1 id="billing">Billing</h1>
  <div class="form-item">
    <label for="name">Full Name: </label>
    <input
      type="text"
      name="name"
      id="name"
      v-model="name"
      aria-labelledby="billing name"
      aria-describedby="nameDescription"
    />
    <p id="nameDescription">Please provide first and last name.</p>
  </div>
  <button type="submit">Submit</button>
</form>

Chrome DevTools で検査することで、その説明文を確認することができます:

Chrome デベロッパー ツールが、入力欄に設定された aria-labelledby のアクセシブルな名前と、aria-describedby の説明文を表示している

プレースホルダー

多くのユーザーを混乱させる可能性があるため、プレースホルダーの使用は避けてください。

プレースホルダーの問題点の 1 つは、デフォルトではカラーコントラスト基準を満たしていないことです。カラーコントラストを修正すると、プレースホルダーは入力フィールドにあらかじめ入力されたデータのように見えるようになります。次の例を見ると、色のコントラスト基準を満たす Last Name プレースホルダーは、あらかじめ入力されたデータのように見えることがわかります:

Accessible placeholder

template
<form
  class="demo"
  action="/dataCollectionLocation"
  method="post"
  autocomplete="on"
>
  <div v-for="item in formItems" :key="item.id" class="form-item">
    <label :for="item.id">{{ item.label }}: </label>
    <input
      type="text"
      :id="item.id"
      :name="item.id"
      v-model="item.value"
      :placeholder="item.placeholder"
    />
  </div>
  <button type="submit">Submit</button>
</form>
css
/* https://www.w3schools.com/howto/howto_css_placeholder.asp */

#lastName::placeholder {
  /* Chrome, Firefox, Opera, Safari 10.1+ */
  color: black;
  opacity: 1; /* Firefox */
}

#lastName:-ms-input-placeholder {
  /* Internet Explorer 10-11 */
  color: black;
}

#lastName::-ms-input-placeholder {
  /* Microsoft Edge */
  color: black;
}

ユーザーがフォームを入力するのに必要な情報は、入力欄外で提供するとよいでしょう。

インストラクション

入力フィールドにインストラクションを追加する場合は、入力欄に正しくリンクさせるようにしてください。 インストラクションを追加し、aria-labelledby の中に複数の id をバインドすることができます。これにより、より柔軟なデザインが可能になります。

template
<fieldset>
  <legend>Using aria-labelledby</legend>
  <label id="date-label" for="date">Current Date: </label>
  <input
    type="date"
    name="date"
    id="date"
    aria-labelledby="date-label date-instructions"
  />
  <p id="date-instructions">MM/DD/YYYY</p>
</fieldset>

または、aria-describedby で入力欄に説明文を付けることもできます:

template
<fieldset>
  <legend>Using aria-describedby</legend>
  <label id="dob" for="dob">Date of Birth: </label>
  <input type="date" name="dob" id="dob" aria-describedby="dob-instructions" />
  <p id="dob-instructions">MM/DD/YYYY</p>
</fieldset>

コンテンツの非表示

通常、たとえ入力欄がアクセシブルな名前を持っていても、ラベルを視覚的に非表示にすることは推奨されません。しかし、入力欄の機能が周囲の内容から理解できるのであれば、視覚的にラベルを非表示にすることができます。

この検索フィールドを見てみましょう:

template
<form role="search">
  <label for="search" class="hidden-visually">Search: </label>
  <input type="text" name="search" id="search" v-model="search" />
  <button type="submit">Search</button>
</form>

非表示にできるのは、検索ボタンが入力フィールドの目的を視覚的に明らかにしているからです。

要素を CSS で視覚的に非表示にしつつ、なおアシスティブ・テクノロジーからはそれを利用できます:

css
.hidden-visually {
  position: absolute;
  overflow: hidden;
  white-space: nowrap;
  margin: 0;
  padding: 0;
  height: 1px;
  width: 1px;
  clip: rect(0 0 0 0);
  clip-path: inset(100%);
}

aria-hidden="true"

aria-hidden="true" を追加すると、アシスティブ・テクノロジーから要素を隠しますが、その他のユーザーは視覚的に利用できます。フォーカス可能な要素には使用せず、純粋に装飾的なコンテンツ、複製されたコンテンツ、画面外のコンテンツに使用してください。

template
<p>This is not hidden from screen readers.</p>
<p aria-hidden="true">This is hidden from screen readers.</p>

ボタン

フォーム内で button を使用する場合、フォームを送信しないようにするため type を設定する必要があります。 またはボタンを作成するために input を使用することもできます:

template
<form action="/dataCollectionLocation" method="post" autocomplete="on">
  <!-- ボタン -->
  <button type="button">Cancel</button>
  <button type="submit">Submit</button>

  <!-- Input ボタン -->
  <input type="button" value="Cancel" />
  <input type="submit" value="Submit" />
</form>

機能的な画像

このテクニックを使って、機能的な画像を作ることができます。

  • 入力フィールド

    • これらの画像は、フォーム上で submit type のボタンとして機能します。
    template
    <form role="search">
      <label for="search" class="hidden-visually">Search: </label>
      <input type="text" name="search" id="search" v-model="search" />
      <input
        type="image"
        class="btnImg"
        src="https://img.icons8.com/search"
        alt="Search"
      />
    </form>
  • アイコン

template
<form role="search">
  <label for="searchIcon" class="hidden-visually">Search: </label>
  <input type="text" name="searchIcon" id="searchIcon" v-model="searchIcon" />
  <button type="submit">
    <i class="fas fa-search" aria-hidden="true"></i>
    <span class="hidden-visually">Search</span>
  </button>
</form>

標準規格

World Wide Web Consortium(W3C)の Web Accessibility Initiative(WAI)は、さまざまなコンポーネントの Web アクセシビリティー規格を策定しています:

Web コンテンツアクセシビリティーガイドライン(WCAG)

WCAG 2.1 は、WCAG 2.0 を拡張し、Web の変化に対応することで、新しい技術の実装を可能にするものです。W3C は、Web アクセシビリティー方針を策定又は更新する際に、最新版の WCAG を使用することを推奨しています。

WCAG 2.1 四つの原則:

  • 知覚可能
    • 表示されている情報は、利用者が知覚できなければならない
  • 操作可能
    • インターフェースフォーム、コントロール、ナビゲーションは操作可能でなければならない
  • 理解可能
    • 情報及びユーザーインターフェースの操作は全ての利用者に理解可能でなければならない
  • 堅牢
    • テクノロジーが進歩しても、利用者はコンテンツにアクセスできなければならない

Web Accessibility Initiative – Accessible Rich Internet Applications (WAI-ARIA)

W3C の WAI-ARIA は、動的コンテンツや高度なユーザーインターフェイスコントロールの構築方法に関するガイダンスを提供しています。

リソース

資料

アシスティブ・テクノロジー

テスト

ユーザー

世界保健機関(WHO)は、世界人口の 15% が何らかの障害を持ち、そのうち 2-4% が重度であると推定しています。これは全世界で 10 億人と推定され、障害者は世界最大のマイノリティーグループとなっています。

障害の範囲は非常に多く、大きく 4 つに分類されます。

  • 視覚 - このようなユーザーは、スクリーンリーダー、画面拡大表示、画面コントラスト制御、点字表示の使用が有効です。
  • 聴覚 - このようなユーザーには、キャプション、字幕、手話映像が有効です。
  • 肢体 - このようなユーザーは、音声認識ソフトウェア、アイトラッキング、シングルスイッチアクセス、頭部装着型指示器、息操作スイッチ、特大トラックボールマウス、アダプティブキーボード、その他のアシスティブ・テクノロジーなど、さまざまな肢体障害支援技術の使用が有効です。
  • 認知 - このようなユーザーには、補足的なメディア、構造的なコンテンツ、明確でシンプルな文章が有効です。

WebAim の以下のリンクをチェックして、ユーザーの理解を深めましょう:

アクセシビリティーが読み込まれました