アクセシビリティについて

HTMLのアクセシビリティについて記述しています。
近年増えてるインタラクティブなWEBサイトやJavascriptを使用したUI/UXで無視されがちなアクセシビリティについて書いていきます。

「WAI-ARIA」「アクセシビリティを意識したUI/UX」について書いていきます。

アクセシビリティとは

可能な限り広い種類の利用者が、さまざまな製品や建物やサービスなどを支障なく利用できる度合いをいいます。(Wikipediaより引用)
WEBでは誰でもどんな環境でも問題なく使いやすく使用出来るサイトのことを指します。

具体的にどのようなことなのか考えてみましょう。

  • キーボードで操作できる
  • Javascriptが使用できなくても表示に問題がない
  • 画像が読見込めなくても何の画像かわかる
  • スクリーンリーダーユーザーでも問題なく内容がわかる
  • プログレッシブエンハスメントである
  • etc…

その為にWCAG 2.0の考えを元に考えていきます。

プログレッシブエンハスメントとは

正しいHTMLでサイトを作成してCSS3などをサポートしているブラウザに対して、
よりリッチなデザインや機能を提供し、サポートしていないブラウザにはそれなりのデザインや機能を提供することを言います。
これにを意識し制作することでサイトが構造化しWEB標準になり読みやすく見やすく使いやすいサイトになります。

ではボタンのマークアップ(HTML5)をベースに考えていきましょう。
なぜボタンかというとどんなサイトやWEBアプリケーションにもあるものだからです。

1
<button>ボタン</button>

ボタンの正しいマークアップ(HTML5)は<button>になります。
しかしこれだけでは機能しませんしキーボードでもフォーカスしません。

1
<button type="button">ボタン</button>

WCAG 2.0によるとtype="button"は何もしないという意味です。
なのでJavascriptの操作に適しています。

buttontypeには以下があります

  • submit -> フォームを送信する
  • button -> Javascriptの操作
  • reset -> フォームのリセットなどに使用

しかし上記にあげた以外にも機能として使用したいですよね。
ページの遷移にわざわざ毎回Javascriptを使用していたら重くなってしまいます。

以下のようなボタンのマークアップはよくあります。

1
<a href="xxx.html" class="c-button">ボタン</a>

このマークアップではプログレッシブエンハスメントではなくなってしまいます。
c-buttonというクラスをつければどんなタグでもボタンの見た目になってしまいます。
それでも正しいマークアップではなくなってしまいます。

W3CとWCAG 2.0ではWAI-ARIAラベルをつけることで解決します。

1
<a href="xxx.html" class="c-button" role="button">ボタン</a>

上記のマークアップのように<button>ではない要素に役割(role要素)を指定すれば、ボタンとして認識されます。

WAI-ARIAについて

WAI-ARIAとは正しいマークアップではない要素をプログレッシブエンハスメントにするものです。
WAI-ARIAには以下のARIAがあります

  • ロール => 役割
  • プロパティ => プロパティ
  • ステート => 状態
  • ラベル => 説明
    があります。

    ARIA使用のルール

  • 1 要素を置き換えるのに難しい場合と新しいHTMLの属性がサポートされていない場合に使用します。
  • 2 セマンティックなものには使用してはいけません。
  • 3 キーボードで使用できなければいけません。

ロール

ロール要素は正しいマークアップではないものを正しものと認識させます。
ロールは以下の種類があります。

抽象ロール
基本的に抽象ロール使用してはいけません

  • command
  • composite
  • input
  • landmark
  • range
  • roletype
  • section
  • sectionhead
  • select
  • structure
  • widget
  • window

ウィジェットロール(最小限のパーツに使用)

  • alert
  • alertdialog
  • button
  • checkbox
  • dialog
  • gridcell
  • link
  • log
  • marquee
  • menuitem
  • menuitemcheckbox
  • menuitemradio
  • option
  • progressbar
  • radio
  • scrollbar
  • slider
  • spinbutton
  • status
  • tab
  • tabpanel
  • textbox
  • timer
  • tooltip
  • treeitem

