🌟
【技術書まとめ】HTML解体新書
HTMLやWAI-ARIAの仕様について改めて学ぼうと思い読んでみた。
1: HTMLの基本概念
- リンクをマウスでクリックするだけで、遥か彼方の国にある文書を読むことができる
- ルール
- 字句的ルール
- 閉じタグがないなど
- 語彙的ルール
- h1やpをstrong要素の中に入れる
- 意味論的ルール
- 本文をh1とする
- 字句的ルール
- アクセシビリティ
- ガイドライン
- WCAG2.1
- サポート文書
- Understanding WCAG2.0
- Techniques WCAG2.0
- WAI-ARIA
- HTML要素に対して、支援技術に伝えるべき情報を追加する
-
role
で要素の役割 -
aria-
で状態
-
- HTML要素に対して、支援技術に伝えるべき情報を追加する
- ガイドライン
- URL
- スキーム
https
- ホスト
example.com
- ポート
3000
- パス
/foo/bar.php
- クエリ
?q=xxx
- フラグメント
#result
- スキーム
- MIMEタイプ
- 未設定だとブラウザが推測するMIME sniffingする
- text/plainであるはずがHTMLと解釈させてJSを実行する脆弱性となることもある
- 未設定だとブラウザが推測するMIME sniffingする
- HTML仕様
- WHATWG
- 規範と参考
- 規範: normative
- 参考: informative, non-normative
2: HTMLマークアップのルール
- URL
- 絶対URLと相対URL
- スキーム相対URL
-
//example.com/foo/bar.html
- http, httpsが同じになる
-
- パス絶対URL
- スキーム相対URLから
//
とホストを取り除いたもの/foo/bar.html
- スキーム相対URLから
- パス相対URL
- 先頭が
/
で始まらないパス-
foo/bar.html
-
./
などを使う
-
-
- 先頭が
- スキーム相対URL
- パーセントエンコードは%に続いて2桁の16進数で文字コードを表現する
-
&
はHTMLの文字参照に利用するので&
とする
-
- 絶対URLと相対URL
3: HTMLの主要な要素
- セクション
-
article
- そのセクションだけで自己完結するもの
- スクリーンリーダーによってランドマークとして扱うこともある
- そのセクションだけで自己完結するもの
-
section
-
<h2>
などの見出しが必要 - ランドマークではない
-
-
aside
- スクリーンリーダーで任意の要素にジャンプしたり、丸ごとスキップできる
-
nav
- 読み飛ばしやジャンプができると便利ならばnav要素にする
- 使い過ぎには注意
- 読み飛ばしやジャンプができると便利ならばnav要素にする
- 見出し
- h1からh6
-
aria-level
を使うと7以上も表現できる- 対応していないことも多いので慎重に使用する
-
- h1からh6
-
header
- もっとも近い祖先のセクショニングコンテンツのヘッダーとみなされる
-
- グルーピングコンテンツ
-
p
- 特別な意味を持たない文のかたまりはpで問題ない
- ARIAロールはない
- 特別な意味を持たない文のかたまりはpで問題ない
-
dl
- 当面スクリーンリーダーによるdl関連要素の扱いは安定しない
-
figure
- 本文から参照される自己完結型のコンテンツ
- 画像、図表、例、コード断片など
- 本文から参考として参照されている
- 本文から切り離しても本文の説明が成立する
- 単独で1つのコンテンツとして成立する
- 画像、図表、例、コード断片など
- imgのaltと同内容をfigcaptionに入れるとスクリーンリーダーで2回読み上げてしまうため注意する
- 本文から参照される自己完結型のコンテンツ
-
- テキストレベルセマンティクス
-
cite
- 参考文献の正式なタイトルを示す
- 著者名は含まない
- 参考文献の正式なタイトルを示す
-
time
- 日付や時刻をマシンリーダブルな形式で表現する
<time datetime="2017-01-23">2017年1月23日</time>
- 日付や時刻をマシンリーダブルな形式で表現する
-
data
- 日時以外のデータをマシンリーダブルにする
-
wbr
- その位置で改行が可能であることを表す
-
- リンク関連要素
-
a
- リンク先のコンテンツタイトルをそのままリンクテキストとするのが望ましい
- スクリーンリーダーにおいては、「こちら」では意味をなさないから
- 画像をリンクにするとaltがリンクテキストとなる
-
target="_blank"
はテキスト内に新しいタブで開くことを明示した方がよい - 属性
-
target
-
_blank
は新しいブラウジングコンテキストを作成する-
window.opener
で元のブラウジングコンテキストを参照できる- 古いブラウザではこれがクロスドメインで可能だったのでセキュリティ上の重大な注意点となっていた
-
-
-
download
- ダウンロードファイル名のヒントとなる
-
ping
- どこからどこにページ遷移したのか把握できる
- HTTPリダイレクトやJSよりもパフォーマンスが高い
- どこからどこにページ遷移したのか把握できる
-
rel
-
rel="nofollow"
- サイトオーナーがリンク先を推奨しないことを示す
-
rel="preconnect"
- ドメインの名前解決、TCPコネクションの確立、TLSのネゴシエーションまで行う
- リンク先URLスキームはhttp若しくはhttpsでないと無視される
- ドメインの名前解決、TCPコネクションの確立、TLSのネゴシエーションまで行う
-
rel="prefetch"
- 事前にリソースを取得しキッシュさせることができる
-
rel="preload"
- 現在のページで使用するサブリソースをキャッシュする
-
rel="prev"
,rel="next"
- ブラウザはnextで指定されたリソースを先読みすることがある
-
-
- リンク先のコンテンツタイトルをそのままリンクテキストとするのが望ましい
-
- エンベディッドコンテンツ
-
img
要素- alt
-
alt
が空の場合は装飾的なものとみなされる- alt属性はウェブアクセシビリティにおいてもっとも重要な属性のひとつ
- 画像をテキストに置き換えても違和感なく、内容が過不足なく伝わるように代替テキストを記述する
- 画像と等価なテキストとする(電話口で読み上げるように)
- 本文に説明がある場合は繰り返しを避ける
-
- alt
-
iframe
要素- 提供されるHTMLコードが正しくない場合もある
- アクセシブルかどうか確認してから用いる
- 提供されるHTMLコードが正しくない場合もある
-
- テーブル(
table
)- かつてCSSが未成熟だったときにレイアウト目的でtableが使われることがよくあった
- アクセシビリティの観点でもやるべきではない
-
tr
-
th
かtd
を必ず1つ以上入れる
-
-
th
-
scope="col"
などで行か列のどちらが見出しか明示的に表す -
abbr="割合"
などで見出しが長いときに略称を付けられる -
caption
要素でテーブルタイトルや説明文を入れられる
-
- かつてCSSが未成熟だったときにレイアウト目的でtableが使われることがよくあった
- フォーム
-
form
要素-
method
: get, post, dialogのいずれかを指定する-
get
- 入力データはURLのクエリーに付与される
-
application/x-www-form-urlencoded
でシリアライズされる
-
- method値を省略した場合のデフォルトとなる
- 入力データはURLのクエリーに付与される
-
- formにformを入れ子にはできない
- 複数のボタンがあって送信先を変えるときはformaction属性を指定する
-
action
: フォームの送信先となるURLを指定する- 指定なしの場合はフォームが配置されるページ自身が送信先となる
-
enctype
: postで送信するときのリクエストボディの形式を指定できる-
application/x-www-form-urlencoded
- form controlの名前と値のペアをURL ecncodedして連結したもの
-
multipart/form-data
- 入力項目それぞれをboundaryで区切った形式
------WebKitFormBoundary***
- 入力項目それぞれをboundaryで区切った形式
-
text/plain
- 名前=値のペアを改行(CR+LF)で区切った形式
-
-
-
label
要素- labelとform controlとを明示的に関連づけることができる
-
for
属性でidと結びつける
-
- labelとform controlとを明示的に関連づけることができる
-
input
要素-
type
属性によって変わる-
text
,search
: 1行テキスト入力 -
tel
- 改行以外のあらゆる文字を受け入れる
- スクリーンリーダーではデフォルトは
textbox
となるので、a11yとしては電話番号入力欄であることがわかるラベルをつける
-
url
- 絶対URL
- HTTPやHTTPSに限られないことに注意する
- コロンを含む文字列はほぼすべて許可してしまう
- HTTPやHTTPSに限られないことに注意する
- 絶対URL
-
email
- a11yではメールアドレスとわかるようなラベルをつける
-
password
- 視覚的には隠されていてもスクリーンリーダーでは読み上げることがあるので注意する
- 日付および時刻の入力
-
number
- 入力できる値は妥当な不動小数点
- 数字以外の文字も入力できる(
.
,+
,-
,e
,E
)
- 数字以外の文字も入力できる(
- min, max, stepで制限できる
- クレジットカード番号は数値だとしてもtextが適する
- 入力できる値は妥当な不動小数点
-
checkbox
- チェックされたnameとvalueがフォーム送信時に送られる
- チェックされていない場合はnameとvalueは送られない
- チェックされたnameとvalueがフォーム送信時に送られる
-
radio
- 一度でも選択されると戻すことはできない
-
file
- enctype属性値を
multipart/form-data
にする -
multiple
で複数選択可能とする -
accept
でファイルの種類を絞り込める"audio/*"
"video/*"
"image/*"
- パラメータのないvalidなMIMEタイプ文字列
-
text/html
など
-
-
.
で始まる文字列で指定された拡張子のファイルを指定できる-
".doc,.docx,xml..."
など
-
- 想定外のファイル種類のアップロードを防ぐことはできないことに注意
- enctype属性値を
-
hidden
- システム側では値を受け取る必要があるが、ユーザーに入力・編集させる必要がないもの
- このコントロール値は秘匿されない
- dev toolsで読み取り書き換え可能
-
-
maxlength
,minlength
属性- minはそれより短い値を入れられる
- 送信時にvalidationされる
- maxはそれ以上入れられなくしてもよい
- minはそれより短い値を入れられる
-
size
属性- 見た目の幅を指定する
- 正確な幅はCSSで指定する
- デフォルト値は20
- 見た目の幅を指定する
-
readonly
属性- 入力を受け付けない状態とする
-
disable
属性と違って、入力されている値は送信される
-
- 入力を受け付けない状態とする
-
pattern
属性- テキスト入力コントロールの値をチェックできる
- type属性が、
test
,search
,url
,tel
,email
,password
のみ- それ以外は指定しても無視される
- type属性が、
-
title
属性を入れておくとエラー時に表示される<input pattern="[0-9]{3,4}" title="3〜4文字の数字を入力してください">
- 値が空の場合はvalidationされない
- セキュリティ上の意味は持たない
- dev toolsによってpattern属性を削除できる
- テキスト入力コントロールの値をチェックできる
-
list
属性- 定義済み候補のリストを示す
- 値は同一文書内のdatalist要素のID
- 定義済み候補のリストを示す
-
placeholder
属性- 入力するとスクリーンリーダーで読み上げられなくなるのでラベルの代わりに使わない
- デフォルトで薄い文字色だがWCAGのコントラスト比を満たさないこともある
-
- フォームコントロールの共通属性
-
name
属性- フォームコントロールに名前を与える
- name属性がないと、そのコントロールの値は送信されない
- 複数の要素に同じ名前を与えられる
- chackboxやradio buttonなどは同一グループとなる
- 送信時にはすべて個別に送信される
- chackboxやradio buttonなどは同一グループとなる
- フォームコントロールに名前を与える
-
disabled
属性- 値は送信されない
- これがreadonlyとの違い
- 値は送信されない
-
form
属性- form要素の外にある要素を明示的に関連づけられる
-
<form id="form01"> <!-- さまざまな入力欄 --> <button>送信する</button> </form> <!-- さまざまなコンテンツ --> <button form="form01">送信する</button>
-
- form要素の外にある要素を明示的に関連づけられる
-
autocomplete
属性- 通常ブラウザはname属性の値を参考にするが、autocomplete属性を利用すると明示的に指定できる
- 氏名、住所、性別、クレジットカード番号、URL、メールアドレスなど
- 4種類のトークンを組み合わせた値を指定する
- 配送先か、請求先か:
shipping
,billing
- グループ名:
section-
- 値の種類:
name
,nickname
,country
,photo
など - 追加の種類:電話番号に対して自宅や職場など
- 配送先か、請求先か:
- アクセシビリティが向上するので積極的に利用するとよい
- WCAG2.1の「入力目的の特定」を満たす
- 通常ブラウザはname属性の値を参考にするが、autocomplete属性を利用すると明示的に指定できる
-
-
- フォーム その2
-
button
要素-
type
属性- デフォルトはsubmit
- フォーム送信を意図しない場合は
type=button
にする
- フォーム送信を意図しない場合は
- デフォルトはsubmit
-
-
select
要素-
required
属性- 条件を満たす必要がある
- multipleではない
- sizeが1である
- 最初のoptionがoptgroupの子ではない
- 最初のoptionのvalueが空文字である
- 条件を満たす必要がある
-
-
option
要素-
select
やdatalist
とセットで扱う -
value
属性- フォーム送信時に送信される値
- valueがなければ、要素の内容となっているテキストが値となる
- フォーム送信時に送信される値
-
label
属性- 省略すると、要素の内容となっているテキストがラベルとなる
-
-
optgroup
要素- optionをカテゴリなどでグループ化できる
-
datalist
要素- input要素の入力補完の候補を提示できる
- ユーザーは選択肢から選ぶことも、選択肢を無視してテキスト入力することもできる
- input要素の入力補完の候補を提示できる
-
textarea
要素-
type=text
のinput要素と異なり、改行できる -
rows
,cols
属性- 入力可能な行数を制限するものではない
- rowsで行数を指定できる
- デフォルト値は2
- colsで1行あたりの文字数を指定できる
- デフォルト値は20
- 使用フォントの文字幅の平均で計算される
- デフォルト値は20
- 幅や高さはCSSで上書きされる
-
wrap
属性- 長い行の折り返しを制御する
- デフォルト値はsoft
- hardに指定すると改行(CR+LF, %0d%0a)が挿入される
- GETメソッドで送信すると入る
-
-
output
要素- 実行結果を表示できる
- JSでの動的処理に適する
-
for
属性- このoutputに関連する入力欄を示すことができる
-
progress
要素- プログレスバー
<progress value="0.5">50%</progress>
- プログレスバー
-
meter
要素- 棒グラフのようなゲージ
- 適正範囲を指定することで表示を変えられる
- 棒グラフのようなゲージ
-
fieldset
要素- 一連のフォームコントロールをグループ化する
-
legend
要素でラベルを付けられる- fieldsetの直接の子要素である必要がある
- 装飾としてdivで囲うことはできない
- fieldsetの直接の子要素である必要がある
- ラジオボタンやチェックボックス使用時に何に対する選択か明確にすることができる
- labelは個々の選択肢の名前となるだけだから
-
- legendをつけて、その下はulでフォームをまとめていく使い方もある
- 属性
-
disabled
,name
,form
属性が指定できる
-
- 一連のフォームコントロールをグループ化する
-
legend
要素- 中に
h2
などの見出しも入れられる- divは入れられない
- 中に
-
- インタラクティブ要素
-
details
要素- アコーディオンのようなもの
- 必ず
summary
要素を含む -
open
属性によって開閉する
-
summary
要素- 見出し要素も入れられる
- 見出しをクリックすると展開されるようにできる
- legendは入れらないのでfieldsetには使えない
- 見出し要素も入れられる
-
dialog
要素- ダイアログボックスやサブウィンドウ
- 子要素に
method=dialog
としたformがある場合- 送信時にダイアログを閉じて、値をreturnValueプロパティから取得できる
- JSで操作するときは
show()
,showModal()
,close()
で操作する- JSでopen属性を操作するとフォーカス制御が行われない
-
- スクリプティング
- 現在のHTML仕様はJSのみを想定している
- ブラウザ上で動作するスクリプトは事実上JSのみとなっている
-
script
要素- 特定のセマンティクスを持たない
- ユーザーに何かを提示するものではない
- 終了タグは省略できない
-
type
属性-
defer
,async
属性- 読み込みタイミングを制御できる
- 外部JSを読み込んでいる場合のみ
-
defer
- HTML解析と並行してJSを読み込む
- 両方終わったら実行される
-
DOMContentLoaded
イベントが発生するタイミングで初めて実行される
-
- 両方終わったら実行される
- HTML解析と並行してJSを読み込む
-
async
- HTML解析完了を待たずにJSを実行する
- 実行開始タイミングは不定
- HTMLソースでの出現順とは異なることもある
- 実行開始タイミングは不定
- HTML解析完了を待たずにJSを実行する
- deferとasyncを同時指定するとasync挙動になる
- async対応なしブラウザではdeferとなる
- モジュールスクリプトでは常にdefer動作となる
- 読み込みタイミングを制御できる
-
-
crossorigin
属性- srcで指定されたリソース参照のCORS挙動を制御できる
- src属性で指定したリソースの取得を制御するだけ
- JS内部からのCORSリクエストはwithCredentialsなどのプロパティなどの設定が必要
- src属性で指定したリソースの取得を制御するだけ
- 単に
crossorigin
とだけ指定すると"crossorigin-"annonymous"となる - "anonymous"
- HTTP認証やCookieなどのクレデンシャル情報は同一オリジンに対してのみ送信される
- クロスオリジンだと送信されない
- HTTP認証やCookieなどのクレデンシャル情報は同一オリジンに対してのみ送信される
- "use-credentials"
- オリジンに関わらずクレデンシャル情報が常に送信される
- srcで指定されたリソース参照のCORS挙動を制御できる
-
integrity
属性- 「サブリソース完全性(Subresource Integrity)」の仕様に沿ってチェックできる
- JSが改竄されていないか確認できる
- ハッシュ値を照合する
- base64でエンコードされたハッシュ値をハイフンでつないだ文字列
- ハッシュ値を照合する
- 外部サイトが攻撃を受けてJS改竄された場合に、読み込み側も影響を受けることを防ぐ
- JSが改竄されていないか確認できる
- 「サブリソース完全性(Subresource Integrity)」の仕様に沿ってチェックできる
-
referrerpolicy
属性- JSを参照する場合のreferrerpolicyを指定できる
- 特定のセマンティクスを持たない
-
noscript
要素- JSが無効な場合のフォールバックコンテンツを提供できる
-
canvas
要素- JSで任意のビットマップを描画できるキャンバスを表せる
- インタラクティブコンテンツ(
a
,button
,tabindex
など)を子孫要素にできない - 中身はcanvasが利用できないときのフォールバックコンテンツとなる
-
img
要素などとする
-
-
width
,heigh
省略時は300, 150となる - ARIAロールがないのでセマンティクス上の意味を持たない
- カスタム要素
- WebComponentsを構成するものの1つ
- 独自の要素を定義できる
- 5つ星の評価のマークアップなど
- 制約
- アルファベット小文字で始まること
- 1つ以上のハイフンを含むこと
- 現在のHTML仕様はJSのみを想定している
4: 主要な属性とWAI-ARIA
- グローバル属性
- すべてのHTML要素に共通して利用できる属性
- HTML仕様以外にもWAI-ARIA仕様やXML仕様もある
-
title
属性- 要素に対するヒントや助言を表す
- 値はユーザーに伝わらないことも多い
- titleはツールチップ表示になるが表示できない環境も多い
-
lang
属性- 指定された要素の自然言語を指定する
- 値は大文字小文字を区別しない
-
style
属性- specificityが最も高くなり、あらゆるセレクターよりも優先される
-
class
属性- CSSやJSで使用する
- 要素の役割や状態を伝えたい場合はARIA属性を利用する
-
[aria-pressed="true"] { /* スタイル */ }
など- ARIA属性のみでスタイルの変化を実装できる
- class属性は削除できる
- ARIA属性のみでスタイルの変化を実装できる
-
-
id
属性- URLフラグメント、参照、JSでの使用などで使われる
- ASCII空白文字を除くすべての文字が使える
- 大文字小文字は区別される
-
tabindex
属性- その要素がフォーカスを受け取るかどうかを制御できる
- sequential focus navigationと呼ばれる
- DOMツリー順に移動する
- focusableではないHTML要素をフォーカス可能にする
- sequential focus navigationと呼ばれる
-
tabindex=0
を指定した場合- focusableでなくてもフォーカスを受け取れるようになる
-
tabindex=-1
を指定した場合- フォーカス可能になりfocus()メソッドを受け取るが、シーケンシャルフォーカスナビゲーションの対象にはならない
- キーボード操作ではフォーカスできない
- JSでフォーカス制御するときに使用する
- キーボード操作ではフォーカスできない
- フォーカス可能になりfocus()メソッドを受け取るが、シーケンシャルフォーカスナビゲーションの対象にはならない
-
tabindex=正の数
を指定した場合- シーケンシャルフォーカスナビゲーションの順序が変更される
- 数値の小さいものが優先的にフォーカスが移る
- シーケンシャルフォーカスナビゲーションの順序が変更される
- その要素がフォーカスを受け取るかどうかを制御できる
-
autofocus
属性- 基本的に同一ページ内で1つだけ
- ログインフォームや検索フォームしか存在しないページなど
- dialog
- 基本的に同一ページ内で1つだけ
- イベントハンドラーコンテンツ属性
- 要素のイベントが発生したときにJSを実行できる
- イベントハンドラー属性
- onで始まる
-
onclick
など
-
- form内のbutton要素のonclickはsubmitしてしまうので、
type=button
と指定する
- onで始まる
- イベントハンドラー属性を使用しないイベント定義
- イベントリスナーを設定する
-
button.addEventListener('click', ...)
など
-
- イベントリスナーを設定する
-
accesskey
属性- ユーザーエージェントに対してショートカットキーのヒントを与える
<button type="button" accesskey="1"...
- 修飾キーとの同時押し(alt+1など)
- アクセシビリティ観点では利用を避ける方が好ましい
- 操作のバッティングや挙動の不安定さなど
- ユーザーエージェントに対してショートカットキーのヒントを与える
-
hidden
属性- 現時点でこのページと無関係であることを示す
- 子要素もまとめてレンダリングしなくなる
- スクリーンリーダーでも読み上げられなくなる
- 現時点でこのページと無関係であることを示す
- カスタムデータ(
data-*
)属性- 任意の要素に任意の属性を指定できる
- 主にJSから参照する
- 属性名から先頭の
data-
を除去したものがプロパティ名となる- *部分にハイフンを含むときはキャメルケースでアクセスできる(
data-html-book
->htmlBook
) - 数字で始めると.でアクセスはJS構文エラーとなる(
data-0
)
- *部分にハイフンを含むときはキャメルケースでアクセスできる(
- 属性名から先頭の
- 主にJSから参照する
- 任意の要素に任意の属性を指定できる
- すべてのHTML要素に共通して利用できる属性
- WAI-ARIA
- W3CのWAIによって発行されている仕様
- アクセシビリティ向上のための属性を定義している
- 組み合わせる相手のマークアップ言語をホスト言語(host language)と呼ぶ
- アクセシビリティ向上のための属性を定義している
- ARIA属性の分類
- ロール(role)
- 要素の役割を表す
- 何か、何もするものか
-
role="navigation"
など
-
- 対応するHTML要素がない場合もある
- 何か、何もするものか
- 要素の役割を表す
- ステート(state)
- 要素の現在の状態を表す
- 頻繁に変化することが想定されるもの
-
aria-disabled="true"
など- 現在無効になっている
-
- 頻繁に変化することが想定されるもの
- 要素の現在の状態を表す
- プロパティ(property)
- 要素の性質や特性を表す
-
aria-required="true"
など - stateとの違いは厳密なものではない
-
- 要素の性質や特性を表す
- ロール(role)
- WAI-ARIAとその周辺仕様
- WAI-ARIA仕様
- WAI-ARIAそのものの説明と、ロール、ステート、プロパティの定義
- ARIA in HTML
- HTMLをホスト言語とした場合のARIAの位置付けを規定している
- Using ARIA
- W3Cのワーキンググループノート
- WAI-ARIA Authoring Practices
- W3Cのグループノート
- 本格的なウィジェットの実装例が紹介されている
- WAI-ARIA仕様
- role属性
- 要素のロールを指定する
- ASCII空白文字で区切って複数指定できる
- フォールバックのためなので、適用可能な先頭が適用される
<div role="dummyrole blockquote ...">...</div>
- 抽象ロールは指定できない
- ロールの上書き
- ホスト言語がもともと持つロールを「暗黙のネイティブロール(inplicit native role)」と呼ぶ
- role属性で上書きできる
-
<a href="/register" role="button">...</a>
- link -> button に上書きしている
- 上書きするのはセマンティクスだけ
- 機能は変更しない
- スペースキーでボタンを押せるようにはならない
- 機能は変更しない
- ネイティブロールを上書きできるが、機能と矛盾するような指定はできない
- button -> heading など
- ホスト言語がもともと持つロールを「暗黙のネイティブロール(inplicit native role)」と呼ぶ
- 特殊な働きをするロール
- ランドマークロール
- ナビゲーションランドマークとして機能するもの
- mainまで読み飛ばすなどができる
- ナビゲーションランドマークとして機能するもの
- ライブリージョンロール
- live regionは内容が更新された際にユーザーに通知される領域
- ランドマークロール
- ロールの削除
- presentationロール, noneロール
- ネイティブロールを打ち消すロール
- タブコンポーネントの親子のロール関係を修復したいなど
- ネイティブロールを打ち消すロール
- presentationロール, noneロール
- 必須の所有要素が存在する場合のロール変更
- 親要素のロールだけを変更すると矛盾してしまう
- 代表的なaria-*属性
-
aria-hidden
属性(state)- true or falseを指定する
- アクセシビリティAPIに公開されず、支援技術からアクセス不可となる
- 意味を持たないアイコンをアイコンフォントで表現するときなど
-
aria-label
属性(property)- 要素にラベル付けする文字列を定義する
- "X"を閉じるボタンとしたときに
aria-label="閉じる"
とするなど- 「エックスボタン」ではなく「閉じるボタン」と読み上げるようになる
- "X"を閉じるボタンとしたときに
- aria-labelの使いすぎに注意
- 名前付けできないロールもある
- spanなど
- 要素にラベル付けする文字列を定義する
-
aria-labelledby
属性(property)- 属性値にラベルを含む要素のIDを指定する
-
aria-labelledby="billing name"
- 元あったラベルは上書きされる
-
- 属性値にラベルを含む要素のIDを指定する
-
aria-describedby
属性(property)- 使い方はaria-labelledbyとほとんど同じ
- 説明を付与できる
- 使い方はaria-labelledbyとほとんど同じ
-
aria-current
属性(state)- current itemであることを示せる
- 「現在のページ」と読み上げるなど
- current itemであることを示せる
-
aria-haspopup
属性(property)- 指定した要素がポップアップする何かを持っていることを示せる
-
aria-expanded
属性(state)- expandするかや開閉状態を示せる
-
aria-controls
属性(property)- aria-expandedと組み合わせて使う
-
aria-level
属性(property)- 見出しレベルを示す
- h7も表現できる
- 見出しレベルを示す
-
aria-live
属性(propetry)- 要素をライブリージョンとして定義できる
- 動作を変更できる
- 挙動変更は推奨されない
- 動作を変更できる
- リアルタイム通知や部分的更新などで使用される
- 要素をライブリージョンとして定義できる
-
aria-atomic
属性(property)- ライブリージョンに変更があったときに差分だけを通知するかどうか設定できる
- falseだと、時計の値が17:33 -> 17:34となったときは4のみ通知される
- デフォルトはtrue
- ライブリージョンに変更があったときに差分だけを通知するかどうか設定できる
-
- W3CのWAIによって発行されている仕様
- ARIA利用時の注意点
- 誤用や使いすぎに注意する
- 「ARIAを使う際にもっとも注意すべきことは、ARIAを使わないようにすることです」
- 基本的な注意点
- まずHTML自身の機能を利用する
- 冗長なロールやARIA属性を使用しない
-
<main role="main">
など - ネイティブセマンティクスをむやみに変更しない
-
<h2 role="tab">
など-
<div role="tab"><h2>見出しタブ</h2></div>
とする
-
-
-
- インタラクティブコンテンツを扱う際の注意点
- マウスやタッチで操作可能なものはキーボードでも操作可能にする
- WAI-ARIAは機能は追加しないので注意
- 操作可能な要素を隠さない
- フォーカス可能な要素にaria-hidden="true"などをつけない
- マウスやタッチで操作可能なものはキーボードでも操作可能にする
- アクセシブルな名前を与える方法
- 要素のテキストや、画像のaltなどがアクセシブルな名前となる
- 操作可能でない要素にアクセシブルな名前を与える
- ランドマークに名前を与える
-
<nav aria-label="パンくずナビゲーション">
- 複数navがある場合に区別できるようになる
-
- ランドマークに名前を与える
- ARIA実装時の基本テクニック
- アクセシブルな名前を提供する方法
- テストを行い、警告に注意する
- 可視のテキストを使う
- フローティングラベル手法で可視のラベルテキストを確保できる
- HTMLのネイティブ機能を使う
- ブラウザーのフォールバックに頼ることは避ける
- 簡潔で有用な名前を付ける
- スクリーンリーダー向けテキストを提供する
-
class="visually-hidden"
などで指定する- https://github.com/twbs/bootstrap/blob/main/scss/mixins/_visually-hidden.scss
- ただ、「操作可能な要素を隠さない」と競合する
-
- キーボードフォーカスを制御する
- フォーカスを当てた後に何か操作させたいときはJSで実装する
- アクセシブルな名前を提供する方法
- 動作検証とアクセシビリティサポーテッド
- スクリーンリーダーによって動作検証する
- フィードバックとして利用ユーザーの意見を聞く
- スクリーンリーダーによって動作検証する
- 誤用や使いすぎに注意する
- WAI-ARIAの実践
- 事例1:
div
で開閉buttonを作ったハンバーガーメニュー- どう改善するか
- キーボード操作を可能にする
- divではフォーカスが当てられない
- 方法1: button要素とする
- 方法2: a要素を使用する(非推奨)
-
role=button
としてもボタンと同じ挙動にはならないので可能な限りbutton要素を使用すべき
-
- 方法3: divのままキーボード操作可にする(非推奨)
-
tabindex=0 role=button
として、JSでkeypressイベントをつける
-
- divではフォーカスが当てられない
- 何のボタンかわかるようにする
- 方法1: 画像をimg要素にしてaltをつける
- 方法2: スクリーンリーダー用テキストを入れる
- 方法3: aria-labelを利用する
- 方法4: aria-huspopupを利用する
- メニューの開閉状態がわかるようにする
- 方法1: 開いたメニューにフォーカスを移す
- 方法2: ボタンのラベルで状態を伝える
- 方法3: aria-expandedを利用する
- メニューの裏側にフォーカスが当たらないようにする
- 方法1: メニューの外の要素をすべてフォーカス不可にする
- 方法2: フォーカス移動するときにメニューの先頭に戻す
- メニューの最後の要素にkeypressイベントをつけるなど
- 方法3: フォーカス移動しようとした場合にメニューを自動的に閉じる
- キーボード操作を可能にする
- どう改善するか
- 事例2: カルーセルのライブラリーを選定する
- キーボード操作可能か
- フォーカスが明確に見えるかどうかも確認する
- フォーカス時のローテーション停止
- スクリーンリーダーで操作できるか
- 他の箇所の読み上げを妨害しないか
- カルーセルがライブリージョンとして扱われるなど
- ローテーションごとに読み上げられる
- カルーセルがライブリージョンとして扱われるなど
- ローテーションコントロールがあるか
- キーボード操作可能か
- 事例3: タブのマークアップを検討する
- tab, tablist, tabpanelはHTMLネイティブ要素にはない
- role属性で指定する
- タブ
-
a
またはbutton
要素を使う-
<button type="button" role="tab" id="tab01" aria-controls="tabpanel01" aria-selected="true">タブその1</button>
など- JSで
aria-selected=true
とtabindex=-1
を操作する
- JSで
-
-
- タブリスト
- どの要素を採用するかは議論の余地がある
- menu, ol, ul, navなど
- WAI-ARIA Authoring Practicesでは
div
要素を使用している
- どの要素を採用するかは議論の余地がある
- タブパネル
-
section
かdiv
-
- タブの操作方法をあえて実装しない選択もある
- ただ省スペース化するだけならulとページ内リンクでもいい
- tab, tablist, tabpanelはHTMLネイティブ要素にはない
- 事例4: モーダルダイアログ
- dialogは対話なので、ユーザー操作を受け付けない通知領域はdialogとは呼ばない
- WAI-ARIAを駆使した実装
- divに
role=dialog
を指定する -
tabindex=0
でフォーカストラップを行う
- divに
- 事例5: インラインSVGのアクセシビリティを担保する
- svg要素はデフォルトのロールがimg要素とは異なる
- graphics-documentロール
- 画像なら
role=img
と指定する
- svg要素はデフォルトのロールがimg要素とは異なる
- 画像の代替テキストと説明を提供する
- インラインでSVGを使用するとき
- 画像の代替テキストと説明文をSVGの中で与えるようにする
- 装飾的なSVG画像を無視させる
-
aria-hidden=true
とする- img要素の
alt=""
と同じ
- img要素の
-
- インラインでSVGを使用するとき
- 事例1:
Discussion