ユーザー操作の一括無効化で役立つ!
HTMLのinert属性の紹介

179
68

HTMLやCSSには、ユーザーインタラクション(ユーザー操作)を無効化するための方法がいくつか存在します。たとえば、マウスやタッチ操作を無効化したいときはCSSでpointer-events: noneを要素に指定するなど、制御したいユーザー操作によってさまざまです。

カルーセルやモーダルなユーザーインターフェイス(UI)では、非アクティブな要素が操作されないように「画面には表示されているが、あらゆるユーザー操作を受け付けない状態」にしたい場合があります。具体的には、以下のユーザー操作を無効化します。

  • マウスやタッチ操作を無効化したい
  • テキスト選択を無効化したい
  • キーボードフォーカスをあえて無効化したい
  • 音声読み上げをあえて無効化したい

必要なプロパティや属性を複数指定することが考えられますが、そのようなときに役立つのがinertイナートと呼ばれるHTMLのグローバル属性です。

inert属性は、指定された要素を子孫要素含めて非活性な状態として扱い、あらゆるユーザー操作を無効化します。2023年4月12日にFirefox 112がリリースされたことで、主要なブラウザで利用可能になりました。

inert | Can I use…

inert属性のサポート状況

この記事では、inert属性について作例とあわせて紹介します。

inert属性の使い方

冒頭でも少し説明しましたが、inert属性を有効にすると子孫要素を含め要素を非活性な状態として扱い、あらゆるユーザー操作を無効化します。また、アクセシビリティーツリーからは削除され、音声読み上げソフトの読み上げも無効となります。

inert属性は論理属性で、JavaScriptではHTMLElement.inertを利用して値を指定します。

▼HTMLでの利用例

<div inert>
  <!-- div要素含め、子孫要素が非活性な状態となる -->
</div>

▼JavaScriptでの利用例

// id="target"の要素にinert属性を付与する
const element = document.querySelector("#target");
element.inert = true;

これまでの実装方法と比較

inert属性を使わずにinert属性の動作を再現する場合、次のいくつかの設定が必要でした。

  • クリックやタッチ操作を無効化する
    • CSSでpointer-events: noneを指定する
  • 選択を無効化する
    • CSSでuser-select: noneを指定する
  • キーボードフォーカスを無効化する
    • HTMLでtabindex="-1"を指定する
  • 音声読み上げを無効化する
    • HTMLでaria-hidden="true"を指定する

従来の方法では、UIの状態が切り替わるときにこれらの設定をJavaScriptで操作します。inert属性を利用することで各ユーザー操作をまとめて無効化できます。

inert属性を含め、それぞれの値を確認できるサンプルを用意しましたので、実際に触って確認してみてください。

▼各ユーザー操作を制御するサンプル

各ユーザー操作を制御するサンプル

操作を無効化する別の方法として、disabled属性で非活性化させる方法があります。disabled属性は特定の要素でのみ使用できる属性なので、該当しない要素をinert属性で制御するといった使いわけが考えられます。

また、disabled属性とinert属性はまったく同じものというわけでもなく、disabled属性の場合はアクセシビリティーツリーから残るといった挙動に違いがあります。

display: noneを使用することでもユーザーインタラクションを無効化できますが、要素自体が非表示になりレイアウトにも影響を与えてしまうため、同じ用途で使用できませんでした。

作例の紹介

ここからはinert属性の利用が考えられる作例を紹介します。

入力内容の送信から送信完了の間を制御する

次の作例は、入力内容の送信から送信完了までの間、一時的にユーザー操作を受け付けないようにしたものです。

実際には、入力内容は送信ボタンが押されてもどこにも送信されません。この作例では疑似的に送信をsetTimeout()で待機して、送信が完了したらアラートを表示する実装をしています。待機中はformタグを<div inert>で囲い、CSSで半透明にしています。

▼入力内容の送信完了を待機する例

入力内容の送信完了を待機する例

inert属性が設定されている間はフォームの操作を無効化し、表示上の送信連打防止も行えています。