複合ユーザーインターフェースウィジェット(複数のパーツで構成されるパーツに使用)

  • combobox
  • grid
  • listbox
  • menu
  • menubar
  • radiogroup
  • tablist
  • tree
  • treegrid

文書構造(HTMLの構造に使用する)

文書構造は通常、他のroleと違いインタラクティブ(見た目ではわからないもの)ではないものです。

  • article
  • columnheader
  • definition
  • directory
  • document
  • group
  • heading
  • img
  • list
  • listitem
  • math
  • note
  • presentation
  • region
  • row
  • rowgroup
  • rowheader
  • separator
  • toolbar

ランドマークロール
HTML5では大きく以下のようなランドマークに分けることができます。

ランドマークはそのページで一度しか使用できないルールがあるものもあります。
以下はそのランドマークに使用します。

  • application => 1回のみ
  • banner => 1回のみ
  • complementary => 1回のみ
  • contentinfo => 1回のみ
  • form => 複数化使いすぎに注意
  • main => 1回のみ
  • navigation => 1回のみ
  • search => 複数化使いすぎに注意

各ロールの使用方法は以下を参照
ロールの定義

プロパティ&ステート

他の言語からの機能に関する助言情報を表すものです。
基本的に値は次の種類のいずれかが入ります。

  • true/false
    デフォルトは”false”の値をもつ、trueまたはfalseのいずれかを表す値。

  • tristate
    中間の”mixed”の値をもつ、trueまたはfalseを表す値。特に指定しない限り、デフォルト値は “false”である。

  • true/false/undefined
    ステートまたはプロパティーを示すものが関連しないデフォルトで”undefined”の値をもつ、trueまたはfalseを表す値。

  • ID参照
    同じ文書内の別要素のIDへの参照

  • ID参照リスト
    1つ以上のID参照のリスト。

  • 整数
    小数成分を含まない数値。


  • 任意の実数の値。

  • 文字列
    制約のない値型。

  • トークン
    許可された限定セットの1つ。

  • トークンリスト
    1つ以上のトークンのリスト。

ウィジェット属性
ウィジェットロールをサポートするために使用される。
尚JavascriptによるDOMの変更を行いstateが変更する場合はDOM属性を変更しなければならない。

  • aria-autocomplete
    - aria-checked (ステート)
    - aria-disabled (ステート)
    - aria-expanded (ステート)
    - aria-haspopup
    - aria-hidden (ステート)
    - aria-invalid (ステート)
    - aria-label
    - aria-level
    - aria-multiline
    - aria-multiselectable
    - aria-orientation
    - aria-pressed (ステート)
    - aria-readonly
    - aria-required
    - aria-selected (ステート)
    - aria-sort
    - aria-valuemax
    - aria-valuemin
    - aria-valuenow
    - aria-valuetext

ライブ領域属性

コンテンツをリアルタイムに更新を処理する方法の情報を支援技術に提供することを示すために使用される。

  • aria-atomic
  • aria-busy (ステート)
  • aria-live
  • aria-relevant

ドラッグアンドドロップ属性
ドラッグ可能な要素とそのドロップターゲットの要素に使用する。

  • aria-dropeffect
  • aria-grabbed (ステート)

関係属性

要素間の関係または関連を示す属性に使用する。
ボタンをクリックすると変わる要素などに使用します。

1
2
3
4
5
6
7
8
9
10
11
<div class="c-toolbar" role="toolbar" aria-controls="sortTable">
<button>昇順</button>
<button>降順</button>
</div>
<ul id="sortTable">
<li>テキスト1</li>
<li>テキスト2</li>
<li>テキスト3</li>
<li>テキスト4</li>
...省略
</ul>

この例ではaria-controls="sortTable"id="sortTable"を関連つけています。
このように使用します。

  • aria-activedescendant
  • aria-controls
  • aria-describedby
  • aria-flowto
  • aria-labelledby
  • aria-owns
  • aria-posinset
  • aria-setsize

ラベル

非テキストコンテンツの説明に使用します。
以下の2つが使用されます。

  • aria-label => 通常の説明で使用します。
  • aria-labelledby => 説明と要素を関連づけて使用します。

