tailwindでsr-onlyとoverflowを組み合わせる時はpositionの設定をしておこう
現在PHPで動作しているシステムのフロントエンドを部分的にSvelteに置き換えています
その中でtailwindを用いてスタイルを記述するにあたりハマったので今後の参考のため残しておきます
私自身はバックエンドの開発をメインとして従事しております
この記事の読者としてはスタイルの記述に慣れていない方を想定しています
また今回筆者が遭遇した問題としてはSvelte+tailwindですが、根本的な部分においてはcssの知識となります
筆者の環境としては
- tailwind: 4.1.18
- Chrome: 143.0.7499.169
結論
tailwindでsr-onlyとoverflowを組み合わせる時はposition設定をしておきましょう
sr-only には position: absolute が設定されており、overflow-auto の子要素に sr-only が入っていると、ページ全体がスクロールされる場合があるためです
よくない例
<div class="overflow-auto">
<div>
<span class="sr-only">Badボタン</span>
<img src="./Bad.png"/>
</div>
</div>
よい例
<div class="overflow-auto">
<div class="relative">
<span class="sr-only">Goodボタン</span>
<img src="./good.png"/>
</div>
</div>
より詳細に説明します
そもそも sr-only とはなんなのか
これはtailwindが用意しているスクリーンリーダー用のクラスです
視覚的には表示しなくても良いが、VoiceOverなどを利用した読み上げ時には正しく伝わるようにするための読み上げ用の要素として利用します
See the Pen sr-only by yoshiki shiota (@yoshiki-shiota) on CodePen.
Macであれば cmd + F5で起動して要素をクリックすると読み上げ時にsr-onlyの要素を読み上げてくれることがわかります
このようにアクセシビリティを向上させるクラスの一つで、ファビコンなどの要素につけることによって本来読み上げられないものを読み上げられるようにします
overflow-autoとはなんなのか
続いて overflow-auto ですが overflowプロパティにautoを設定したもので子要素が親要素からはみ出た際の挙動を設定できます
overflow - CSS: カスケーディングスタイルシート | MDN
コンテンツが要素のパディングボックスに収まらない(はみ出す)場合に、水平方向および垂直方向の望ましい動作を設定します。
autoもしくはscrollと設定している場合、子要素が要素からはみ出た場合スクロールできるようになります
サンプルコードでは白色背景内が横スクロールできるようになっています
See the Pen overflow-auto by yoshiki shiota (@yoshiki-shiota) on CodePen.
次になぜpositionを設定しておいた方がよいかという話ですが
sr-onlyのプロパティは下記のようになっています
.sr-only{
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
border-width: 0;
}
position: absolute の記述があります、これによって直近のpositionが設定された親要素に対して絶対位置を取ります
もし、親要素になければその上の親要素に...最終的には文書に対しての絶対位置となります
ただし、topやrightプロパティの記述がない場合は元々の位置にいたように振る舞われます
下のサンプルを見てもらうと
- 1つ目はabsoluteがないので普通です
- 2つ目はabsoluteがあり、topおよびleftプロパティを設定しているので親要素(親要素にpositionがないのでルート)に対して絶対位置を取っています
- 3つ目はabsoluteがありますが、topおよびleftプロパティを設定していないため元の位置のように振る舞っています
See the Pen position by yoshiki shiota (@yoshiki-shiota) on CodePen.
一見すると1つ目も3つ目も変わらないように見えますね。なので問題なさそうですが実際にどういった場合に問題となるか見てみましょう
実際に記述しない場合どのような問題が発生するのか
私がハマったのは、コンポーネント内に sr-only を持つ共通コンポーネントを横スクロール可能な要素として設定していた時でした。
コードを書いて画面を見たら、なぜかページ全体が横スクロールできるようになっていて、「えっ、何これ?自分が書いたスタイルが間違ってた?」と思ったんです。
最初は原因がわからず3,4時間ほど時間をハマり、時間を溶かしてしまいましたが一つづつ要素を消して検証した結果原因を突き止めました。
以下、当時の状況を再現したサンプルコードです
触ってもらったら横スクロールする要素以外にドキュメント全体が横スクロールできることに気づいたかと思います
See the Pen sr-only-with-overflow-auto by yoshiki shiota (@yoshiki-shiota) on CodePen.
より分かりやすく可視化したのが下記のサンプルコードです
See the Pen scroll with absolute by yoshiki shiota (@yoshiki-shiota) on CodePen.
purpleと末尾のredのdiv内に記載されている absolute という文字が子要素をスクロールしても表示されず
ページ全体をスクロールして初めて確認できると思います
子要素内にabsoluteの記述がある場合、追従するのではなく親要素(ルートドキュメント)に対しての絶対位置を取るため
その位置まで横スクロールが可能となります
解決策
ここまで理解できれば、解決策は明確です。
sr-onlyを設定する要素の親にrelativeをつけてあげればいいんです。たったこれだけで、absoluteな要素が親要素を基準にしてくれるようになります。
position: absoluteの記述があります、これによって直近のpositionが設定された親要素に対して絶対位置を取ります
もし、親要素になければその上の親要素に...最終的には文書に対しての絶対位置となります
前項目でこのように記述した通りのことを実施する必要があるということです
実際に設定を行ったのはこちらです
See the Pen scroll-with-sr-only-with-relative by yoshiki shiota (@yoshiki-shiota) on CodePen.
それを可視化したのはこちらになります
See the Pen scroll with relative by yoshiki shiota (@yoshiki-shiota) on CodePen.
子要素と一緒にabsoluteが設定されている要素も追従されていることが確認できます
まとめ
以上のことより tailwindでsr-onlyを設定するときは親要素にrelativeを設定することで解決できるといった話でした。