注意点として、フォームでよく利用するfieldsetinputbuttonタグにはdisabled属性が存在します。これらの要素を個別で非活性化したい場合は、disabled属性を使用したほうがよりウェブ標準の仕様に準拠したマークアップができるかもしれません。

カルーセルUIの前後スライドに適用する

カルーセルUIを実装するとき、前後のスライドを見切れで非表示にしたり、反対にUIの視覚的なアフォーダンスを高めるために前後のスライドを部分的に表示したい場合があります。どちらの場合も、前後のスライドのユーザー操作を無効化したいときにinert属性が役立ちます。

次の作例は、Swiper.js(v8.4.7)というカルーセルライブラリを利用しつつ、前後のスライドのユーザー操作をinert属性で抑制しているサンプルです。前後のスライドは部分的に表示しています。

▼カルーセルUIの前後スライドを制御する例

カルーセルUIの前後スライドを制御する例

カルーセルUIの注意点として、前後のスライドをマウスやタッチ操作でスワイプできる場合があります。inert属性はマウスやタッチ操作を無効化してしまうため、スワイプ機能を保持するためには工夫が必要です。

作例ではマウスやタッチ操作によるスワイプ機能が存在するため、前後のスライド部分もスワイプできるように次の対応をおこないました。

  • スライドの親要素(.swiper-slide)は、音声読み上げのみ無効化(aria-hidden="true"
  • .swiper-slideの子要素にinert属性を指定

dialogタグを使用しないモーダルなUIで、背面を制御する

今回はハンバーガーメニューを例に紹介します。ハンバーガーメニューはメニューの構成がサイトによってさまざまで、dialogタグを利用せずモーダルな実装をすることが多いです。開かれたメニューを画面全域で覆ってモーダルダイアログのような表示にしたいとき、背面の制御にinert属性が役立ちます。

※HTML標準のdialogタグをshowModal()メソッドで表示すると、モーダルダイアログの外側が一切操作できなくなります。inert属性はそれと同様の動作を任意の要素で行えるものです。

背面の制御については『HTMLでモーダルUIを作るときに気をつけたいこと』の「課題2: 裏側にキーボードフォーカスされる現象」でも紹介しています。紹介記事では次の対策を行っていました。

  • 背面にキーボードフォーカスが当たらないようにJSで制御する
  • 背面の音声読み上げが行われないようにaria-hidden="true"を一時的に指定する

次の作例では、両方の対策をinert属性でまとめて行っています。

▼モーダルなメニューの背面を制御する例

モーダルなメニューの背面を制御する例

作例のポイントとして、キーボードフォーカスの順番が自然になるようにDOM構造では開閉ボタンの後ろにメニューを配置しています。

音声読み上げの対策は、aria-hiddenの指定と同じように必要な数だけinert属性の指定が必要ですが、それ以外の対策はまとめて行えています。

コラム: その他の注意点

inert属性が有効になっている要素は、Chromeの開発者ツールにある「ページ内から要素を選択する」機能で選択できません。デバッグの際によく利用されている方は注意が必要です。

開発者ツールから選択できない例

また、inert属性は指定しても画面上の表示は変化しません。属性の切り替わりを視覚的にわかりやすくしたい場合は、個別でスタイルの追加が必要です。

inert属性を指定してもスタイルが変更されない例

まとめ

あらゆるユーザー操作を無効化するinert属性について紹介しました。視覚的に表示しつつも、あらゆるユーザー操作を一時的に無効化したいときに役立ちます。使用の際は、各操作の動作確認も忘れずにおこないましょう。

disabled属性が利用可能な要素や、操作方法が複雑なUIでinert属性を利用したい場合はとくに検討が必要です。今回紹介した作例が参考になれば幸いです。

参考サイト

古舘 和志

フロントエンドエンジニア。ウェブデザイナーのようなHTMLコーダーからフロントエンドエンジニアに転身。現在は岩手からリモートで勤務中。

この担当の記事一覧