🐙

「1文字ずつ表示」させただけで終わるのはエアコンつけたまま実家に帰るのと同じ【アクセシビリティ】

2022/07/09に公開約2,000字7件のコメント

突然のコードサンプル

よくみるヤツに今更何を?

1文字ずつ表示する系の演出自体は頻繁に要求されるので「はいはい、アレね」くらいのテンションでやっていましたが、上記ツイートの参考サイトとして掲載されていた

https://www.richardekwonye.com/about
↑である気づきを得ました。

1文字ずつ表示させて満足したら困るユーザーがいる

大量生成されたspanが全部アクセシビリティツリーに入っちゃったらスクリーンリーダーユーザーは「エイチ オー ジー イー エフ ユー ジー エー」みたいに読み上げられて「?」状態になってしまうという、ちょっと考えたらわかることを見落としていました。大量生成されたspanにはaria-hidden="true"が指定されていなければならない...
悔い改めたコードを供養します。

ソース

思いつきで書いたので伸び代のあるコードに仕上がってると思いますがご容赦ください

HTML

    <p class="text-onebyone">
      <span class="for-accessibility">1文字ずつ表示させる</span>
      <span class="text-split">1文字 ずつ 表示 させる</span>
    </p>

SCSS

.text-onebyone {
  position: relative;
  .text-split {
    font-size: 4rem;
    clip-path: inset(0 0 0);
    .text-each {
      display: inline-block;
      opacity: 0;
      transform: translateY(100%);
      &.is-active {
        transition: 1s;
        opacity: 1;
        transform: translateY(0%);
      }
    }
  }
  .for-accessibility {
    position: absolute;
    width: 1px;
    height: 1px;
    clip: rect(0, 0, 0, 0);
  }
}

JavaScript

const textOneByOne = document.querySelector(".text-split");
let getText = textOneByOne.textContent;
textOneByOne.textContent = "";
getText = getText.split("");
getText.forEach(function (elem, index) {
  const newText = "<span aria-hidden='true' class='text-each'>" + elem + "</span>";
  textOneByOne.insertAdjacentHTML("beforeend", newText);
});

const textEach = textOneByOne.querySelectorAll(".text-each");
const delayTime = 100; //何秒遅れで次の文字が表示されるか設定

textEach.forEach(function (elem, index) {
  setTimeout(function () {
    elem.style.transitionDelay = delayTime * index + "ms";
    elem.classList.add("is-active");
  }, delayTime);
});

おわり

引用元のツイート著者も発信していますが、隠れている部分をoverflowではなくclip-pathで実現するのがclip-pathのプチハックとして満足度が非常に高かった...
WAI-ARIAにわかなので、アクセシビリティ的に「ここ詰め甘いぞ」ってポイントあるかもしれません。誤りを流布したくないのでご指摘頂けると非常に助かります

Discussion

spanを付けるとスクリーンリーダーが区切られるのってどの環境かお分かりになりますか…?

macのVoiceOverで軽く試した時は普通に流暢に読まれたので自分は今簡易実装にしてるのですが、
しっかり確認できていないので変になるなら直さないといけないと思いまして…🙇

続けてすみません。
aria-labelとaria-hiddenの組み合わせでも良さそうですね。

https://qiita.com/uto-usui/items/9208afc3955c7465e554

とりあえず自分の環境もコード修正しとこうと思います。
お陰で気づく事ができました!ありがとうございました!

自分もmac+iOSだと問題なく読み上げられたのですが、「リーダーによって挙動が変わるから挙動はブラックボックス」みたいな記載を見かける + 参考サイトがaria-hidden="true"だったので、あ〜読み上げられるリーダーあるのかなと思った次第でした...!!

aria-labelとaria-hiddenアリですね!ありがとうございます!こっちのほうがよさそう!

早速ありがとうございます!
なるほどです。たまたまmacが賢かっただけのようですね…。
もっと自分もちゃんと意識しようと思います!
ご確認ありがとうございました!

ありがとうございます!
genericにこそlabel指定したくなるんですけどねーそもそもgenericにlabelを指定しなければならないようなマークアップをするなという啓示なのか...

本当まさにその通りで、
今進めている実務でspanにlabel設定してしまっていたので危なかったです…。
genericでも指定できるよう改定してくれたら良いのですが😅

ログインするとコメントできます