Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
多様なユーザーニーズに応えるフロントエンドデザインパターン:入力フォーム編
Rikiya Ihara
March 15, 2018
0
9
多様なユーザーニーズに応えるフロントエンドデザインパターン:入力フォーム編
Rikiya Ihara
March 15, 2018
Tweet
Share
More Decks by Rikiya Ihara
See All by Rikiya Ihara
電子決済等代行事業者協会 アクセシビリティ勉強会「Webアクセシビリティの概要」
magi1125
0
30
noteアクセシビリティ勉強会 〜画像編〜
magi1125
0
12
自社サービスのアクセシビリティ向上、良いパターンとアンチパターン
magi1125
0
12
ユビーAI受診相談でほんとうに起きていた怖い話
magi1125
0
10
noteアクセシビリティ勉強会〜虚空編〜
magi1125
0
8
春だ!既存プロダクトのWebアクセシビリティ改善ことはじめ
magi1125
0
8
Disabilityとデザイン
magi1125
0
8
東京都新型コロナ対策サイトのアクセシビリティ改善を語る
magi1125
0
5
UXデザインなんでも聞いて委員会
magi1125
0
9
Featured
See All Featured
How New CSS Is Changing Everything About Graphic Design on the Web
jensimmons
214
12k
Rails Girls Zürich Keynote
gr2m
87
12k
Learning to Love Humans: Emotional Interface Design
aarron
263
38k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
349
27k
What the flash - Photography Introduction
edds
64
10k
The Web Native Designer (August 2011)
paulrobertlloyd
76
2.2k
Git: the NoSQL Database
bkeepers
PRO
419
60k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
152
13k
Debugging Ruby Performance
tmm1
67
11k
Music & Morning Musume
bryan
37
4.6k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
32
6.7k
A better future with KSS
kneath
230
16k
Transcript
多様なユーザーニーズに応える フロントエンドデザインパターン 〜入力フォーム編〜 伊原 力也 2018.03.15 1
伊原 力也 2 • freee IA/UX • HCD-Net 評議委員 /
認定人間中心設計専門家 • ウェブアクセシビリティ基盤委員会 WG1委員 • 国際ユニヴァーサルデザイン協議会 移動空間研究部会 副主査
https://www.hcdnet.org 3
https://waic.jp 4
Amazonで「アクセシビリティ」と検索! 5
6 Amazonで「インクルーシブHTML」と検索!
7 Amazonで「インクルーシブHTML」と検索!
この本は? 普及しているUIについて、アクセシブルなデザインパターンを提供 • 「やるな」ではなく「こう実装するとアクセシブル」という話 (とはいえ、これはやってはダメ、という話ももちろんある) • ブログ記事、ナビゲーション、メニューボタン、 商品リスト、フィルターウィジェット、登録フォームなど 8
9 + Accessibility
10
11
12 スライド 動画
今日はフォームの アクセシビリティの話をします 13
webをインタラクティブにしているのは リンクとフォームだから 14
15
フォームといえば • 入力欄とラベル • エラー表示 16
入力欄とラベル 17
入力欄とラベルのポイント 18 1. 入力項目とラベルを明示的に関連付ける 2. 見た目でも入力項目とラベルの対応を明確に 3. 何が起きるか明白なラベルにする 4. プレースホルダをラベル代わりにしない
5. 必須と任意を明示する 6. 入力条件は先に提示する
Point 1 入力項目とラベルを明示的に関連付ける <form id="register"> <label for="email">メールアドレス</label> <input type="text" id="email"
name="email"> <label for="username">ユーザー名</label> <input type="text" id="username" name="username" placeholder="例:HotStuff666"> <label for="password">パスワード</label> <input type="password" id="password" name="password"> <button type="submit">登録する</button> </form> 19
Point 1 入力項目とラベルを明示的に関連付ける <form id="register"> <label for="email">メールアドレス</label> <input type="text" id="email"
name="email"> <label for="username">ユーザー名</label> <input type="text" id="username" name="username" placeholder="例:HotStuff666"> <label for="password">パスワード</label> <input type="password" id="password" name="password"> <button type="submit">登録する</button> </form> 20
明示的に関連付けると この例では、スクリーンリーダーユーザーが パスワードフィールドにフォーカスを合わせると、 「パスワード エディット、保護つき」などと読み上げられます。 21
明示的に関連づけるべき理由 スクリーンリーダーユーザーがどのように フォーム内を移動するかを理解する必要があります。 散文的なコンテンツでは、ユーザーは下矢印キーを使って 要素間を順に移動しますが、フォームでは異なり、 あるフィールドから次のフィールドへ直接移動する操作が行われます。 このとき、ラベル要素は飛び越されてしまいます。 ラベル要素とインタラクティブ要素が明示的に関連づけられていない場合、 そのラベル要素は見逃されてしまうのです。 22
Point 2 見た目でも入力項目とラベルの対応を明確に 23
Point 2 見た目でも入力項目とラベルの対応を明確に 24
labelの応用例 25
択一選択なのでラジオボタン+labelに <input type="radio" name="sort-method" id="most-recent" checked /> <label for="most-recent">新着順</label> 26
隣接セレクタでlabelにスタイルを付ける [type="radio"] + label { cursor: pointer; /* その他、基本のスタイル */
} [type="radio"]:focus + label { /* フォーカス時のスタイル */ } [type="radio"]:checked + label { /* 選択時のスタイル */ } 27
ラジオボタンを力強く隠す .sorter [type="radio"] { position: absolute !important; width: 1px !important;
height: 1px !important; padding:0 !important; border:0 !important; overflow: hidden !important; clip: rect(1px, 1px, 1px, 1px); } 28
Point 3 何が起きるか明白なラベルにする 29
Point 3 何が起きるか明白なラベルにする 30
Point 3 何が起きるか明白なラベルにする 31
Point 4 プレースホルダをラベル代わりにしない 32
スペース節約とひきかえにユーザビリティが犠牲に 33
代用すると何が起きるのか 34 • 文字を打ち始めた瞬間にラベルが消えてしまうため 何の項目か覚えておかねばならず認知負荷が高まる • placeholderをサポートしないスクリーンリーダーや ブラウザだと情報が失われて意味不明になる • ブラウザのオートコンプリート機能で複数のフィールドが
一気に埋められた際、適切に入ったか確認できない
35 http://bradfrost.com/blog/post/float-label-pattern/
本当にplaceholderである場合でも、文字色には注意 36
文字色を濃くしつつ、スタイルを変える ::placeholder { color: #000; font-style: italic; } ::-webkit-input-placeholder {
color: #000; font-style: italic; } ::-moz-placeholder { color: #000; font-style: italic; } ::-ms-input-placeholder { color: #000; font-style: italic; } 37
Point 5 必須と任意を明示する 38
Point 5 必須と任意を明示する 39
ありがちな対応 <label for="email">メールアドレス <strong class="red">*</strong></label> <input type="text" id="email" name="email"> 40
より正確を期するなら <label for="email">メールアドレス <strong class="red" aria-hidden="true">*</strong></label> <input type="text" id="email" name="email"
aria-required="true"> 41
required属性というのもあるが… 望ましくない挙動になることもあります。 初期状態で空になっている必須フィールドをエラーとして扱ってしまう、 といった動作です。今回の用途としては、これはやや冗長で、 アグレッシブすぎます。 42
43 Point 6 入力条件は先に提示する
Point 6 入力条件は先に提示する 44
ツールチップ的に出すやりかたも 45
スクリーンリーダーも読み上げる 46
47 <form> <fieldset> <legend>ログインフォーム</legend> <div> <label for="username">ユーザー名</label> <input id="username" type="text"
aria-describedby="username-hint"> <div role="tooltip" id="username-hint">ユーザー名には、あなたの Eメールアドレス を登録してください</div> </div> <div> <label for="password">パスワード</label> <input id="password" type="password" aria-describedby="password-hint"> <div role="tooltip" id="password-hint">メールでお送りしたパスワードを入れてくださ い</div> </div> </fieldset> <button type="submit">サイトに入る</button> </form>
[role="tooltip"] { background: orange; color: white; padding: 0.25em; display: none;
} input:focus + [role="tooltip"] { display: block; } 48 フォーカス時にツールチップを出すCSS
49 そうそう、もう1点
50 http://www.outlinenone.com/
入力欄とラベルのポイント:おさらい 51 1. 入力項目とラベルを明示的に関連付ける 2. 見た目でも入力項目とラベルの対応を明確に 3. 何が起きるか明白なラベルにする 4. プレースホルダをラベル代わりにしない
5. 必須と任意を明示する 6. 入力条件は先に提示する 7. フォーカスインジケーターは消さない
エラー表示 52
エラー表示のポイント 53 1. エラーはフォーム内に出す 2. エラー状態が伝わるようにする 3. エラー箇所を明確にする 4. エラーの修正を助けるメッセージを出す
5. リアルタイム検証は慎重に使う
54 Point 1 エラーはフォーム内に出す
Point 2 エラー状態が伝わるようにする 55
Point 2 エラー状態が伝わるようにする 56 登録する
送信を止め、送信ボタンの上にエラーを出す例 57 <div id="error" aria-live="assertive" role="alert"></div> <button type="submit">登録する</button> #error:empty {display:
none;} var form = document.getElementById('register'); form.addEventListener('submit', function(event) { if (errors) { event.preventDefault(); // 送信させない document.getElementById('error').textContent = '登録情報が正しいことを 確認してください。' } });
アイコン画像とaria-labelでエラーをより明白に 58 <div id="error" aria-live="assertive" role="alert"> <p> <svg role="img" aria-label="エラー:">
<use xlink:href="#error"></use> </svg> 登録情報が正しいことを確認してください。 </p> </div>
ライブリージョンの良いところ ライブリージョンでエラーの存在を宣言することのメリットは、 ユーザーに移動してもらわなくてもエラー情報に注意を促せる点です。 エラーになっている入力欄にフォーカスを移すことで、 フォームエラーをユーザーに警告するという方法もよく見られます。 しかし、このお節介とも言える唐突なアプリケーション内での位置移動は、 ユーザーを混乱させる恐れがあります。 59
ありがちな「勝手にフォーカス移動」に注意 60
ありがちな「勝手にフォーカス移動」に注意 61
Point 3 エラー箇所を明確にする 62
Point 4 エラーの修正を助けるメッセージを出す 63
Point 3 Point 4 改善案 64
invalidを伝え、説明文を紐付ける/アイコンを出す 65 <label for="password">パスワード</label> <input type="password" id="password" aria-invalid="true" aria-describedby="password-hint"> <div
id="password-hint">パスワードは6文字以上にしてください。</div> </label> [aria-invalid="true"] { border-color: red; background: url('images/warning-icon.svg') center right; }
実際の例 66
Point 5 リアルタイム検証は慎重に使う しゃれたフォーム検証スクリプトの中には、テキストを入力している時に リアルタイムでフィードバックを提供し、入力している内容が有効かどうか、 入力している最中に知らせてくれるものもあります。 しかし、こうしたスクリプトは管理が非常に難しくなることがあります。 特定の文字数が必要なエントリーでは、最初の何回かの キーストロークの間は常に無効なエントリーと見なされてしまうからです。 67
問題なし:入力中に残りの入力可能文字数を示す 68
問題あり:入力中にメールアドレス妥当性チェック 69
80年代のリミックスモード ライブリージョンのエラーメッセージが 繰り返し更新される実装になっている場合、スクリーンリーダーは 80年代のリミックスモードに入ります。 「パ、パス、パ、パスワード、パスワードは6文字以上にしてください」 などと読み上げられることになります。 70
対応案 71 1. キーストロークがあいたら発動するよう制御する ◦ 打ち込むたびに検証するとライブリージョンが都度読まれてしまう 2. そもそもリアルタイム検証が必要か再考する ◦ onblur時に再検証してaria-invalidの値を変えれば十分では?
3. 必要な場合でも送信時エラー後にリアルタイム検証を発動させる ◦ 初期入力時からリアルタイム検証する必要は薄いのでは?
エラー表示のポイント:おさらい 72 1. エラーはフォーム内に出す 2. エラー状態が伝わるようにする 3. エラー箇所を明確にする 4. エラーの修正を助けるメッセージを出す
5. リアルタイム検証は慎重に使う
フォームがアクセシブルになると 多くの人のユーザビリティも向上する 73
webをインタラクティブに 使える人が増える 74
ということで 75
Amazonで「アクセシビリティ」と検索! 76
77 Amazonで「インクルーシブHTML」と検索!
Amazonで「インクルーシブHTML」と検索! 78
今日からあなたも インクルーシブデザイナー! 79
80 エンジニア・UXデザイナー積極採用中!
ありがとうございました @magi1125 81