【HTML】inert 属性でコンテンツをまとめて不活性にする

特定のコンテンツに注目させたいときや、何かしらの処理を実行中の場合など、それ以外のコンテンツをユーザーが操作できないようにしたいと考えたことはないでしょうか。

たとえばフォームの送信ボタンを押したら、フォームコントロールを無効にして操作できないようにする、というシーンを思い浮かべると思いますが、さらにもう一歩進んで、クリックも無効にし、テキストも選択できないようにするにはどうすれば良いでしょうか。そのような状態を「不活性」と呼びますが、それを実現するのが inert 属性です。

今回は、Safari 15.5、Chrome 102 で実装された inert 属性について詳しく紹介します。

不活性(inert)の定義

要素が不活性であるとは、次のような状態を指します。

  • ポインターイベントが無効な状態、つまり、クリックやドラッグなどが無効な状態(CSS の pointer-events プロパティに none がセットされたのと同じ状態)
  • テキスト選択が無効な状態(CSS の user-select プロパティに none がセットされたのと同じ)
  • 編集可能な要素(contenteditable 属性に "true" がセットされた要素)が編集不可になった状態
  • ブラウザーのページ内検索の対象にならない状態

上記の条件を満たすと、フォーカスもできなくなります。この不活性な状態になるものとして代表的なのは、dialog 要素のモーダルダイアログのバックドロップです。モーダルダイアログが表示されている間は、その背景となるコンテンツはすべて不活性な状態となり、ユーザーはそれらコンテンツを選択したり操作したりできません。

このバックドロップと同様の状態を意図的に作り出すのが inert 属性です。

オーバーレイで解決できない不活性化

これまで前述の不活性な状態を疑似的に作りす方法として、オーバーレイという手法が良く使われてきました。オーバーレイとは、不活性にしたいコンテンツを div 要素で覆い隠すことでユーザーが操作できないようにする手法です。

一見、問題ないように見えますし、実際にそうしている JS/CSS ライブラリーも多いのも事実です。ところが、問題ないのは PC でマウス操作している人やスマートフォンでタップする人に限った話です。

スクリーンリーダーなどの支援ツールの場合、オーバーレイ方式は何も解決しません。支援ツールから見れば、依然、そこには背景のコンテンツが存在し操作可能なのです。

支援ツールに対する対策として、そもそもフォーカスできなければ問題を緩和できます。そこで一つの案として良く使われるのは tabindex="-1" をセットする方法です。こういった様々な利用者の状況やマウスなどの入力デバイスに対して問題を緩和するべく考えられる方法として、tabindex 以外にも、aria-hidden="true" をセットしたり、CSS で user-selectpointer-events プロパティに none をセットしたりとキリがありません。またすべての要素に対して対策しないといけませんので、手間も相当なものです。

このような問題を解決するべく用意されたのが inert 属性です。

inert 属性の使い方

前置きがかなり長くなりましたが、inert 属性は Boolean 属性であり、使い方はいたって簡単です。inert 属性がマークアップされた要素およびその子孫要素すべてが不活性な状態になります。

次のサンプルでは、div 要素に inert 属性がマークアップされていますが、その div 要素の中には input 要素、contenteditable 属性で編集可能な div 要素、button 要素によるボタンがマークアップされています。

<div inert>
  <p>おはよう。</p>
  <p><input type="text" value="こんにちは"></p>
  <p contenteditable="true">こんばんは</p>
  <p><button type="button">おやすみ</button></p>
</div>

以下は、上記のマークアップのレンダリング結果です。(キャプチャー画像ではありません。)

おはよう。

こんばんは

Chrome, Safari であれば、テキスト選択や編集や押下できないはずです。

不活性なコンテンツのスタイリング

inert 属性によって不活性になったコンテンツは、基本的に見た目では大きな変化がありません。フォームコントロールの disabled 属性であれば無効化が一目瞭然なのとは対照的です。もし不活性になっているにも関わらず違いが分からないというのは、利用者にとっては不便と言えるでしょう。

もっともシンプルな対策としては次のような CSS が有効でしょう。次の CSS では、inert 属性が存在する要素のコンテンツに対して透明度を 0.5 にしています。

[inert] {
  opacity: 0.5;
}

おはよう。

こんばんは

もちろん半透明である必要性はありませんが、何かしらユーザーに違いが分かるようにするのが良いでしょう。

まとめ

inert 属性は、もともとは dialog 要素のモーダルダイアログ用に考えられたものです。いったんは仕様から削除されましたが、その後、ダイアログ以外のユースケースが提案され、グローバル属性として復活したという経緯があります。

inert 属性で簡単にコンテンツを操作できないようにするだけでなく、スクリーンリーダーといった支援ツールにとっても有益となりますので、積極的に使っていきたいですね。2022 年 6 月現在、Firefox はまだ inert 属性をサポートしていませんが、Nightly には実装されているようです。また、Edge もまだサポートしていませんが、ベースとなる Chromium ではすでにサポートされていますので、いずれすべてのメジャーブラウザーで利用可能になるでしょう。

今回は以上で終わりです。最後まで読んでくださりありがとうございました。それでは次回の記事までごきげんよう。

Share