aria-label

1
<button aria-label="説明">&#xE000;</button>

aria-labelledby

1
2
<p id="desc-txt">説明</p>
<button aria-labelledby="desc-txt">&#xE000;</button>

このように使用します。

アクセシビリティのマークアップルール

アクセシビリティが高く、正しいマークアップをするには幾つかルールがあります。
W3Cが定めたルールがありそれに基づいて、マークアップすることはWEB標準のマークアップをすることです。

幾つか例をあげて紹介していきます。

section, article要素

この要素を使用するときは必ず見出しをつけなければなりません。
さらに構造体にする必要があります。

1
2
3
4
5
6
7
8
9
10
11
<article>
<h1 aria-level="1">見出し1</h1>
<section>
<h2 aria-level="2" class="c-heading__lvOne">見出し2</h2>
...省略
</section>
<section>
<h2 aria-level="2" class="c-heading__lvOne">見出し2</h2>
...省略
</section>
</article>

以下のように見出しレベルが下がるごとに入れ子にし構造体にしないといけません。

h1 > h2 > h3 > h4 > h5 > h6

しかし入れ子をやりすぎると見にくいマークアップになってしまいます。
その為aria-levelを使用したりしてマークアップを行います。

1
<h4 aria-level="3">見出し3</h4>

このように使用します。

form要素

form要素を使用する場合は以下のようにします。
<filedset><legend>はセットで使用します。

1
2
3
4
5
6
7
<filedset>
<legend>フォームのタイトル</legend>
<form>
<input type="checkbox" id="checkbox"><label for="checkbox">ラベル</label>
...省略
</form>
</filedset>

画像の代替テキストの使用方法。

以前はテキスト画像を使用する際はaltを使用すればよかったのですが。
それではプログレッシブエンハスメントではなくなってしまいます。
コンテキストの重要性を考えるとテキスト要素のタグを使用する場合テキストが無いのは構造状おかしいです。

変更前
このマークアップはおかしいです。
h1は見出し(テキスト)タグです。

1
<h1><img src="image/logp.png" alt="ロゴ"></h1>

どう変えるか以下のように変更します。

変更後
テキストは隠して使用します。

1
<h1><img src="image/logp.png" alt="">ロゴ</h1>

h1要素にdisplay:none;,opacity:0;これでは画像も消えてしまいます。
span要素で囲み隠すのをおすすめします。

1
<h1><img src="image/logp.png" alt=""><span class="u-hidden">ロゴ<span></h1>
1
2
3
4
.u-hidden {
visibility: hidden;
font-size: 0;
}

もし、Adobe Typekitがしようできる状態なら、font-family:Blank;でけすことをおすすめます。
よりセマンティックな要素になります。

アクセシビリティを意識したUI/UX

アクセシビリティを意識したUI/UXのデザインをしないといけません。
キーボードの操作を考えたデザインにし無いといけません。

特に順番が重要です。
Javascriptを使用したインタラクティブなサイトでは実際にフォーカスする順番になってい無いことが多いです。
例えば、以下のようなタブで切り替える要素はタブ部分とコンテンツ(テキスト)が分かれてマークアップされることが多いです。

1
2
3
4
5
6
7
8
<ul role="tablist">
<li role="presentation"><a href="#section1" role="tab" aria-controls="panel1" aria-selected="true">tab1</a></li>
<li role="presentation"><a href="#section2" role="tab" aria-controls="panel2" aria-selected="true">tab2</a></li>
<li role="presentation"><a href="#section3" role="tab" aria-controls="panel3" aria-selected="true">tab3</a></li>
</ul>
<section id="section1" role="tabpanel">...省略</section>
<section id="section2" role="tabpanel" aria-hidden="true">...省略</section>
<section id="section3" role="tabpanel" aria-hidden="true">...省略</section>

このようなタブはキーボードでは以下のように遷移します。

しかし実際は次のような動きをしないといけません。

tabindexとJavascriptでフォーカスを制御します。
こういったデザインを作るときは構造と機能を考えて作らないといけません。