CSS の scripting
メディア特性を使うことで、ウェブブラウザをはじめとする、ユーザエージェントの JS のサポート状況に応じて、スタイルを出し分けることができます。
この記事では、この scripting
メディア特性の基本説明に加え、実例を挙げながら利用シーンを考えていきます。
前提
見出し「前提」scripting
メディア特性は、W3C の仕様では「Media Queries Level 5」に属しており、草案(Working Draft)段階のため、今後、実装方法や機能に変更が発生する可能性があります。
また、この scripting
メディア特性は、主要なブラウザでサポートされていますが、Safari でのサポートは 17.0 からと比較的最近なので、こちらも注意が必要です。
scripting メディア特性の基本
見出し「scripting メディア特性の基本」scripting
メディア特性には、none
、initial-only
、enabled
の値を指定できます。
以下のコードのように、none
は JS が無効なときのスタイル、enabled
は JS が有効なときのスタイルを指定できます。
/* JS が無効なときのスタイル */
@media (scripting: none) {
.foo {
display: block;
}
}
/* JS が有効なときのスタイル */
@media (scripting: enabled) {
.bar {
display: block;
}
}
none
の判定は、ユーザが明示的に JS を無効化した場合のみならず、通信速度が極端に遅いときのような外的要因によって、ユーザエージェント側で自動的に JS が無効に切り替わるケースも考えられるかもしれません(可能性は極めて低いですが)。
例えば、Android Chrome では、2018 年に「データセーバ」がオンの状態で、2G 以下のネットワークを使用しているときに、自動的に JS が無効になる機能がデフォルト設定になりました1。ただ、Chrome のバージョン 100 で「ライトモード(かつてのデータセーバ)」が廃止されたので2、今ではこの機能もなくなっているのかもしれません(どうなんでしょう?)。
initial-only
は、W3C の仕様ではドキュメントを読み込んだときにだけ JS が有効になる環境が該当するとあります。例として、印刷されたページや、プロキシサーバを介してほぼ静的なページが配信されるケース(JS が制限されたケース)が想定されているようです。
現時点では、initial-only
を使用する場面はあまり考えられません。
以下は、何の面白みもないデモですが、ユーザエージェントの JS が利用できる状況に応じてランプが点灯します。通常は enabled
が点灯していると思われますが、ブラウザの設定などを変更して、JS を無効にすると none
が点灯します。
scripting
メディア特性に非対応の環境では、どのランプも点灯しません。
- none
- initial-only
- enabled
ブラウザで JS を無効にする方法はいくつかありますが、デベロッパーツールが使用できる状況では、それぞれ以下のとおりです。
Google Chrome / Microsoft Edge で JS を無効にする設定
デベロッパーツールを開いて「設定 > (基本)設定 > デバッガ」の「JavaScript を無効にする」のチェックボックスを選択します。

もしくは、Command + Shift + P キーでコマンドパネルを開いて、javascript
や js
とタイピングすると「JavaScript を無効にする」の項目が表示されます。

Firefox で JS を無効にする設定
デベロッパーツールを開いて「設定 > 詳細設定」の「JavaScript を無効化」のチェックボックスを選択します。

Safari で JS を無効にする設定
メニューバーの「開発」から「JavaScript を無効にする」を選択します。

「開発」メニューが表示されていない場合には、メニューバーの「Safari」から「環境設定」を開いて、「詳細」タブから「メニューバーに開発メニューを表示」を選択します。
利用シーン
見出し「利用シーン」ここからは、実例を挙げながら、scripting
メディア特性の利用シーンを考えてみます。
例1: ローディング画面
見出し「例1: ローディング画面」まず、ローディングイメージやプログレスバー、ローディングスピナーなどの、リソースの読み込みを待機している状態を表現する画面がページ全体を覆っている状況を考えてみます。
これらのローディング画面はリソースの読み込みが完了すると非表示になりますが、JS で制御されている場合、無効の状況ではいつまでもローディング画面が消えません。
このケースで scripting
メディア特性を使用するには、デフォルトでローディング画面を非表示にして、scripting: enabled
で表示するのがよいでしょう。

/* デフォルトは非表示 */
.loading {
display: none;
}
/* JS が有効なときに表示 */
@media (scripting: enabled) {
.loading {
display: block;
}
}
JS で style
プロパティを指定しても同じことが実現できますが、CSS で指定することにより、ローディング画面を表示するまでの遅延を少なくすることができます。
例2: 段階的開示
見出し「例2: 段階的開示」次に、いくつかのステップに分かれて進んでいくような UI で、通常のリンク遷移ではなく、JS のクリックイベントをきっかけに、動的にステップが切り替わるケースを考えていきます。
こちらは先ほどの例とは逆に、デフォルトでは次のステップを表示しておき、scripting: enabled
で非表示にするのがよいでしょう。

