@masuP9(わかり手) 株式会社サイバーエージェント
@o_ti(キレ手) 株式会社まぼろし
広義のセマンティクスと今回のセマンティクス
今日はいくつかある未来の中からある一つの未来の話をします
ウェブがよりアクセシブルになる。
HTMLというだけで得られるアクセシビリティ
※電源とWi-Fiがあれば
etc...
<section>
<h2>見出し</h2>
<p><a href="#">パラグラフ</a></p>
<ul>
<li>リスト</li>
<li>リスト</li>
</ul>
<button type="button">ボタン</button>
</section>
タグ(要素)によってセマンティクスを
要素の記述順と入れ子によって構造を構築
要素名(タグ)に依存する
非同期通信で画面が書き換わるアプリケーションなウェブサイトが広まり、現状のHTMLのネイティブセマンティクスでは足りなくなっている
モーダルなダイアログをHTML要素で表現できる
<button id="confirm">確認</button>
<dialog id="privacy-policy">
<h1>プライバシーポリシー</h1>
<p>同意せよ</p>
<button id="agree">同意します</button>
</dialog>
副次的な見出し/キャッチコピー/スローガンを
マークアップできる。
<section>
<hgroup>
<h1>deisui_html_radio #sp1</h1>
<h2>〜マークアップは裏切らない〜</h2>
</hgroup>
<p>我々はJSフレームワークと戦い、マークアップ共和国を作りました。</p>
</section>
まだ見ぬ要素も追加される可能性は十分ある
HTML以外のセマンティクスと言えば?
etc...
よくあるMicrodataで提供されたセマンティクス
確かに現在のHTMLにないセマンティクスを提供するが、
これらはどちらかというとデータ構造を俯瞰したものを提供する力が強い。
そのウェブページ上で利用するというよりは、外部ツール(検索エンジン)がパースしてそのウェブページの外で使われている。
やりたいのはそのウェブページ自体のセマンティクスの強化なんだよ!!!
アプリケーションなウェブページをアクセシブルにするため、HTML(ホスト言語)のセマンティクスを補強するための仕様
role
aria-*
<ul role="tree" aria-label="menu tree">
<li role="treeitem" aria-selected="true">...</li>
<li role="treeitem" aria-selected="false">...</li>
</ul>
role
<ul role="tree"></ul>
これはツリーウィジェットである
<li role="treeitem" aria-selected="true">...</li>
このツリーアイテムは選択されている/されてない
<ul role="tree" aria-label="menu tree"></ul>
このツリーウィジェットの名前プロパティはmenu tree
である
DOMツリーに依存しない関係性を定義できる。
パスワードは8文字以上必要です。
<label>パスワード:
<input type="password" aria-describedby="description" />
</label>
<p id="description">パスワードは8文字以上必要です。</p>
同じ表示領域で内容が切り替わるウィジェット
role="tablist"
role="tab"
role="tabpanel"
aria-selected
aria-hidden
<nav>
<ul>
<li>
<a href="#tabItem1">越智</a>
</li>
<li>
<a href="#tabItem2">桝田</a>
</li>
</ul>
</nav>
<div>
<div id="tabItem1">キレ手</div>
<div id="tabItem2">わかり手</div>
</div>
<nav>
<ul role="tablist">
<li role="presentation">
<a href="#tabItem1" role="tab" aria-controls="tabItem1" aria-selected="true" id="tabBtn1">越智</a>
</li>
<li role="presentation">
<a href="#tabItem2" role="tab" aria-controls="tabItem2" aria-selected="false" id="tabBtn2">桝田</a>
</li>
</ul>
</nav>
<div>
<div id="tabItem1" role="tabpanel" aria-describedby="tabBtn1" aria-hidden="false">キレ手</div>
<div id="tabItem2" role="tabpanel" aria-describedby="tabBtn2" aria-hidden="true">わかり手</div>
</div>
更新される領域であることを支援技術に伝える
etc...
<div role="log" aria-live="polite">
<ol>
<li>魔界合宿</li>
<li>「人はすぐ死ぬ」</li>
<li>伊東家のこじらせ</li>
<li>マスみがある</li>
</ol>
</div>
<div role="log" aria-live="polite">
<ol>
<li>魔界合宿</li>
<li>「人はすぐ死ぬ」</li>
<li>伊東家のこじらせ</li>
<li>マスみがある</li>
<li>例え話下手くそ選手権優勝</li> <!-- New -->
</ol>
</div>
WAI-ARIAはホスト言語と相互に進化していく
e.g. role="switch"
👉 input[type="switch"]
WAI-ARIAは補強するもので代替では無い
これらの付与されたセマンティクスはどのようにユーザー(支援技術)に伝わるか
OSが支援技術にセマンティクスなどの
情報を伝えるAPI
ブラウザがレンダリングしているコンテンツと
セマンティクスをアクセシビリティAPIの
オブジェクトに変換して支援技術に伝える
要素に属性として付与しないといけない
canvas
の中のUIなどid
が必要アクセシビリティAPIに変換されうるセマンティクスをモデルとして定義しJavaScriptから操作・探索可能にしたもの(ないしは提案)
const tree = document.createElement('ul');
tree.role = 'tree';
tree.ariaLabel = 'menu tree';
const desc = document.querySelectorAll('.tree-desc');
tree.ariaDescribedBy = [...desc].map(el => el.id).join(' ');
See the Pen Demo: AOM Reflecting ARIA attributes by masuP9 (@masuP9) on CodePen.
tree.accessibleNode.role = "tree";
tree.accessibleNode.label = "menu tree";
id
が必要さっきのこれ
const desc = document.querySelectorAll('.tree-desc');
tree.ariaDescribedBy = [...desc].map(el => el.id).join(' ');
こうしたい!
const desc = document.querySelectorAll('.tree-desc');
tree.ariaDescribedByElements = [...desc];
class TabListElement extends HTMLElement { ... }
customElements.define(
"custom-tablist",
TabListElement,
{ role: "tablist", ariaOrientation: "horizontal" });
Web ComponentsでのshadowRoot
問題
支援技術が起こすイベントをDOMのイベントに
ルーティングしハンドリングすることができるようにする。
<button type="button" onclick="alert('click!')">button</button>
現状、支援技術のイベントをルーティングするにはDOMのイベントが足りない。
role="slider"
の増加/減少イベントなど
<input type="range" />要素上のみハンドリング可能
See the Pen Demo: Listen for input events from AT by masuP9 (@masuP9) on CodePen.
element.accessibleNode.addEventListener('accessibleclick', function);
element.addEventListener('accessibleclick', function);
プライバシーの問題
canvas
などで作られたUIに対して仮想のアクセシビリティノードを付与する。
const canvas = document.getElementById('canvas');
canvas.attachAccessibleRoot();
const table = canvas.accessibleRoot.appendChild(new AccessibleNode());
table.role = 'table';
See the Pen Demo: Build virtual accessible nodes out-of-date syntax by masuP9 (@masuP9) on CodePen.
ここでもプライバシーの問題?
計算されたアクセシビリティツリーを確かめる。
const tree = document.createElement('ul');
tree.role = 'tree';
window.getComputedAccessibleNode(tree).then(result => {
console.log(result.role); // 👉 'tree';
});
非同期で取得する
See the Pen Demo: Query computed Accessible Tree table display: block; table by masuP9 (@masuP9) on CodePen.
当初はDOMのElement
に関連付けられたAccessibleNode
からプロパティを
読み書きする方針だった
以下のような問題があり、AccessibleNode ではなく簡素なAPIへの提案へ以降
element.accessibleNode.role = 'tree';
console.log(element.accessibleNode.role) // 本当に 'tree' 🤔
単純な参照では無い。
書き込みと読み取りを共通化しない
element.role = 'tree';
window.getComputedAccessibleNode(element).then(result => {});
Chrome 70 | Firefox NB*1 | Safari TP*2 | |
---|---|---|---|
Reflect ARIA attributes | Yes*3 *4 | No | No |
Listen for input events from AT | No | No | No |
Build virtual accessible nodes | Yes *5 | No | No |
Query computed accessibility tree | Yes | No *6 | No |