アクセシビリティ対策用カンニングコード
以前ポストした「コーディング視点からの、ウェブアクセシビリティ対応」を基に、実際どう組んでいたか、(自分が)特に忘れやすい部分を思い出すため用のカンニングコードをまとめてみました。
フォントの相対指定
直観的に記述するなら、ベースとなるサイズ指定の時点で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がソースも提供してくれる世の中で、便利になったなーと思います。・・・活用には至ったことないけど。
画像が一つもない味気ない記事になってしまったので、最近作ったタコ飯を載せて、締めとさせていただきます。