--- title: CSS と JavaScript のアクセシビリティの ベスト・プラクティス slug: Learn/Accessibility/CSS_and_JavaScript tags: - Accessibility - Article - CSS - CodingScripting - Guide - JavaScript - Learn - color - contrast - hiding - unobtrusive - ひかえめ - アクセシビリティ - ガイド - コントラスト - 学習 - 色 - 隠す translation_of: Learn/Accessibility/CSS_and_JavaScript ---
CSS と JavaScript も、適切に使えばアクセシブルなウェブ体験を可能にしてくれる可能性がありますが、誤用すると、大幅にアクセシビリティを悪化させることがあります。本記事では、複雑なコンテンツでもできる限りアクセシブルにすることを保証するために考慮すべき、CSS と JavaScript のベスト・プラクティスのいくつかを概観します。
前提知識: | 基本的なコンピューターの知識、HTML と CSS と JavaScript に関する基本的な理解、アクセシビリティとは何かに関する理解。 |
---|---|
学習目標: | アクセシビリティを損わず、最大化するように、自身のウェブドキュメントで CSS と JavaScript を適切に使うことに慣れること。 |
CSS と JavaScript は、アクセシビリティに関して HTML と同じだけの直接的重要性があるわけではありません。ですが、それでも使い方によっては、アクセシビリティを高めることも損うこともありえます。別の言葉で言うと、自分の CSS と JavaScript の使い方によってドキュメントのアクセシビリティを台無しにしていないと確認するために、いくつかのベスト・プラクティスを考慮することが重要です。
CSS を見ることから始めましょう。
CSS を使って、どのような HTML 要素をどのように見せかけることも可能です。しかし、このことは、そうすべきだと意味しているわけではありません。「HTML: アクセシビリティの基礎」という記事でしばしば述べたように、可能な場合にはいつでも、役割にふさわしい意味の要素を使うべきです。そうしないと、混乱を巻き起こしかねませんし、あらゆる人にとっての——とりわけ障碍のあるユーザーにとっての——使い勝手の問題を引き起こしかねません。正しいセマンティクスを使うことは、ユーザーの予期することと大いに関係があります。つまり、要素とは、その機能にしたがって、特定の見かけをしており特定のふるまいをするものであり、こうした通常の慣習をユーザーは予期するものなのです。
一例として、開発者が見出し要素を適切に使ってコンテンツをマークアップしていなかった場合には、スクリーン・リーダーのユーザーは、見出し要素を通じてページの見通しを得ることができないでしょう。同様に、見出しのようには見えないように見出しにスタイルをつけた場合には、見出しは視覚的な目的を失ってしまいます。
大まかな目安はこうです。つまり、自分のデザインに合わせるように、ページ項目のスタイル付けを更新するのは構いません。しかし、その項目が予期されるのとは全然違う見かけになったり、予期されるのとは全然違うふるまいをしたりするほど大幅にスタイル付けを変えてはいけません。以下の節では、考慮すべき主な HTML 項目について概説します。
見出し、段落、リスト——これらは、ページの中心的テキストコンテンツです。
<h1>見出し</h1> <p>段落</p> <ul> <li>わたしのリストには</li> <li>二つの項目があるよ。</li> </ul>
ある種の典型的な CSS は以下のようなものかもしれません。
h1 { font-size: 5rem; } p, li { line-height: 1.5; font-size: 1.6rem; }
なすべきことは以下の通りです。
より詳しくは、HTML テキストの基礎とテキストのスタイリングを参照してください。
囲んでいるテキストに対して特定の強調を与えるインライン・マークアップは、たとえば以下のようなものです。
<p>そのお湯は<em>とても熱いよ</em>。</p> <p>表面に集まる水滴は、<strong>結露</strong>と呼ばれます。</p>
強調したテキストに対して、なんらかの単純な色付けを加えたいかもしれません。
strong, em { color: #a60000; }
けれども、なんらかの目立つ方法で強調要素をスタイル付けする必要はめったにないでしょう。太字とイタリック体のテキストという標準的慣習はとても認識しやすく、そのスタイルを変更することは混乱を招きかねません。強調についてのさらなる情報は、強調と重要性を参照してください。
略語、頭文字語、つまり頭文字で表したものを、その展開形と関連付けることを可能とする要素は、たとえば以下のようなものです。
<p>ウェブ・コンテンツは、<abbr title="Hypertext Markup Language">HTML</abbr>を使ってマークアップされています。</p>
この場合も、なんらかの単純な方法でスタイルを付けたいかもしれません。
abbr { color: #a60000; }
略語に対する公認のスタイル付けの慣習は、点線の下線です。そして、点線の下線から大きく逸脱するのは愚かしいことです。略語についてのさらなる情報は、略語を参照してください。
ハイパーリンク——ウェブ上の新たな場所に行く方法——は、たとえば以下のようなものです。
<p><a href="https://www.mozilla.org">Mozilla のホームページ</a>に来てくださいね。</p>
ある種のとても簡単なリンクのスタイル付けを以下に示します。
a { color: #ff0000; } a:hover, a:visited, a:focus { color: #a60000; text-decoration: none; } a:active { color: #000000; background-color: #a60000; }
標準的なリンクの慣習は、下線を引いた、標準状態とは異なる色 (デフォルトは青) と、そのリンクを以前にたどったことがある場合の別の色変化 (デフォルトは紫) と、そのリンクがアクティブになっている場合のさらに別の色 (デフォルトは赤) です。さらに、リンクにマウスオーバーした場合には、マウスポインターがポインターアイコンに変化しますし、リンクは、(たとえばタブキーを押して) フォーカスが当たったり、アクティブ化されたりすると、ハイライトされます。以下の画像は、Firefox でのハイライト (点線の輪郭線) と Chrome でのハイライト (青い輪郭線) の双方を示したものです。
ユーザーがリンクを対話的に操作する際にユーザーに対してフィードバックを与え続ける限りは、リンクのスタイルに関して創造性を発揮して構いません。状態が変化する際には何かが明確に生じるべきであり、かつ、ポインターカーソルも輪郭線も——この両者は、キーボード・コントロールを使う人々にとって非常に重要なアクセシビリティの助けなのです——除去するべきではありませんが。
ユーザーがウェブサイトにデータを入力できるようにする要素であり、たとえば以下のようなものです。
<div> <label for="name">お名前を入力してください</label> <input type="text" id="name" name="name"> </div>
form-css.html の例 (ライブも見てください) において、ある種の適切な例示的 CSS が見られます。
フォーム用に書く CSS のほとんどは、要素のサイズを変更したり、ラベルと入力欄を整列したり、それらをすっきり整えたりするためのものでしょう。
ですが、フォーム要素にフォーカスが当たったときにそのフォーム要素が受けとる、予期された視覚的フィードバックからは、逸脱しすぎるべきではありません。そのことは、リンクの場合 (上記参照) と基本的に同様です。フォームのフォーカス / ホバー状態に対してスタイルを付けて、このふるまいがブラウザ間でより首尾一貫したものとなるようにしてもよいでしょうし、あるいは、自分のページ・デザインとより良く適合するようにしてもよいでしょう。しかし、予期される視覚的フィードバックをすべて捨て去ってはなりません。再び言いますが、これらの手がかりが、何が起きているのかを知る手助けになってくれるだろう、と人々は当てにしているのです。
表データを提示するためのテーブルです。
table-css.html の例 (ライブも見てください) において、テーブルの HTML と CSS の、適切で簡潔な例を見られます。
テーブル CSS は一般に、テーブルを自分のデザインによりうまく適合させて、見苦しさを減らすのに役立ちます。テーブルの見出しが目立つようにすること (普通は太字を使います)、異なる行同士が見分けやすいようにシマウマ的配色を使うことは、良い考えです。
自分のウェブサイト用のカラー・スキームを選ぶときには、テキスト (前景) の色が背景色と十分に差があることを確認してください。あなたのデザインはかっこよく見えるかもしれませんが、もし色盲などの視覚障碍のある人々がコンテンツを読めなかったら、まったく良いデザインではありません。
問題を起こさない程度に十分にコントラストが大きいかどうかを調べる簡単な方法があります。前景色と背景色を入力して調べることができる、コントラストのチェック用ツールが、オンライン上にいくつもあります。たとえば、WebAIM の Color Contrast Checker は、簡単に使えますし、色のコントラストに関して WCAG の基準に適合するためには何を行えば良いのかについて、説明もしてくれます。
注意: コントラスト比を高くすることによって、光沢のある画面のスマートフォンまたはタブレットを使う人が陽光のような明るい環境でページを読みやすくもなるでしょう。
もう一つ別のコツは、標識や案内について色だけに頼らないことです。というのも、色だけに頼るのは、色が見えない人々にとってまったく良くないからです。必須のフォーム・フィールドを赤でマークする代わりに、たとえば、アスタリスクと赤でマークしましょう。
すべてのコンテンツをいちどきに示さないことを視覚的デザインが求めているような、多くの事例があります。たとえば、Tabbed info box example の例 (ソースコードを参照) では、三つの情報パネルがありますが、それらをお互いの上に配置しており、クリックするとそれぞれの情報パネルを表示できるタブを設けています (これはキーボード・アクセシブルでもあります。つまり、情報パネルを選ぶのに、クリックする代わりに、タブキーとエンターキー / リターンキーとを使うこともできます)。
スクリーン・リーダーのユーザーは、こうしたことは何も気にしません。ソースの順序が意味をなしている限りはコンテンツに満足しますし、コンテンツすべてに到達できます。(この例で使われているような) 絶対的な位置指定は、一般的に、視覚効果のためにコンテンツを隠す最善の仕組みの一つとして見られるものです。なぜなら、これは、スクリーン・リーダーがコンテンツに到達するの邪魔しないからです。
一方で、 {{cssxref("visibility")}}:hidden
も {{cssxref("display")}}:none
も、スクリーン・リーダーからコンテンツを隠してしまうので、使うべきではありません。もちろん、スクリーン・リーダーからこのコンテンツを隠したいと思う然るべき理由がない限りは、ということですが。
注意: Invisible Content Just for Screen Reader Users には、この話題をめぐる多くのさらに有用な詳細があります。
ユーザーは、自分のカスタム・スタイルでスタイルを上書きできます。たとえば以下のとおりです。
ユーザーは様々な理由から、スタイルの上書きを行うかもしれません。視覚障碍のあるユーザーは、すべての訪問先のウェブサイトでテキストを大きくしたいかもしれませんし、あるいは、重度の色覚障碍のあるユーザーは、すべてのウェブサイトを自分でも見やすい高コントラストの色にしたいかもしれません。その必要性がいかなるものであるにせよ、(スタイルの上書きという) この事態にはなじんでおくべきですし、そうした変更が自分のデザインにおいてうまく機能するように、自分のデザインを十分に柔軟なものとしておくべきです。例として、主なコンテンツ領域がより大きいテキストを扱えて (その領域は、全体を見られるようにスクロールし始めるかもしれません)、ただ隠したり完全に破綻したりしないように、気をつけると良いでしょう。
JavaScript も、その使い方によっては、アクセシビリティをぶち壊しにする可能性があります。
モダンな JavaScript は強力な言語です。簡単なコンテンツと UI の更新から、本格的な 2D ゲームや 3D ゲームに至るまで、近頃では JavaScript を使ってとても多くのことができます。すべてのコンテンツがすべての人々にとって 100% アクセシブルであるべきだ、といった決まりはありません。自分にできることをし、自分のアプリをできる限りアクセシブルにする必要があるだけなのです。
単純なコンテンツと機能——たとえば、テキスト、画像、テーブル、フォーム、関数を起動する押しボタン——は、まず間違いなく、アクセシブルにするのが簡単です。HTML: アクセシビリティの基礎 の記事で見たように、考慮すべき重要な事項は以下のとおりです。
機能が欠けているところに機能を盛り込むように JavaScript を使う方法の例も見ました (Building keyboard accessibility back in を参照)。この例は理想的ではありません。実際、ただふさわしい要素をふさわしい役割に使うべきなのです。が、この例は、使われるマークアップを何らかの理由で統制できない状況においては、こうしたこともあり得るのだと示しています。非意味的な、JavaScript で実装されたウィジェットについて、アクセシビリティを向上させる別の方法は、WAI-ARIA を用いて追加的なセマンティクスをスクリーン・リーダーのユーザーに提供することです。次の記事では、このことも詳しく扱います。
3D ゲームのような複雑な機能は、アクセシブルにするのがそう簡単ではありません。WebGL を使って作られた複雑な 3D ゲームは {{htmlelement("canvas")}} 要素上に描画されるでしょうが、今のところ {{htmlelement("canvas")}} 要素には、重度の視覚障碍のあるユーザーが利用できるように代替テキストもしくは他の情報を提供する手段がないのです。 そうしたゲームは、こうした人々のグループを実際に主要な対象者の一部としてはいないのだ、というのはもっともです。それに、そのゲームを、目の見えない人々にとって 100% アクセシブルにせよ、と期待するのも不合理でしょう。しかし、マウスを使わないユーザーにとって利用可能なようにキーボード・コントロールを実装することや、 色覚障碍のある人々にとって利用可能なようにカラー・スキームに十分なコントラストを持たせることならできるでしょう。
JavaScript に頼りすぎると、しばしば問題が起きます。ときどき、何でもかんでも JavaScript で行われたウェブサイト—— HTML が JavaScript により生成され、CSS が JavaScript により生成され、といった調子のもの——を見るでしょう。これには、あらゆる種類のアクセシビリティの問題および付随するその他の問題があり、お勧めできません。
ふさわしい役割にふさわしい要素を使うのと同様に、ふさわしい役割にふさわしい技術を使っていることも確認しておくべきです! JavaScript で実装されたキラキラの 3D 情報ボックスが必要なのか、あるいは、プレーンな古めかしいテキストでも用が足りそうか、ということについて注意深く考えてください。複雑で非標準的なフォーム・ウィジェットが必要なのか、あるいは、テキスト入力でも用が足りそうか、ということについて注意深く考えてください。そして、とにかく可能な場合に JavaScript を使ってすべての HTML コンテンツを生成する、などということはしないでください。
コンテンツを作るときには、ひかえめな (unobtrusive) JavaScript を心に留めておくべきです。ひかえめな JavaScript という考え方は、次のようなものです。すなわち、機能を拡張できるところならどこでも使うべきだけれども、機能を盛り込むためにはまったく使うべきではない——基本的機能は JavaScript なしでも理想的には動くはずなのだから。もっとも、これが常に選択できるとは限らないことはよく理解されているのですが。しかし再び言いますが、この考えの大部分を占めるのは、可能な箇所ではブラウザーの組み込み機能を使うということです。
ひかえめな JavaScript の適切な使用例には、次のものが含まれます。
<video>
用のカスタム・コントロールを提供すること。それとともに、JavaScript が利用できない場合にその動画にアクセスするのに使える、動画への直接リンクも提供すること (ほとんどのブラウザでは、デフォルトの <video>
ブラウザ・コントロールは、キーボード・アクセシブルではありません)。一例として、やっつけ仕事のクライアントサイドのフォーム検査の例を書きました。form-validation.html を参照してください (demo live も参照してください). ここでは、単純なフォームが見えます。一方または双方のフィールドを空にしたままフォームを送信しようとすると、送信が失敗し、エラーメッセージ・ボックスが現れて、何が間違っているのかを教えてくれます。
この種のフォーム検査はひかえめです。JavaScript が利用できなくても、依然としてまったく申し分なくフォームを使えます。それに、分別のあるフォームの実装なら何であれ、サーバーサイドの検査も作動させておくことでしょう。なぜなら、悪意のあるユーザーがクライアントサイドの検査を (たとえば、ブラウザで JavaScript をオフにしておくことによって) 迂回することは、あまりに容易だからです。クライアントサイドの検査は、それでも実際に、エラーを報告するためには有用なのです。ユーザーは、自分のおかした間違いについて、サーバーまでのラウンドトリップおよびページリロードを待つ必要なしに、すぐに知ることができます。これは使い勝手の上での明らかな利点です。
注意: この単純なデモではサーバーサイドの検査を実装しませんでした。
このフォーム検査も、とてもアクセシブルにしておきました。{{htmlelement("label")}} 要素を用いて、フォーム・ラベルがそのラベルの入力欄に曖昧な点なしに紐付けられるようにして、それによってスクリーン・リーダーがラベルを一緒に読み上げられるようにしました。
<label for="name">お名前を入力してください (Enter your name):</label> <input type="text" name="name" id="name">
フォームが送信されるときにだけ検査をしています。これは、UI をあまりに頻繁に更新しないようにするため、そして、スクリーン・リーダーのユーザーを (また、おそらくは他のユーザーも) 潜在的に混乱させることがないようにするためです。
form.onsubmit = validate; function validate(e) { errorList.innerHTML = ''; for(var i = 0; i < formItems.length; i++) { var testItem = formItems[i]; if(testItem.input.value === '') { errorField.style.left = '360px'; createLink(testItem); } } if(errorList.innerHTML !== '') { e.preventDefault(); } }
注意: この例では、絶対的な位置指定を用いてエラーメッセージ・ボックスを隠したり見せたりしています。visibility や display などの他の方法を使っているわけではありません。なぜなら、絶対的な位置指定は、スクリーン・リーダーがコンテンツを読めるようにしておくことを妨げないからです。
現実のフォーム検査は、これよりもっと複雑でしょう。入力された名前が実際に名前のようであることを確認したいかもしれませんし、入力された年齢が実際に数であり、かつ現実的である (たとえば、負数ではなく、4 桁でもない、など) ということを確認したいかもしれません。ここでは、各入力フィールドに値が入れられたことを確認する (if(testItem.input.value === '')
という) 簡単な検査を実装しただけです。
検査が実行された際に、もしテストに通れば、フォームが送信されます。もしエラーがあれば (つまり if(errorList.innerHTML !== '')
であれば)、 (preventDefault()
を用いて) フォームの送信を中止し、生成されたエラーメッセージをすべて表示します (下記参照)。この仕組みは、エラーが存在するときにだけエラーが表示される、ということを意味します。そしてそのことは、使い勝手のうえで、より良いことなのです。
フォームが送信される際に値が入れられていない入力それぞれについて、リンクを有するリスト項目を作って、それを errorList
に挿入しています。
function createLink(testItem) { var listItem = document.createElement('li'); var anchor = document.createElement('a'); anchor.textContent = testItem.input.name + ' field is empty: fill in your ' + testItem.input.name + '.'; anchor.href = '#' + testItem.input.name; anchor.onclick = function() { testItem.input.focus(); }; listItem.appendChild(anchor); errorList.appendChild(listItem); }
各リンクは二つの役割を果たします。つまり、何のエラーなのかを教えてくれますし、さらに、そのリンクをクリックする / アクティブにすると問題の入力要素へ直接ジャンプして入力を訂正できるようになっています。
注意: この例の focus()
の部分は少し手が込んでいます。Chrome と Edge (と、IE の新しいバージョン) は、リンクがクリックされたときに要素にフォーカスを当てるので、onclick
/focus()
ブロックを必要としません。Safari はリンク自体とともにフォーム要素をハイライトするだけであり、そのため、実際にフォーム要素にフォーカスを当てるには onclick
/focus()
ブロックが必要です。Firefox は、こうした状況において入力要素に適切にフォーカスを当てることはまったくありません。よって、Firefox のユーザーは、現時点ではこの onclick
/focus()
ブロックの利益を享受できません (それ以外のすべてはうまく機能するのですが)。Firefox の問題はすぐに修正されるはずです。というのも、他のブラウザと同等のふるまいを Firefox にさせるための作業が、今なされている最中ですから ({{bug(277178)}} を参照).
さらに、ソース順における先頭に errorField
を置いてあります (CSS を使って、UI 上では別のところに配置してありますが)。これが意味することは、ユーザーが、ページの最初に戻ることで、自分のフォーム送信でまさに何が間違っているのかも分かるし、問題の入力要素にも行ける、ということです。
最後の注記ですが、このデモではいくつか WAI-ARIA 属性を使いました。ページリロードをともなわずに絶えず更新するコンテンツの領域が引き起こすアクセシビリティの問題を、解決する手助けとするためです (スクリーン・リーダーは、デフォルトでは、こうしたコンテンツを拾い上げたり、ユーザーにこうしたコンテンツを警告したりはしないでしょう)。
<div class="errors" role="alert" aria-relevant="all"> <ul> </ul> </div>
もっと詳細に WAI-ARIA を扱う次の記事で、これらの属性について説明します。
注意: HTML5 フォームには required
属性や min
/minlength
属性や max
/maxlength
属性のような組み込みの検査の仕組みがあること (より詳しくは、{{htmlelement("input")}} 要素のリファレンスを参照) について考える読者もおそらくいることでしょう。このデモでは、結局これらの属性は使いませんでした。なぜなら、これらの属性についてのクロスブラウザ・サポートが当てにならないからです (たとえば IE10 以上のみでのサポートだったり、Safari ではサポートされていなかったりします)。
注意: WebAIM の Usable and Accessible Form Validation and Error Recovery は、アクセシブルなフォーム検査についてのさらに有用な情報をいくつか教えてくれます。
JavaScript で実装しつつアクセシビリティについて考えるときに意識すべきことは他にもあります。見つけ次第、さらなる事項を追加するつもりです。
お気づきのとおり、ユーザーとの対話的動作のほとんどは、イベントハンドラーを使ってクライアントサイドの JavaScript で実装されます。イベントハンドラーによって、特定のイベントが起きるのに応じて関数を実行できるようになります。ある種のイベントには、アクセシビリティの問題があるかもしれません。読者が見つけることになるであろう主な例は、mouseover や mouseout や dblclick などの、マウスに特有のイベントです。これらのイベントに応じて動作する機能は、キーボード・コントロールのような他の仕組みを用いていると、アクセシブルではなくなります。
こうした問題を軽減するには、これらのイベントと、他の手段によってアクティブにできるような類似のイベントとの二重化をすべきです (いわゆるデバイスとは独立なイベントハンドラーです)。focus と blur は、キーボードのユーザーに対するアクセシビリティを提供してくれることでしょう。
これが有用になりうる場合においてハイライトを行う事例を見てみましょう。ときにはサムネイル画像を設けたいことがあります。そのサムネイル画像にマウスオーバーした場合またはフォーカスが当たった場合に、その画像の、より大きなバージョンを表示するものです (電子商取引の商品カタログ上で見受けられるようなものです)。
とても簡単な例を作りました。これは、mouse-and-keyboard-events.html で見られます (ソースコード も参照)。このコードは、ズームインした画像を表示する関数と隠す関数という、二つの関数を特徴としています。これらの関数は、これらの関数をイベントハンドラーとして設定する以下の行により実行されます。
imgThumb.onmouseover = showImg; imgThumb.onmouseout = hideImg; imgThumb.onfocus = showImg; imgThumb.onblur = hideImg;
最初の 2 行は、それぞれ、マウスポインターがサムネイル上にホバーしたときと、マウスポインターがサムネイル上にホバーするのをやめたときに、関数を動作させます。しかしこれだと、ズームしたビューにキーボードを通じてアクセスすることはできません。それをできるようにするために、後ろの方の 2 行を含めました。この 2 行は、画像にフォーカスが当たったときと、画像からフォーカスが外れた (フォーカスが停止した) ときに、関数を動作させます。こうしたことは、タブキーで画像上に移動することでできることです。なぜなら、画像に tabindex="0"
を含めておいたからです。
click クリックイベントは興味深いものです。マウス依存のように聞こえる名前ですが、ほとんどのブラウザーは、フォーカスの当たっているリンクまたはフォーム要素上でエンター / リターンが押された後に、あるいは、そうした要素がタッチスクリーン装置上でタップされたときに、onclick イベントハンドラーをアクティブにすることでしょう。しかしこれは、tabindex を用いて、デフォルトではフォーカス可能ではないイベントがフォーカスを持つようにしていると、デフォルトのままではうまく機能しません。そうした場合では、まさにそのキーが具体的にはいつ押されたのかを検出する必要があります (Building keyboard accessibility back in を参照)。
ウェブページ上での CSS と JavaScript の使用にまつわるアクセシビリティの問題について、このページが適切な量の細部と理解をもたらしたのであれば幸いです。
次は WAI-ARIA の番です!