概要
クロスブラウザ対応とは「古いブラウザを使えるようにする」ことではない。
それは**“あらゆる実行環境で、想定通りに動作し、体験の破綻を回避するために構造的に差異を吸収する設計”**である。
特定APIが使えない、CSSが反映されない、イベント挙動が異なる。
このような**「仕様に忠実すぎる」JavaScript**は、逆に動作保証ができないことが多い。
1. “想定外環境”の種類を把握する
- 古いAndroidブラウザ(WebViewベース)
- Safariの制限(input挙動・IntersectionObserver)
- Firefoxのセキュリティ制約
- iOS WebKit独自仕様
- 企業端末(IE11相当 or Edge Legacy)
- ✅ モダン環境だけを前提にしない
- ✅ 少数ユーザーでも「使えない」は UX破綻
2. 標準APIの利用前に feature detection(存在確認)を行う
if ('IntersectionObserver' in window) {
new IntersectionObserver(callback).observe(el);
} else {
// フォールバック処理
window.addEventListener('scroll', fallbackCheck);
}
- ✅
in
演算子、typeof
、try-catch
で確認 - ✅ 存在しないならフォールバック or 機能無効化へ
3. ポリフィル vs フォールバックの選択基準
- ポリフィル:動作そのものを「再現する」ライブラリ(例: core-js, smoothscroll-polyfill)
- フォールバック:機能を「簡易化 or 無効化」する(例: lazyload → 即時表示)
技術 | ポリフィル | フォールバック |
---|---|---|
Promise | 必須 | 再設計困難 |
Fetch API | ポリフィル可 | XMLHttpRequest等代替 |
LazyLoad | 任意 | loading属性削除で即読み込み |
4. UA判定ではなく “機能ベース” の検出に徹する
// ❌ NG: UAによる判定は壊れやすい
if (navigator.userAgent.includes('Safari')) {}
// ✅ OK: 機能存在確認による分岐
if ('scrollBehavior' in document.documentElement.style) {
scrollTo({ top: 0, behavior: 'smooth' });
} else {
window.scrollTo(0, 0);
}
- ✅ ユーザーエージェントは偽装や変更で簡単に壊れる
5. ビルド時に環境差異を吸収する(Babel + core-js)
npm install --save core-js
// Babel設定
"presets": [
["@babel/preset-env", {
"useBuiltIns": "usage",
"corejs": 3
}]
]
- ✅ 使用した機能に応じて自動的にポリフィルを挿入
- ✅ JSファイルサイズと保守性の最適化が可能
6. CSSとの連携:@supports で挙動制御
@supports (backdrop-filter: blur(10px)) {
.frosted {
backdrop-filter: blur(10px);
}
}
@supports not (backdrop-filter: blur(10px)) {
.frosted {
background: rgba(255, 255, 255, 0.7);
}
}
- ✅ CSSもモダンとレガシーの二層構造を想定
- ✅ JavaScript側から
classList.toggle()
で上書き補正も可能
設計判断フロー
① このAPIは本当に全ブラウザで使えるか? → MDN / caniuse で確認
② フォールバック手段 or ポリフィルが存在するか?
③ Feature detection(存在確認)で安全に使っているか?
④ ビルド時にBabelやcore-jsで自動挿入できるか?
⑤ CSS含めて、非対応時の視覚的破綻が起きないか?
よくあるミスと対策
❌ UAでSafariを判定し、ピンポイントバグを修正
→ ✅ 機能ベース判定で壊れにくいロジックに
❌ モダンAPIだけで構成し、古いWebViewで真っ白になる
→ ✅ 最低限の動作にフォールバックする構造を設計
❌ Promiseやasync/awaitを使ってるのにポリフィルを入れてない
→ ✅ Babel + core-js で自動化し、破綻を防止
結語
クロスブラウザ対応とは「対応表を見て個別処理すること」ではない。
それは**“実行環境の差異を機能レベルで吸収し、どのブラウザでもユーザー体験を保証するための設計構造”**である。
- 標準APIの可否を明示的に確認し
- 存在しない環境では代替手段で機能を担保し
- ポリフィル + フォールバックを設計に組み込み
- UI・JS・CSSすべてのレイヤーで環境差を吸収する
JavaScriptにおけるクロスブラウザ戦略とは、
“仕様と現実のギャップを設計的に埋めるための技術と構造の防衛線”である。