【テクニカル・上級編】 :fullscreen 擬似クラス – CSS実践ガイド

こんにちは。フロントエンドの現場で日々、CSSの不可解な挙動やブラウザの気まぐれなレンダリングパイプラインと格闘しているエンジニアなら、一度は「フルスクリーンAPI」の沼にハマったことがあるはずだ。

モーダル、動画プレイヤー、ビジュアライザー、あるいは高度なキャンバスベースの描画アプリケーション。画面いっぱいにコンテンツを引き伸ばすために、私たちはJavaScriptの `Element.requestFullscreen()` を叩き、そのステート変化を監視する。しかし、ここで一つの問いが生まれる。

「なぜ、JavaScriptで状態を管理するだけでなく、CSSの `:fullscreen` 擬似クラスをアーキテクチャの根幹に組み込む必要があるのか?」

今回は、単なる「画面いっぱいに広げるスタイリング」という初歩的な話はしない。ブラウザのレンダリングエンジン(Blink, Gecko, WebKit)の内部挙動、メモリ効率、非同期ステートの競合、そして実務で踏み抜く地雷の回避策まで、`:fullscreen` 擬似クラスを極限まで使い倒すための実践的知見を共有しよう。

—

1. なぜ `:fullscreen` なのか? JSステート駆動との決定的な違い

モダンなフロントエンド開発において、ReactやVueなどのフレームワーク全盛の今、UIの状態はすべてJavaScriptのステート(例: `isFullScreen: boolean`)で管理したくなる。DOMに `data-fullscreen=”true”` のような属性を付与し、それに依存したCSSを書く設計もよく見かける。

だが、チーフアーキテクトの視点から言わせてもらえば、これはメンテナンス性の低いアンチパターンになり得る。

メモリ効率とスタイリングの分離

JavaScriptによるステート管理は、イベントリスナーの登録、仮想DOMの差分検出、そして属性の変更によるDOMの再描画(Relayout / Repaint)というオーバーヘッドを伴う。
一方、Fullscreen APIはブラウザのネイティブ機能だ。ユーザーが `Esc` キーを押したり、ブラウザのセキュリティポリシーによって強制解除されたりした場合、JavaScriptのステートとDOMの状態が同期ズレを起こすバグ(いわゆる「嘘をつくUI」)が頻発する。

`:fullscreen` 擬似クラスは、ブラウザが管理する真のフルスクリーン状態に直接フックする。
JavaScriptの肥大化を防ぎ、レンダリングエンジンとCSSOM(CSS Object Model)のレイヤーで完結するため、メモリ効率の観点からも極めて優れている。

—

2. レンダリング負荷とレイアウトシフト(CLS)の最適化

フルスクリーン移行時に最も恐ろしいのは、突然のレイアウトシフト(CLS)や、GPUアクセラレーションの剥奪によるカクつきだ。

フルスクリーン化された要素は、ブラウザによって強制的にルート(Viewport)サイズにリサイズされる。この時、親要素のレイアウトコンテキストから一時的に切り離され、Top Layer(最上位レイヤー)と呼ばれる特別なレンダリングスタックに配置される。

ここで、安易に `width: 100vw; height: 100vh;` などを `:fullscreen` 内で指定すると、不要な再計算(Recalculate Style)やリフローを引き起こす。実務で堅牢なコードを書くための、最適化されたCSSアーキテクチャの例を見てほしい。

/ フルスクリーン対象のコンテナ:GPUアクセラレーションを事前に強制 /
.app-media-container {
position: relative;
width: 100%;
height: 400px;
/ 事前にレイヤーを昇格させ、フルスクリーン移行時のリペイントコストをゼロにする /
will-change: transform;
transform: translateZ(0);
transition: background-color 0.3s ease;
}

/
:fullscreen 擬似クラスの適用
ブラウザのTop Layerに移動した瞬間、自動的にビューポート全体を覆う。
ここではサイズ指定ではなく、フルスクリーン時特有の「見た目の装飾」と「内部レイアウトの変更」に集中する。
/
.app-media-container:fullscreen {
/ フルスクリーン時は背景を完全に不透明な黒にする(余白対策) /
background-color: #000000;

/ 内部の子要素(コントロールパネルなど)の配置をグリッドで再構築 /
display: grid;
grid-template-rows: 1fr auto;

/ パディングやマージンのリセット(親の制約から解放されるため) /
padding: 0;
margin: 0;
width: 100vw;
height: 100vh;
}

/ ベンダープレフィックスの現実:
Gecko (Firefox) と Blink/WebKit (Chrome, Safari) で仕様の歴史的経緯があるため、
実務ではプレフィックス併用が不可避。 /
.app-media-container:-webkit-full-screen {
background-color: #000000;
}
.app-media-container:-moz-full-screen {
background-color: #000000;
}