/* デフォルトは表示 */
.step2 {
/* ... */
}
/* JS が有効なときに非表示 */
@media (scripting: enabled) {
.step2 {
display: none;
}
}
ただ、JS が有効であったとしても、Safari 16.x のように scripting
メディア特性がサポートされていない環境では、JS 無効時と同じ見え方になります。
レイアウトシフトに注意する必要はありますが、このようなケースでは JS 側でもスタイルを指定するのが無難かもしれません。
const isSupported = window.matchMedia('(scripting: enabled)').matches;
if (!isSupported) {
const step2 = document.querySelector('.step2');
step2 && step2.style.display = 'none';
}
例3: サードパーティ製のウィジェット
見出し「例3: サードパーティ製のウィジェット」SNS のタイムラインなどを表示する、サードパーティ製のウィジェットが JS で生成されるケースを考えてみます。
ウィジェットの外側に、見出しなどの静的な要素が含まれていることが一般的ですが、この場合には scripting: none
を使用して、見出しを含めたエリアごと非表示にする方法が考えられます。

<div class="widget">
<h3>SNS</h3>
<!-- 埋め込みコード -->
<iframe src="...">
</div>
<style>
/* JS が無効なときに非表示 */
@media (scripting: none) {
.widget {
display: none;
}
}
</style>
ただ、このケースでは、scripting
メディア特性を使うのではなく、<noscript>
要素で補足説明を表示したほうが適切かもしれません。

<div class="widget">
<h3>SNS</h3>
<!-- 埋め込みコード -->
<iframe src="...">
<noscript>
<p>このコンテンツは JavaScript を有効にする必要があります。</p>
</noscript>
</div>
例4: JS 前提のサイト
見出し「例4: JS 前提のサイト」全面的にクライアントサイド JavaScript が前提となるサイトでは、JS を無効にするとコンテンツが何も表示されなくなります。
ここでは scripting
メディア特性を使用するのではなく、HTML の <noscript>
要素を使用して、コンテンツが表示されない理由を説明をしたほうがよいでしょう。
<div id="app"></div>
<noscript>
<p>このウェブサイトを閲覧するには JavaScript を有効にする必要があります。</p>
</noscript>
このように、JS が無効なときに代替コンテンツが必要になる場面では、<noscript>
要素を使用するのが適切だと考えられます。
おわりに
見出し「おわりに」この記事では、実例を取り上げながら scripting
メディア特性の使用方法を説明しました。
JS が無効になるケースはかなり限られているとはいえ3、主要なコンテンツやナビゲーションについては、最低限の情報を取得できるように対応をしておくのがよいかもしれません。
ネットワークの高速化やブラウザの進化により、JS を使用したリッチな表現や機能が増える一方で、モバイルユーザが大多数になっていることや、ウェブサステナビリティの観点から、データ通信量や消費電力の少ないサイトが求められていることも事実です。
また例えば、電力需給が逼迫している状況や、大きな災害に被災した状況でインターネットを利用する場面において、JS を無効にすることで通信量の抑制やバッテリーを長持ちさせることにつながるので、そのような側面がもう少し議論されてもいいのかもしれないと感じています。
もちろん JS が不要だと主張したいわけではないですが、前回の記事「HTML Web Components とは何か」でも触れた Progressive Enhancement な思想をベースに、改めて考えてきたいです。
参考文献
見出し「参考文献」本記事の作成にあたり、以下のウェブページを参考にしました。
- scriptingメディア特性のinitial-onlyについて | ミツエーリンクス(外部リンクを開く)
- CSS Media Query for Scripting Support | The Web Witch's Blog(外部リンクを開く)
- Media Queries Level 5 | W3C(外部リンクを開く)
脚注
-
Feature: Intervention: Disable scripts for Data Saver users on slow connections | Chrome Platform Status ↩
-
Sunsetting Chrome Lite mode in M100 and older |Google Chrome Community ↩
-
JS 無効に関する包括的な調査データは見つかりませんでしたが、WebAIM による「Screen Reader User Survey #9 Results(2021)」では、スクリーンリーダーを利用するユーザが、JS を無効にしている割合は 0.6% でした。 ↩