【課題16】タブ切り替えでWAY-ARIAに入門

【課題16】タブ切り替えでWAY-ARIAに入門

もりけん塾の課題16でタブの実装にチャレンジしています。
今までタブ切り替えでアクセシビリティに対応しないとと思いつつ、
できていなかったので、実装したまとめです。

WAI-ARIAとは?

WAI-ARIAはWeb Accessibility Initiative Accessible Rich Internet Applicationsの略で、
W3Cが取り決めた仕様です。
HTMLだけでは足りないアクセシビリティの機能を属性を使って補完します。

ちなみにWAI-ARIAはウェイアリアと読むそうです。

支援技術が障害をもつ人に対し適切な情報を伝えられるようにするために、ウェブコンテンツのアクセシビリティは、ウィジェット、構造、動作に関するセマンティック情報を要…
momdo.github.io

アクセシビリティを向上させる3つの機能

WAI-ARIAには3つの機能は提供されています。Role(ロール)、Property(プロパティ)、ステート(State)です。

Role(ロール)

Roleを指定する要素(タグ)が、なんの役割を持つのかを定義します。
今回の課題はタブの切り替えだったので、
下記のように利用しました。

<ul class="tab-list" role="tablist">
 <li role="presentation">
    <button role="tab">ニュース</button>
  </li>
 <li role="presentation">
    <button role="tab">経済</button>
  </li>
</ul>

<ul>が持つ本来の意味はリストなので、タブとはわかりません。
そこでrole属性を使い、role=”tablist”としてタブのリストだよと役割も持たせました。
<button>にもタブだよとrole=”tab”で役割を持たせていいます。

Property(プロパティ)

Propertyは追加の意味や用途を追加登録するために「arai-***」を使って性質を登録します。
今回の課題ではタブの部分とタブのコンテンツの部分を紐付ける必要があったため、
aria-controlsとidで紐付けを行いました。
タブのaria-controls=”panel-1″とタブのコンテンツid=”panel-1″が紐づく形です。 

<button id="tab-1" aria-controls="panel-1"	role="tab" tabindex="0">
 ニュース
</button>

<!--タブのコンテンツ部分-->
<div id="panel-1" aria-hidden="false"	aria-labelledby="tab-1"	role="tabpanel">
 <ul class="news-list">
	 <li class="news-item">
		 <a href="" class="news-link">総合ニュース Topic01</a><span class="icon-new">new</span><span class="comment-count">300</span>
		</li>
		<li class="news-item">
			<a href="" class="news-link">総合ニュース Topic01</a><span class="comment-count"></span>
		</li>
		<li class="news-item">
			<a href="" class="news-link">総合ニュース Topic01</a>
		</li>
		<li class="news-item">
			<a href="" class="news-link">総合ニュース Topic01</a>
		</li>
	</ul>
</div>

State(ステート)

Stateは現在の特定の状態を「arai-***」を使って示す特別なプロパティです。
先程のPropatyとの違いはPropatyは不変なもの、(一度設定したら変更しない)に対し、StateはJavaScriptを用いて変更することができます。
今回作成したタブではaria-selectedを使用し、選択されているタブにはtrueをそれ以外はfalseを設定しています。それ以外にもタブのコンテンツ部分にはaria-hidden=”true/false”を用いて表示・非表示も操作しています。

<ul class="tab-list" role="tablist">
 <li role="presentation">
    <button role="tab" aria-selected="true">ニュース</button>
  </li>
 <li role="presentation">
    <button role="tab" aria-selected="false">経済</button>
  </li>
</ul>

注意が必要な暗黙のARIA

HTMLにはもともと持っているrole(定義)が存在しています。
WAI-ARIAはHTMLでは補えない部分を後から補完するためのものなので、
重複しないように設定する必要があるようです。

例えばリストやチェックボックスにはもともとリスト、チェックボックスと既に定義されています。

<!--role=checkbox-->
<input type="checkbox" name="" id="">

<!--ul role=list,li role=listitem-->
<ul> 
 <li>ulはrole=listがもともと定義されている</li>
 <li>liはrole=listitemがもともと定義されている</li>
</ul>

既存のroleについては下記にまとめられています。

This specification defines the authoring rules (author conformance requirements)…
www.w3.org

今回タブの構造をulを使って実装しました。

<ul class="tab-list" role="tablist">
 <li>
    <button role="tab" aria-selected="true">ニュース</button>
  </li>
 <li>
    <button role="tab" aria-selected="false">経済</button>
  </li>
</ul>

li要素の中にあるbuttonにrole=tabを設定し、liのもともとのrole=listitemが余計になってしまいました。
カテゴリーをリストのように並べたかったのですが、リストとタブボタンは違うので、
既存のroleを無効にするためliにrole=presentationを指定します。

<ul class="tab-list" role="tablist">
 <li role="presentation">
    <button role="tab" aria-selected="true">ニュース</button>
  </li>
 <li role="presentation">
    <button role="tab" aria-selected="false">経済</button>
  </li>
</ul>

実際に実装したコード

調べながら実装した結果、このようになりました。

