こんにちは、アプリケーションエンジニアの id:nanto_vi です。はてなでは週 1 回、エンジニアとデザイナーが参加する社内勉強会が開かれています。その勉強会にて「少しずつアクセシビリティ意識する」という発表を行ったので、発表資料を公開します。
- なぜするの?
- 何をするの?
- とりあえず何をするの?
- 例: テキストラベルを付与する
- 例: キーボードで操作できるようにする
- 例: キーボードで操作している場所が分かるようにする
- 例: マウスホバーでもタブ移動でもメニューが開くようにする
- 例: 文字を読みやすい色にする
- 例: 入力手段を限定しない
- 終わりに
なぜするの?
ミッション - 株式会社はてな
- コミュニケーションや、情報との出会いの機会を増やすことで、社会を豊かにします
事業者は、その事業を行うに当たり、(略) 障害者の権利利益を侵害することとならないよう、(略) 社会的障壁の除去の実施について必要かつ合理的な配慮をするように努めなければならない。
障害を理由とする差別の解消の推進に関する法律 - 内閣府
- 「障害者が利用しやすく」ではなく、「ほとんどの人にとって利用しやすく」
- 誰でも不自由な状況になりうる
- メガネのフレームが割れた
- 利き手を骨折した
- 通信量制限で低速回線になった
何をするの?
Web Content Accessibility Guidelines (WCAG) 2.0 の 4 原則
- 知覚可能
- 情報や機能の存在がわかる
- 操作可能
- 情報を読み取れる、機能を使える
- 理解可能
- 情報を読み解ける、どんな機能かわかる
- 堅牢性
- どこでも、どんなときも
とりあえず何をするの?
- 簡単にチェックできる、機械的にチェックできることから
- macOS の VoiceOver (Command + F5 でオンオフ) は読み上げ内容が文字でも表示されるので便利
- 個人的にまずやっておきたいのは
- テキスト情報も提供する
- キーボードだけでも操作可能にする
例: テキストラベルを付与する
<!-- OK --> <button type="button"> <img src="star.png" alt="お気に入りに追加"> </button>
<!-- OK --> <button type="button" aria-label="お気に入りに追加"> <i class="icon icon-star"></i> </button>
アイコンフォントを使った例について (2017-08-30 16:00 追記)
上の例で空の i
要素を使ったものは、既にアイコンフォントが使われている箇所への暫定的な対処に過ぎません。aria-label
だけに頼るのではなく、従来からある手段でもテキスト情報をつけたほうがいいでしょう。
元記事にもある、ボタンの中に <img> を入れた方の例がもっともスマートかつアクセシブルだと思います。空の <i> は既存コードを変えられないときや、何らかの事情で background-image で表示せざるを得ないときのやむを得ない対処法という認識ですね。
— 富永冴樹 (@SaekiTominaga) August 30, 2017
例: キーボードで操作できるようにする
Tab
で移動、Space
で選択 (チェックボックスやラジオボタンのチェック)、Enter
で実行できるように- 「クリックしたら何かが起こる」部分には
button
要素を使うのが無難- 既存の HTML 要素で表現できるならそちらが優先 (
<a href="">
、<input type="">
など)
- 既存の HTML 要素で表現できるならそちらが優先 (
<!-- NG --> <span onclick="addItem();">追加する</span>
<!-- OK --> <button type="button" onclick="addItem();">追加する</button>
例: キーボードで操作している場所が分かるようにする
Twitter では、Tab
でボタンにフォーカスを移すと、ツールチップが表示されたりフォーカスリングが表示されたりする。
- フォーカスリングを消さない
- フォーカスリングを消すなら、代わりに背景色を変えるなどする
- フォーカスリングは CSS の
outline
やbox-shadow
で表現されることが多い
- CSS で
:hover
だけでなく:focus
も指定する
/* NG */ .nav-link { outline: 0; } .nav-link:hover { background-color: #6ff; }
/* OK */ .nav-link:hover, .nav-link:focus { background-color: #6ff; }
例: マウスホバーでもタブ移動でもメニューが開くようにする
<div class="container"> <button type="button" aria-label="編集">▼</button> <ul class="menu"> <li><button type="button">この項目を移動する</button></li> <li><button type="button">この項目をコピーする</button></li> </ul> </div>
/* NG */ .menu { display: none; } .container:hover .menu { display: block; }
/* 依然として NG */ .menu { display: none; } .container:hover .menu, .container:focus .menu { display: block; }
:hover
疑似クラスは子孫要素上にマウスポインタがあるときにも適用される:focus
疑似クラスはその要素自身にフォーカスが置かれていないと適用されない
/* OK だが対応ブラウザが少ない */ .menu { display: none; } .container:hover .menu, .container:focus-within .menu { display: block; }
/* OK、JS の力も借りる */ .menu { display: none; } .container:hover .menu, .container.focus-within .menu { display: block; }
function emulateFocusWithin(container) { container.addEventListener('focusin', (event) => { if (event.relatedTarget && container.contains(event.relatedTarget)) return; container.classList.add('focus-within'); }); container.addEventListener('focusout', (event) => { if (event.relatedTarget && container.contains(event.relatedTarget)) return; container.classList.remove('focus-within'); }); if (document.activeElement && container.contains(document.activeElement) { container.classList.add('focus-within'); } }
例: 文字を読みやすい色にする
- 視力 0.5 (80 歳前後での標準的な視力) まで考慮すると
- 通常の大きさの文字ならコントラスト比 4.5 : 1 以上
- 大きな文字 (日本語文字の場合、22pt 以上または太字で 18pt 以上) ならコントラスト比 3 : 1 以上
- 3 : 1 以上でないと、厳しい (文字を読むのに集中力を要する) 場面が増える印象
#300 (18.4 : 1) | #030 (14.3 : 1) | #003 (20.0 : 1) |
#600 (13.4 : 1) | #060 (7.2 : 1) | #006 (17.6 : 1) |
#900 (8.9 : 1) | #090 (3.8 : 1) | #009 (14.4 : 1) |
#c00 (5.9 : 1) | #0c0 (2.2 : 1) | #00c (11.2 : 1) |
#f00 (4.0 : 1) | #0f0 (1.4 : 1) | #00f (8.6 : 1) |
#f33 (3.6 : 1) | #3f3 (1.4 : 1) | #33f (6.9 : 1) |
#f66 (2.9 : 1) | #6f6 (1.3 : 1) | #66f (4.3 : 1) |
#f99 (2.0 : 1) | #9f9 (1.2 : 1) | #99f (2.5 : 1) |
#fcc (1.4 : 1) | #cfc (1.1 : 1) | #ccf (1.5 : 1) |
例: 入力手段を限定しない
- 文字が入力されたことを検知したいなら、
keydown
/keyup
イベントではなくinput
/change
イベントを用いる- 文字パレット
- クリップボードからの貼り付け
- 手書き入力
- 音声入力
click
イベントはマウスクリックだけでなく、様々な入力手段で発生する
// NG textField.addEventListener('keydown', (event) => { suggestItems(textField.value); });
// OK textField.addEventListener('input', (event) => { suggestItems(textField.value); });
終わりに
ミッション - 株式会社はてな
- コミュニケーションや、情報との出会いの機会を増やすことで、社会を豊かにします
- 目の前の環境がすべてではないと意識することで、情報との出会いの機会をぐっと増やせる
- 社会を豊かにしていこう!
デザイニングWebアクセシビリティ - アクセシブルな設計やコンテンツ制作のアプローチ
- 作者: 太田良典,伊原力也
- 出版社/メーカー: ボーンデジタル
- 発売日: 2015/07/27
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (4件) を見る
コーディングWebアクセシビリティ - WAI-ARIAで実現するマルチデバイス環境のWebアプリケーション
- 作者: ヘイドン・ピカリング,Heydon Pickering,伊原力也,太田良典,株式会社Bスプラウト
- 出版社/メーカー: ボーンデジタル
- 発売日: 2015/03/27
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (1件) を見る
はてなではデザイナーが HTML と CSS (LESS、Sass) を、エンジニアが JavaScript (TypeScript、Flow) を書くので、フロントエンドのコーディングには両者の協力が欠かせません。また、文章やサービス内での導線などをわかりやすくするためには、企画職・編集職・ディレクターなどチームが一丸となって取り組みます。
アクセシビリティを向上させていくためには、これらチームメンバー全体で「自分が普段使っている環境以外にも、世の中にはたくさんの環境がある」ということを意識していく必要があると感じています。
コミュニケーションや情報との出会いの機会を増やすために、はてなで一緒に働いてみませんか?