【SVGアクセシビリティ】グラフィックスをアクセシブルにする方法

これは Web Accessibility Advent Calendar 2014の13日目のエントリーです。

徐々に案件で使うケースも増えてきたであろうSVGですが、本エントリーでは、SVGのアクセシビリティについて書きます。

SVGとは

説明は不要だと思いますが一応。

SVG(Scalable Vector Graphics)は、XMLをベースとしたベクトルグラフィックス用の画像形式です。

SVG自体はそれなりに前からありましたが、ブラウザのサポートがあまりよくありませんでした。近年、徐々に対応されつつあり、ほぼ最新のブラウザで使うことができます。
SVG (basic support) - Can I use...

ちなみに下記がSVGのバージョンと勧告時期です。

SVG 1.0
2001年9月 W3C勧告
SVG 1.1
2003年1月 W3C勧告
SVG 1.1 2nd edition
2011年8月 W3C勧告
SVG 2.0
草案段階

SVG アクセシビリティ

ここから本題です。SVGは、グラフィックスをアクセシブルにする機能があります。

ひとつの機能は、拡大してもグラフィックスがぼやけないことです。グラフィックスの中にテキスト情報があった場合に拡大してもぼやけないので、読みにくくなることはありません。

もうひとつの機能は、グラフィックスにテキスト情報を付与できることです。

WCAG 2.0/JIS X 8341-3:2010に非テキストコンテンツに対する達成基準があります。非テキストコンテンツが何であるかを伝えるために、代替テキストなどの代替手段を用意しなければなりません。それを満たすことができる機能がSVGにはあります。それが、text要素title要素desc要素です。

text要素

text要素はテキストからなるグラフィックスを定義します。このテキスト内容がグラフィックスを説明しているのであれば、この要素だけで良いですが、そうでない場合は、title要素desc要素を使います。

<svg version="1.1" x="0px" y="0px" viewBox="0 0 595.3 841.9">
<text
  transform="matrix(1 0 0 1 136.6205 77.3923)"
  font-family="Verdana"
  font-size="46">緑色の星印</text>
<polygon 
   fill="#179A3A" 
   points="364.5,282.5 301,264.1 249.9,305.9 247.8,239.9 192.2,204.2 254.3,181.8 271.1,117.9 311.6,170.1 377.5,166.3 340.5,220.9 "/>
</svg>

title要素

この要素は、グラフィックスの短い説明に使います。desc要素との併用も許可されています。title要素はグラフィックスとして画面には表示されません。

<svg version="1.1" x="0px" y="0px" viewBox="0 0 595.3 841.9">
<title>5つの星印</title>
<polygon
  fill="#179A3A"
  points="198.3,184.2 166.2,174.9 140.4,196 139.3,162.7 111.2,144.6 142.6,133.3 151.1,101 171.6,127.3 204.9,125.4 186.2,153 "/>
<polygon
  fill="#1D2B57"
  points="337.9,193.6 305.8,184.3 280,205.5 278.9,172.1 250.8,154.1 282.2,142.7 290.7,110.4 311.2,136.8 344.5,134.9 325.8,162.5 "/>
<polygon
  fill="#C3172F"
  points="265.7,279.2 233.7,270 207.8,291.1 206.7,257.7 178.6,239.7 210,228.3 218.5,196 239,222.4 272.4,220.5 253.6,248.1 "/>
<polygon
  fill="#C9DA2B"
  points="408.4,268.9 376.3,259.6 350.4,280.8 349.4,247.4 321.2,229.3 352.7,218 361.1,185.7 381.6,212.1 415,210.1 396.2,237.8 "/>
<polygon
  fill="#50BFCC"
  points="472.5,184.2 440.5,174.9 414.6,196 413.5,162.7 385.4,144.6 416.8,133.3 425.3,101 445.8,127.3 479.2,125.4 460.4,153 "/>
</svg>

また、仕様書には以下のような記述があります。

display the 'title' element as a tooltip, as the pointing device moves over particular elements.

IE11やChromeではまだ未実装ですが、いづれはマウスでホバーするとツールチップで表示されるかもしれません。

desc要素

desc要素もグラフィックスとして画面には表示されません。より詳細な説明をする場合にこの要素を使います。title要素との併用も許可されています。

<svg version="1.1" x="0px" y="0px" viewBox="0 0 595.3 841.9">
<title>5つの星印</title>
<desc>5つの色とりどりの星がちりばめられている</desc>
<polygon
  fill="#179A3A"
  points="198.3,184.2 166.2,174.9 140.4,196 139.3,162.7 111.2,144.6 142.6,133.3 151.1,101 171.6,127.3 204.9,125.4 186.2,153 "/>
<polygon
  fill="#1D2B57"
  points="337.9,193.6 305.8,184.3 280,205.5 278.9,172.1 250.8,154.1 282.2,142.7 290.7,110.4 311.2,136.8 344.5,134.9 325.8,162.5 "/>