—

3. 非同期の競合と「一瞬の破綻」を防ぐテクニック

Fullscreen APIは完全に「非同期(Asynchronous)」で動作する。`requestFullscreen()` を呼んでから、実際にブラウザがフルスクリーン状態に移行し、`:fullscreen` セレクタがヒットするまでの間には、数ミリ秒のタイムラグが存在する。

この非同期のタイムラグの間に、JavaScript側でDOMの構造を激しく書き換えたりすると、ブラウザのレンダリングパイプラインが混乱し、画面がブラックアウトしたり、スタイルが適用されないまま中途半端なサイズで固まるという重大なバグ(レンダリングのデッドロック)を引き起こす。

解決策:CSSのトランジションと状態のデカップリング

JavaScript側で無理やりクラスを付け替えるのではなく、`:fullscreen` の適用をトリガーにした純粋なCSSアニメーション・トランジションで繋ぐのが、最も堅牢なアーキテクチャだ。

/ トランジションの基本定義:フルスクリーン移行前後のギャップを埋める /
.modal-dashboard {
/ 通常時のスタイル /
transform: scale(1);
opacity: 1;
transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1),
opacity 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

/
フルスクリーン移行の瞬間をCSSで優雅にハンドリングする。
ブラウザがTop Layerに要素を配置した直後、このセレクタが非同期に発火する。
/
.modal-dashboard:fullscreen {
/ 必要であれば、フルスクリーン移行時にスケールアニメーションを走らせることも可能 /
transform: scale(1);
width: 100% !important;
height: 100% !important;
}

/ フルスクリーン解除時のパフォーマンス担保 /
.modal-dashboard:not(:fullscreen) {
/ 戻るときのトランジション挙動を制御 /
}

—

4. 上級者が知るべき罠:`:backdrop` 擬似クラスとの共生

`:fullscreen` を語る上で絶対に外せないのが、兄弟(あるいは裏側)に存在する `:backdrop` 擬似クラス だ。

要素がフルスクリーンモードに入ると、ブラウザは自動的にその要素の背後(下層)に、全画面を覆う見えない(あるいはデフォルトで黒い)レイヤーを生成する。この背景レイヤーをスタイリングするのが `:backdrop` だ。

よくあるバグとして、「フルスクリーンにしたのに、背後が白くチラつく」「動画以外の部分に変な余白が見える」というものがある。これは `:backdrop` のデフォルトスタイルがブラウザ依存であることに起因する。

堅牢なWebアプリケーションを作るなら、`:fullscreen` と `:backdrop` はセットで制御しなければならない。

/ フルスクリーン要素自体のスタイリング /
.video-player-wrapper:fullscreen {
width: 100vw;
height: 100vh;
object-fit: contain;
}

/
【重要】:backdrop を制圧する
フルスクリーン時の背景を完全にコントロールし、
ブラウザごとのデフォルト挙動の差異(Flickerや予期せぬ色)を完全に排除する。
/
.video-player-wrapper:fullscreen::backdrop {
background-color: #050505; / 純粋な黒ではなく、わずかに階調を持たせたダークトーン /
backdrop-filter: blur(10px); / 余裕があれば背景をぼかすなどのリッチな演出も可能 /
}

/ ベンダープレフィックスも忘れない /
.video-player-wrapper:-webkit-full-screen::backdrop {
background-color: #050505;
}
.video-player-wrapper:-moz-full-screen::backdrop {
background-color: #050505;
}

—

5. チーフアーキテクトからの提言

`:fullscreen` 擬似クラスは、単なる「便利なセレクタ」ではない。
JavaScriptの肥大化を防ぎ、ブラウザのネイティブなレンダリングエンジンに状態管理の大部分をオフロードするための、極めて強力なアーキテクチャ・ツールである。

フロントエンドのコードベースが複雑化するにつれて、私たちは「JavaScriptでできること」を増やしすぎてしまいがちだ。しかし、CSSが本来持っている宣言的なパワー、特に擬似クラスのレイヤーを活用することで、コードはより堅牢に、メモリ効率はより高く、そして予期せぬバグから解放された美しいアプリケーションへと昇華していく。

次にフルスクリーン機能を実装する時は、JavaScriptのステートに頼り切るのではなく、`:fullscreen` と `:backdrop` にその身を委ねてみてほしい。ブラウザが持つ本来のポテンシャルを、CSSを通じて最大限に引き出す快感がそこにはあるはずだ。

コメント

タイトルとURLをコピーしました