<div class="news-category">
	<ul class="tab-list" role="tablist">
		<li class="tab-list-item" role="presentation">
			<button
				id="tab-1"
				class="tab-button js-tabButton"
				aria-selected="true"
				aria-controls="panel-1"
				role="tab"
				tabindex="0">
				ニュース
			</button>
		</li>
		<li class="tab-list-item" role="presentation">
			<button
				id="tab-2"
			  class="tab-button js-tabButton"
				aria-selected="false"
				aria-controls="panel-2"
				role="tab"
				tabindex="-1">
				経済
			</button>
		</li>
		<li class="tab-list-item" role="presentation">
			<button
				id="tab-3"
				class="tab-button js-tabButton"
				aria-selected="false"
				aria-controls="panel-3"
				role="tab"
				tabindex="-1">
				エンタメ
			</button>
		</li>
		<li class="tab-list-item" role="presentation">
			<button
				id="tab-4"
				class="tab-button js-tabButton"
				aria-selected="false"
				aria-controls="panel-4"
				role="tab"
				tabindex="-1">
				スポーツ
			</button>
		</li>
		<li class="tab-list-item" role="presentation">
			<button
				id="tab-5"
				class="tab-button js-tabButton"
				aria-selected="false"
				aria-controls="panel-5"
				role="tab"
				tabindex="-1">
				国内
			</button>
		</li>
	</ul>
</div>
<div class="news-contents">
	<div
		id="panel-1"
		class="news-area category_illust"
		aria-hidden="false"
		aria-labelledby="tab-1"
		role="tabpanel">
		<ul class="news-list">
			<li class="news-item">
				<a href="" class="news-link">総合ニュース Topic01</a><span class="icon-new">new</span><span class="comment-count">300</span>
			</li>
			<li class="news-item">
				<a href="" class="news-link">総合ニュース Topic01</a><span class="comment-count"></span>
			</li>
			<li class="news-item">
				<a href="" class="news-link">総合ニュース Topic01</a>
			</li>
			<li class="news-item">
				<a href="" class="news-link">総合ニュース Topic01</a>
			</li>
		</ul>
	</div>
	<div
		id="panel-2"
		class="news-area category_illust"
		aria-hidden="true"
		aria-labelledby="tab-2"
		role="tabpanel">
   <ul class="news-list">
			<li class="news-item">
				<a href="" class="news-link">総合ニュース Topic01</a><span class="comment-count"></span>
			</li>
			<li class="news-item">
				<a href="" class="news-link">総合ニュース Topic01</a><span class="comment-count"></span>
			</li>
			<li class="news-item">
				<a href="" class="news-link">総合ニュース Topic01</a>
			</li>
			<li class="news-item">
				<a href="" class="news-link">総合ニュース Topic01</a>
			</li>
		</ul>
	</div>
	<div
		id="panel-3"
		class="news-area category_illust"
		aria-hidden="true"
		aria-labelledby="tab-3"
		role="tabpanel">
		<ul class="news-list">
			<li class="news-item">
				<a href="" class="news-link">総合ニュース Topic01</a><span class="comment-count"></span>
			</li>
			<li class="news-item">
				<a href="" class="news-link">総合ニュース Topic01</a><span class="comment-count"></span>
			</li>
			<li class="news-item">
				<a href="" class="news-link">総合ニュース Topic01</a>
			</li>
			<li class="news-item">
				<a href="" class="news-link">総合ニュース Topic01</a>
			</li>
		</ul>
	</div>
	<div
		id="panel-4"
		class="news-area category_illust"
		aria-hidden="true"
		aria-labelledby="tab-4"
		role="tabpanel">
		<ul class="news-list">
			<li class="news-item">
				<a href="" class="news-link">総合ニュース Topic01</a><span class="comment-count"></span>
			</li>
			<li class="news-item">
				<a href="" class="news-link">総合ニュース Topic01</a><span class="comment-count"></span>
			</li>
			<li class="news-item">
				<a href="" class="news-link">総合ニュース Topic01</a>
			</li>
			<li class="news-item">
				<a href="" class="news-link">総合ニュース Topic01</a>
			</li>
		</ul>
	</div>
	<div
		id="panel-5"
		class="news-area category_illust"
		aria-hidden="true"
		aria-labelledby="tab-5"
		role="tabpanel">
		<ul class="news-list">
			<li class="news-item">
				<a href="" class="news-link">総合ニュース Topic01</a><span class="comment-count"></span>
			</li>
			<li class="news-item">
				<a href="" class="news-link">総合ニュース Topic01</a><span class="comment-count"></span>
			</li>
			<li class="news-item">
				<a href="" class="news-link">総合ニュース Topic01</a>
			</li>
			<li class="news-item">
				<a href="" class="news-link">総合ニュース Topic01</a>
			</li>
		</ul>
	</div>
</div>

まとめ

最初は参考を読み込むだけではなかなかPropatyやStateの使い方が分からなかったですが、
実際にタブに組み込んでみて違いがわかりました。
コードは書かないと理解できないですね。
属性はCSSにも使えるので、タブの見た目の切り替えのJSやCSSがスッキリかけたのでコードの量を減らすこともできました。

今後もアクセシビリティを考えたサイト制作に取り組んでいきたいと思います。

参考にしたサイト

こんにちは。Webデザイナーの山田です。 とても暑い日々が続いていますが、皆さまいかがお過ごしでしょうか。 今年はマスクをつけて外出されることが殆どだと思います…
www.willstyle.co.jp
This document describes how user agents should expose semantics of web content l…
www.w3.org
アクセシビリティとは可能な限りの多くの人々が利用できるようにする状態のことを指します。 ウェブサイトで言えばス
b-risk.jp
Webコンテンツアクセシビリティを確保するさまざまな仕様のうち、WebサイトやWebアプリケーションで活用できるrole属性とaria属性について取り上げます。…
www.codegrid.net

もりけん塾

現在もりけん塾に参加し、JavaScriptの課題に取り組んでいます!
素敵な先生と塾生に囲まれて切磋琢磨な日々を送っています。

森田先生のBLOG:無骨日記
Twetter:@terrace_tech

毎日7時に「おはようございます」の記事で投稿しています。ブロガーです。 先輩芸人の運転手していた29歳の頃、芸人の中でも何か一芸を身に付けたいと思い、初海外単身…
kenjimorita.jp