アクセシビリティのためによく書く CSS

アクセシビリティを意識した CSS に関するいくつかの tips です。

## スクリーンリーダー用のテキスト

テキストを視覚的には隠したいけどスクリーンリーダーには伝えたい、デザイン上にタイトルはないけどマークアップで見出しを入れて構造化したい要件などを実現するために、要素を隠すような CSS を書きます。

たとえば、Apple の [ホーム](https://www.apple.com/) にアクセスしてみると、次のような CSS で隠された `h1` を見つけることができます。

```scss
.visuallyhidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip: rect(1px, 1px, 1px, 1px);
  -webkit-clip-path: inset(0px 0px 99.9% 99.9%);
  clip-path: inset(0px 0px 99.9% 99.9%);
  border: 0;
}
```

要素にはいろいろな隠し方がありますが、`display: none` や `visibility: hidden` だと支援技術は認識しません。この辺りはいろいろな hack が入り組んだスタイリングになっていますが、次のスニペットや Bootstrap のヘルパーが参考になります。

- [Improved .sr-only · GitHub](https://gist.github.com/ffoodd/000b59f431e3e64e4ce1a24d5bb36034)
- [Accessibility · Bootstrap](https://getbootstrap.com/docs/4.0/getting-started/accessibility/#visually-hidden-content)

ぼくは Bootstrap の mixin を参考にしています。

```scss
@mixin sr-only {
  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;
}
```

## 要素の順序が乖離する

Flex や Grid などで要素の順序を変更した場合、DOM の順序と実際に表示される順序が違ってしまう現象がおきます。キーボード操作やスクリーンリーダーに大きな影響を与えるので、フォーカスされる要素の積極的な順序変更には注意が必要です。

- [HTML Source Order vs CSS Display Order | Adrian Roselli](https://adrianroselli.com/2015/10/html-source-order-vs-css-display-order.html)
- [フレックスアイテムの並べ替え - CSS: カスケーディングスタイルシート | MDN](https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Flexible_Box_Layout/Ordering_Flex_Items)

## 分割したテキストのフォロー

CSS でアクセシブルにするのではなく、ちょっと分脈がそれますが、テキストを分割して 1 文字ずつ CSS アニメーションするときなどに HTML で対応しておきたい tips です。

スクリーンリーダーによっては `<span>` などでスプライトしたテキストたちをひとつの単語として読み上げてくれない場合があります。テキスト集合を `aria-label` でラベリングして `aria-hidden` で元の文字列を無視するよう、スクリーンリーダーに伝えることで解決します。

```html
<div aria-label="accesible text">
  <span aria-hidden="true">
    <span>a</span>
    <span>c</span>
    <span>c</span>
    <span>e</span>
    <span>s</span>
    <span>i</span>
    <span>b</span>
    <span>l</span>
    <span>e</span>
    <span> </span>
    <span>t</span>
    <span>e</span>
    <span>x</span>
    <span>t</span>
  </span>
</div>
```

## 印刷用のスタイルシート

印刷用のスタイルシートを用意することもアクセシビリティ対応のひとつだと考えています。印刷用のルールはメディアクエリで分岐して簡単に記述できます。

```css
@media print {
  .print-only {
    ...
  }
}
```

調整する内容としては、文章中のリンク先 URL を明示したりするなど印刷時に不足する情報を補ったり、改ページの指定などレイアウトを整えたりするといいと思います。

次のガイドに基本的な tips が集まっています。

- [A Guide To The State Of Print Stylesheets In 2018 — Smashing Magazine](https://www.smashingmagazine.com/2018/05/print-stylesheets-in-2018/)

また関連として、未来の CSS で page floats という仕様があります。 区切られるページの一番上部にコンテンツを持ってくることなどを可能にしてくれます。`float` のプロパティとして機能することもあり、おもしろいので注目しています。

- [Things We Can’t (Yet) Do In CSS — Smashing Magazine](https://www.smashingmagazine.com/2019/11/css-things-cant-yet-do/)
- [Paged Media approaches : page floats – Paged Media](https://www.pagedmedia.org/page-floats/)
- [CSS Page Floats](https://drafts.csswg.org/css-page-floats/)

## デザイナーへアラートするための簡単なチェック

CSS を書いているときによく気付く（フォントサイズやコントラストとか）、デザインレイヤーで検討するべきアクセシビリティ項目もいろいろありますよね。もちろん、デザイナーがアクセシブルなデザインを作ってくれるような文化や理解やガイドラインが整っているのが理想ですが、なかなかそうでない場合や見落としもよくあると思います。このあたりをうまくエンジニアがデザイナーに相談しつつ連携できると、優しいサイトが実現できるなーという意識を持って作業したいです。

こちら CSS Advent Calendar 2019 でした。
よいお年をお迎えください🐈

* [CSS Advent Calendar 2019 - Qiita](https://qiita.com/advent-calendar/2019/css)

おわります。