LoginSignup
0
2

More than 5 years have passed since last update.

WAI-ARIAを使ってアクセシビリティを上げながら挙動やスタイルを制御する

Last updated at Posted at 2019-02-28

WAI-ARIAについての説明は今回省かせていただきます。詳しくはAccessible Rich Internet Applications (WAI-ARIA) 1.1 日本語訳をご覧下さい。

なぜWAI-ARIAを使って制御するのか

WAI-ARIAはステートおよびプロパティを明示するものがあります。それを使うことで、不要なclassでの管理を抑えることができます。
例えば以下のようにaria-checkedを使って、状態を表現する事もできます。

<li role="menuitemcheckbox" aria-checked="true">Sort by Last Modified</li>
<style>
[aria-checked="true"] { font-weight: bold; }
[aria-checked="true"]::before { background-image: url(checked.gif); }
</style>

このように情報と見た目で挙動をコントロールしていきたいと思います。

実際にWAI-ARIAで制御する

今回は制作現場でもよく使用されるDialog、Accordionを作っていきたいと思います。

Dialog

今回はこんな感じでDialogを作ってみました。
使ったWAI-ARIAは以下になります。

  • aria-hidden='true':スクリーンリーダーに読み上げられないように、要素を隠します。今回はこれを使ってCSSで挙動を制御してみます。
  • aria-labelledby='dialog-heading':見出しと関連付けています。
  • aria-describedbyy='dialog-desc':説明文と関連づけています。
  • tabindex='-1':Tabキーによるフォーカスの対象にしないが、フォーカスはできるようにします。

HTML

<main id='js-main'>
  <p>Main Contents...</p>
  <button id='js-show-dialog'>Show Dialog!!</button>
</main>
<div id='js-dialog' class='dialog-overlay' aria-hidden='true'>
  <div class='dialog' 
       tabindex='-1'
       aria-labelledby='dialog-heading' 
       aria-describedby='dialog-desc'>
    <div class='dialog-header'>
      <h2 id='dialog-heading'>dialogの見出し</h2>
      <p id='dialog-desc'>dialogの説明</p>
      <span class='dialog-icon-close' aria-hidden='true'>×</span>
    </div>
    <div class='dialog-body'>
      Dialog Contents...  
    </div>
    <div class='dialog-footer'>
      <button id='js-close-dialog'>閉じる</button>
    </div>
  </div>
</div>

CSS

main[aria-hidden='true'] {
  opacity: .05;
}

.dialog-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, .5);
}

.dialog-overlay[aria-hidden="true"] {
  display: none;
}

.dialog {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%);
  background-color: #fff;
  width: 480px;
}

JavaScript

const main = document.getElementById('js-main');
const dialog = document.getElementById('js-dialog');
document.getElementById('js-show-dialog').addEventListener('click', () => {
  dialog.removeAttribute('aria-hidden');
  main.setAttribute('aria-hidden', true);
})
document.getElementById('js-close-dialog').addEventListener('click', () => {
  dialog.setAttribute('aria-hidden', true);
  main.removeAttribute('aria-hidden');
})

とても簡単なのですが、スクリーンリーダーが読まなくても良い部分にaria-hidden='true'をつけています。今回はremoveAttributeを使って出し分けていますがelement.setAttribute('aria-hidden', false);でもいいみたいです。なんとなくしっくりこなかったので、今回は属性ごと削除をしています。

Accordion

Accordionで使ったWAI-ARIAは以下になります。
* aria-expanded='false':要素の状態を表現します。ただこれは隠す要素に対して行うのではなく、制御する側の状態を示します。
* aria-controls='acc-foo':コントロールする要素を示します。この場合は、id='acc-foo'の要素をコントロールする事を指しています。

HTML

<div class='acc'>
  <div class='acc-header' aria-expanded='false' aria-controls='acc-foo'>
    Open Foo
  </div>
  <div id='acc-foo' class='acc-body'>
    <p>Foo.</p>
  </div>
  <div class='acc-header' aria-expanded='false' aria-controls='acc-bar'>
    Open Bar
  </div>
  <div id='acc-bar' class='acc-body'>
    <p>Bar.</p>
  </div>
  <div class='acc-header' aria-expanded='false' aria-controls='acc-baz'>
    Open Baz
  </div>
  <div id='acc-baz' class='acc-body'>
    <p>Baz.</p>
  </div>
</div>

CSS


.acc {
  border: 1px #e3e3e3 solid;
}

.acc-header[aria-expanded='true'] {
  background-color: #eaa3a2;
  cursor: default;
}

.acc-body {
  height: 0;
  overflow: hidden;
}

.acc-header[aria-expanded='true'] + .acc-body {
  height: auto;
}

.acc-body p {
  padding: 10px;
}

JavaScript

const triggers = document.querySelectorAll('[aria-controls^="acc-"]');
const targets = document.querySelectorAll('[id^="acc-"]');
triggers.forEach((trigger) => {
  trigger.addEventListener('click', function() {
    triggers.forEach((trigger) => {
      trigger.setAttribute('aria-expanded', false);
    });
    this.setAttribute('aria-expanded', true);
  });
});

今回はaria-expandedをコントロールできればいいので雑な実装になってます。

まとめ

普段はなんでもclassを付与して、見た目や挙動の変更を行ってきましたが、アクセシビリティに沿った方法で変更する事ができました。
今回調べてみたきっかけは、BootstrapがWAI-ARIAを挙動に合わせてコントロールしていたので興味を持ちました。BootstrapのComponentsの中には、他の属性を使ったものもあると思うので興味のある人は参考にしてみてください。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2