見出し画像

アクセシビリティ対策用カンニングコード

以前ポストした「コーディング視点からの、ウェブアクセシビリティ対応」を基に、実際どう組んでいたか、(自分が)特に忘れやすい部分を思い出すため用のカンニングコードをまとめてみました。


フォントの相対指定

直観的に記述するなら、ベースとなるサイズ指定の時点で10px相当のサイズを指定し、rem指定で調節。

/* CSS */

html {
  font-size: 62.5%;
}

/* 10px = 16px * 0.625 */
/* 以降 10px = 1rem */
/* 14pxを指定するなら、1.4remとか */

Sass等が使えるなら、引数=px数に対応したrem指定で、mixin作ってやったりとか。

/* CSS */

@mixin font-size($font-size) {
  @if $font-size == 10 {
    font-size:0.625rem;
  }
  @else if $font-size == 12 {
    font-size:0.75rem;
  }
  @else if $font-size == 14 {
    font-size:0.875rem;
  }
  @else if $font-size == 16 {
    font-size:1rem; // Base
  }
  @else if $font-size == 18 {
    font-size:1.125rem;
  }
  @else if $font-size == 20 {
    font-size:1.25rem;
  }
  @else if $font-size == 24 {
    font-size:1.5rem;
  }
}

フォーカスの表示

疑似classのfocusへ、outlineプロパティを設置。
テキストのfocusはこれだけでも十分だが、ボタンデザインへのfocusの場合、ロービジョン対応でひっかかる可能性が高いので、outline-offsetでボタンとfocusの間に余白を取ってコントラストを維持させる。

/* CSS */

.Selector:focus {
  outline: 3px solid #f00;
  outline-offset: 3px;
}

メガメニューにおけるキーボードトラップの回避

メガメニューの挙動を、通常のHoverによる挙動とは別に、focusによるカーソル移動を考慮した挙動用を「focus()」と「blur()」を活用し設定。
また、PC用メニューとSP用メニューを同一ソースで記述することもあるので、マウス操作以外で起こりうる動作を想定して記載。

/* HTML */

/* メニューはPCとSPで同一ソース */
/* PCはメガメニュー、SPはハンバーガメニューの挙動 */
/* メガメニュー内部は、SP時はアコーディオンで展開 */

<div class="js_spnavbtn"> /* ハンバーガーメニュー用開閉ボタン */
  <button type="button" tabindex="0">メニュー開く</button>
</div>

<div class="js_spnavwrap">
  <nav>
    <ul class="gnav js_megamenu">
      <li>
        <div class="nav_parent">
          <a>メガメニューの親要素</a>
          <span class="js_ac_btn"></span>
        </div>
        <div class="megamenu js_ac_content"> /* メガメニュー内部 */
          <div class="megamenu_inner">
            <ul>
              <li><a>メガメニューの親要素1</a></li>
              <li><a>メガメニューの親要素2</a></li>
              <li><a>メガメニューの親要素3</a></li>
              <li><a>メガメニューの親要素4</a></li>
              <li><a>メガメニューの親要素5</a></li>
            </ul>
          </div>
        </div>
      </li>
    </ul>
  </nav>
  <a class="js_navcls">SPメニュー閉じる</a> /* 不可視の閉じるボタン */
</div>
/* Javascript */

$(function(){
  $('.gnav .nav_parent a').focus( function () { 
  /* メガメニューの親要素にfocusが当たると */
    if(window.matchMedia('(max-width:768px)').matches) { /* PCorSPの分岐判定 */
      $(this).closest('li').find('div.js_ac_content').stop().slideDown().addClass("open");
      $(this).next('.js_ac_btn').addClass("open");
      /* SPの場合、.js_ac_contentと.js_ac_btnに.openを追加し、メガメニュー内部を表示 */
    } else {
      $(this).closest('li').find('div.megamenu').addClass('focused');
      /* PCの場合、.megamenuに.focusedを追加し、メガメニュー内部を表示 */
    }
  }).blur(function(){
    $(this).closest('li').find('div.megamenu').removeClass('focused');
    /* メガメニュー内部からfocusが外れたら.focusedを削除し、メガメニュー内部を非表示 */
  });

  /* 挙動は上記PCと一緒だが、こちらは親要素にfocusを当てずに、直接子要素にfocusが当たった時の対処 */
  $('.megamenu_inner a').focus( function () {
    $(this).parents('div.megamenu').addClass('focused');
  }).blur(function(){
    $(this).parents('div.megamenu').removeClass('focused');
  });

  /* SPメニューのfocusを最後まで流していくと不可視のボタンがあり */
  /* そこにfocusが当たると.openが外れ、開いていた要素がすべて閉じる */
  $('a.js_navcls').focus( function () {
    $('.js_spnavwrap').stop().fadeToggle().toggleClass('open');
    $('.js_spnavbtn').toggleClass('open');
    $('.gnav .js_ac_btn').removeClass('open');
    $('.gnav div.js_ac_content').removeClass('open').css('display','');
  });
});

スクリーンリーダーに対応させる不可視テキスト(Visually Hidden)

Visually Hiddenと呼ばれるstyleのセットを用いることで、視覚的には確認できないが、スクリーンリーダー等の支援技術上で確認できる方法。
設定方法はいくつかあり、下記は一例です。

/* CSS */

.visually-hidden {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0,0,0,0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

アコーディオン開閉ボタンの支援技術対応

アコーディオンコンテンツの開閉状態や、それに伴う開閉ボタンのテキストを、読み上げ等の支援技術に対応させる。

/* HTML */

<div class="ac_wrap">
  <div class="ac_head">
    <h3>ダミータイトル</h3>
    <button type="button" tabindex="0" class="js_ac_btn" aria-expanded="false">開くボタン</button>
   /* 開閉ボタン */
  </div>
  <div class="js_ac_content"> /* 開閉部分 */
    <p>ダミーテキスト</p>
  </div>
</div>
/* Javascript */

$(function(){
  $('.ac_wrap .js_ac_btn').on("click", function() {	
    $(this).closest('.ac_wrap').find('div.js_ac_content').stop().slideToggle().toggleClass("open");
    $(this).toggleClass("open");
    if ('true' !== (this).getAttribute('aria-expanded')) {
    /* アコーディオンの挙動制御に加えて、aria-expandedの状態判定を追加 */
      (this).setAttribute('aria-expanded', 'true');
      (this).lastElementChild.innerText = "閉じるボタン";
    } else {
      (this).setAttribute('aria-expanded', 'false');
      (this).lastElementChild.innerText = "開くボタン";
    }
  });
});

アコーディオンのソースに、展開状態を示す「aria-expanded 属性」を記載し、Javascriptにはaria-expanded 属性の判定とボタンテキストの書き換えを記述。
これで、ボタンへマウスオンまたはフォーカスを当てると、ボタンのテキスト「開くボタン」とアコーディオンの状態「折り畳み」が読み上げられ、ボタンを押すと、テキスト「閉じるボタン」とアコーディオンの状態「展開」が読み上げられる。

さいごに

ここでまとめてきたソースは、変更と追加を重ねて再利用を繰り返してきた、付き合いの長いモノたちです。(特にHTMLとJS)
そんな継ぎ接ぎだらけのモノなので、今にして思えばもっとうまい書き方があると思いますし、今ならAIがソースも提供してくれる世の中で、便利になったなーと思います。・・・活用には至ったことないけど。

画像が一つもない味気ない記事になってしまったので、最近作ったタコ飯を載せて、締めとさせていただきます。

写真:タコ飯
タコの生姜煮を作り、そこからさらに錬成。


いいなと思ったら応援しよう!