<polygon
  fill="#C3172F"
  points="265.7,279.2 233.7,270 207.8,291.1 206.7,257.7 178.6,239.7 210,228.3 218.5,196 239,222.4 272.4,220.5 253.6,248.1 "/>
<polygon
  fill="#C9DA2B"
  points="408.4,268.9 376.3,259.6 350.4,280.8 349.4,247.4 321.2,229.3 352.7,218 361.1,185.7 381.6,212.1 415,210.1 396.2,237.8 "/>
<polygon
  fill="#50BFCC"
  points="472.5,184.2 440.5,174.9 414.6,196 413.5,162.7 385.4,144.6 416.8,133.3 425.3,101 445.8,127.3 479.2,125.4 460.4,153 "/>
</svg>

VoiceOverで確認

実際にVoiceOverでtitle要素やdesc要素の内容が読み上げられるか確認しましたが、読み上げれませんでした。

Web Accessibility Advent Calendar 2014 9日目の記事の object要素で配置した SVG ロゴをスクリーンリーダーに読ませるで、title要素等の内容ではありませんが、近いことが書かれています。
また、Using ARIA to enhance SVG accessibilityでは、スクリーンリーダーでtitle要素などの読み上げテストを行った結果が載っています。ほとんどのスクリーンリーダーで対応していません。

aria-labelledby、role(WAI-ARIA)

現状、SVGにあるテキスト内容をスクリーンリーダーで読み上げられるようにするためには、WAI-ARIAを使う必要があります。

role属性

今回のサンプルで作ったグラフィックスはイメージとしていますので、svg要素にrole="img"を付与。

<svg
  version="1.1"
  x="0px" 
  y="0px"
  viewBox="0 0 595.3 841.9"
  role="img">
<polygon
  fill="#179A3A"
  points="198.3,184.2 166.2,174.9 140.4,196 139.3,162.7 111.2,144.6 142.6,133.3 151.1,101 171.6,127.3 204.9,125.4 186.2,153 "/>
<polygon
  fill="#1D2B57"
  points="337.9,193.6 305.8,184.3 280,205.5 278.9,172.1 250.8,154.1 282.2,142.7 290.7,110.4 311.2,136.8 344.5,134.9 325.8,162.5 "/>
<polygon
  fill="#C3172F"
  points="265.7,279.2 233.7,270 207.8,291.1 206.7,257.7 178.6,239.7 210,228.3 218.5,196 239,222.4 272.4,220.5 253.6,248.1 "/>
<polygon
  fill="#C9DA2B"
  points="408.4,268.9 376.3,259.6 350.4,280.8 349.4,247.4 321.2,229.3 352.7,218 361.1,185.7 381.6,212.1 415,210.1 396.2,237.8 "/>
<polygon
  fill="#50BFCC"
  points="472.5,184.2 440.5,174.9 414.6,196 413.5,162.7 385.4,144.6 416.8,133.3 425.3,101 445.8,127.3 479.2,125.4 460.4,153 "/>
</svg>

VoiceOverで「イメージ」と読み上げられました。

aria-labelledbyプロパティ

title要素やdesc要素のテキスト内容をラベル付けするために、aria-labelledbyプロパティをsvg要素に付与します。

title要素とdesc要素にid属性を付与し、そのid属性の値をaria-labelledbyプロパティに指定します。

title要素のみ取得

<svg
  version="1.1"
  x="0px" 
  y="0px"
  viewBox="0 0 595.3 841.9"
  role="img" 
  aria-labelledby="title">
<title id="title">5つの星印</title>
<polygon
  fill="#179A3A"
  points="198.3,184.2 166.2,174.9 140.4,196 139.3,162.7 111.2,144.6 142.6,133.3 151.1,101 171.6,127.3 204.9,125.4 186.2,153 "/>
<polygon
  fill="#1D2B57"
  points="337.9,193.6 305.8,184.3 280,205.5 278.9,172.1 250.8,154.1 282.2,142.7 290.7,110.4 311.2,136.8 344.5,134.9 325.8,162.5 "/>
<polygon
  fill="#C3172F"
  points="265.7,279.2 233.7,270 207.8,291.1 206.7,257.7 178.6,239.7 210,228.3 218.5,196 239,222.4 272.4,220.5 253.6,248.1 "/>
<polygon
  fill="#C9DA2B"
  points="408.4,268.9 376.3,259.6 350.4,280.8 349.4,247.4 321.2,229.3 352.7,218 361.1,185.7 381.6,212.1 415,210.1 396.2,237.8 "/>
<polygon
  fill="#50BFCC"
  points="472.5,184.2 440.5,174.9 414.6,196 413.5,162.7 385.4,144.6 416.8,133.3 425.3,101 445.8,127.3 479.2,125.4 460.4,153 "/>
</svg>

title要素のテキスト内容が読み上げられました。

desc要素のみ取得

<svg
  version="1.1"
  x="0px" 
  y="0px"
  viewBox="0 0 595.3 841.9"
  role="img" 
  aria-labelledby="desc">
<desc id="desc">5つの色とりどりの星がちりばめられている</desc>
<polygon
  fill="#179A3A"
  points="198.3,184.2 166.2,174.9 140.4,196 139.3,162.7 111.2,144.6 142.6,133.3 151.1,101 171.6,127.3 204.9,125.4 186.2,153 "/>
<polygon
  fill="#1D2B57"
  points="337.9,193.6 305.8,184.3 280,205.5 278.9,172.1 250.8,154.1 282.2,142.7 290.7,110.4 311.2,136.8 344.5,134.9 325.8,162.5 "/>
<polygon
  fill="#C3172F"
  points="265.7,279.2 233.7,270 207.8,291.1 206.7,257.7 178.6,239.7 210,228.3 218.5,196 239,222.4 272.4,220.5 253.6,248.1 "/>
<polygon
  fill="#C9DA2B"
  points="408.4,268.9 376.3,259.6 350.4,280.8 349.4,247.4 321.2,229.3 352.7,218 361.1,185.7 381.6,212.1 415,210.1 396.2,237.8 "/>
<polygon
  fill="#50BFCC"
  points="472.5,184.2 440.5,174.9 414.6,196 413.5,162.7 385.4,144.6 416.8,133.3 425.3,101 445.8,127.3 479.2,125.4 460.4,153 "/>
</svg>

desc要素のテキスト内容が読み上げられました。

title要素とdesc要素を取得

<svg
  version="1.1"
  x="0px" 
  y="0px"
  viewBox="0 0 595.3 841.9"
  role="img" 
  aria-labelledby="title desc">
<title id="title">5つの星印</title>
<desc id="desc">5つの色とりどりの星がちりばめられている</desc>
<polygon
  fill="#179A3A"
  points="198.3,184.2 166.2,174.9 140.4,196 139.3,162.7 111.2,144.6 142.6,133.3 151.1,101 171.6,127.3 204.9,125.4 186.2,153 "/>
<polygon
  fill="#1D2B57"
  points="337.9,193.6 305.8,184.3 280,205.5 278.9,172.1 250.8,154.1 282.2,142.7 290.7,110.4 311.2,136.8 344.5,134.9 325.8,162.5 "/>
<polygon
  fill="#C3172F"
  points="265.7,279.2 233.7,270 207.8,291.1 206.7,257.7 178.6,239.7 210,228.3 218.5,196 239,222.4 272.4,220.5 253.6,248.1 "/>
<polygon
  fill="#C9DA2B"
  points="408.4,268.9 376.3,259.6 350.4,280.8 349.4,247.4 321.2,229.3 352.7,218 361.1,185.7 381.6,212.1 415,210.1 396.2,237.8 "/>
<polygon
  fill="#50BFCC"
  points="472.5,184.2 440.5,174.9 414.6,196 413.5,162.7 385.4,144.6 416.8,133.3 425.3,101 445.8,127.3 479.2,125.4 460.4,153 "/>
</svg>

title要素とdesc要素の内容が読み上げられました。

lang属性

これまでの内容とは外れますが、SVG 2でのtitle要素とdesc要素です。
まだ草案段階ですが、SVG 2ではtitle要素とdesc要素にlang属性が追加になっています。 5.5. The 'desc' and 'title' elements

場合によったら、説明文に他言語を使わなければならないかもしれません。その場合にはユーザーエージェントが判別してユーザーの使われている環境にマッチしたものが適用されます。もし、そうでない場合は、最初の要素が適用されます。下記のソースコードだとlang="ja"のテキスト内容がそれにあたります。

<svg>
  <g>
    <title lang="ja">5つの星印</title>
    <title lang="en">Five Stars</title>
    <title lang="fr">Cinq étoiles</title>
    <desc lang="ja">5つの色とりどりの星がちりばめられている</desc>
    <desc lang="en">Five colorful stars are studded</desc>
    <desc lang="fr">Cinq étoiles colorées sont parsemés</desc>
  </g>
</svg>

まとめ

title要素とdesc要素を使って、グラフィックスの説明を提供します。

スクリーンリーダーのSVGへの対応がまだまだですので、SVG内にあるテキスト内容を読み上げさせるためには、現時点ではWAI-ARIAを使う必要がありますので、当分はSVG + WAI-ARIAの併用になります。

SVGをがんがん案件で使っている人や今後使おうとしている人は、SVGを使っていく場合には、title要素、もしくはdesc要素、あとWAI-ARIAを指定するようにしていただければと思います。

また、SVGの仕様書には、Accessibility Supportという資料があります。上記で記載したことも含まれていますが、他にも「色に頼らない」「文法に従ったマークアップ」といった基本的なことも書かれているので目を通しておくとよいと思います。

関連

参考