技術深掘り・ワークフロー
技術深掘り:最初からブラウザ横断にする、Baselineのフォールバックの仕組み
新しい機能を使うコードを書いても、未対応のブラウザで壊れる。逆に古い書き方に逃げると標準機能の利点が消える。その間を、Baselineの対応データと4つのフォールバックの型で埋める仕組みの解説です。
ガイドなしのエージェントが落とすところ
書き方は2つの極端に寄ります。学習データの古い書き方に寄って、標準機能で済むものを複雑なJavaScriptや外部ライブラリで作る。または、新しい機能を頼まれると対応ブラウザ向けだけを書き、機能検出もフォールバックも省いて、未対応のブラウザでページを壊します。
判断の土台:Baselineの3段階
| 状態 | 意味 | 既定の扱い |
|---|---|---|
| Widely available(広く利用可能) | 主要ブラウザ全部で30か月以上動いている | そのまま使う。検出もフォールバックも付けない |
| Newly available(新たに利用可能) | 主要ブラウザ全部で動くようになった(最後のブラウザが対応した日が起点) | 検証済みのフォールバックと組で使う |
| Limited availability(限定) | 主要ブラウザ全部ではまだ動かない | 検証済みのフォールバックと組で使う |
対象の主要ブラウザは、デスクトップとモバイルのChrome、Edge、Firefox、Safariです。各ガイドには、web-features のデータから、状態、対応開始日、ブラウザの版が埋め込まれています。例えば <dialog closedby> は「Limited availability。Chrome 134(2025年3月)、Edge 134、Firefox 141(2025年7月)で対応。Safariは未対応」という形でエージェントに渡ります。
フォールバックは4つの型
型1:フォールバックのコードなし(段階的な強化)
装飾や付加的な機能は、未対応のブラウザが無視してもページが壊れません。そのまま入れます。例は見出しの行のバランスを取る text-wrap: balance と、先読みのSpeculation Rulesです。
そのまま(text-wrap指定なし):長い見出しは最後の行に短い言葉だけが残ることがあります
balance指定:長い見出しは行の長さがそろうように折り返されます
.balanced { text-wrap: balance; }
型2:CSSの機能検出(@supports)
見た目や配置に関わる機能は、一部だけ適用されると壊れて見えます。アンカー付きコンテナクエリでツールチップの矢印を反転させる例では、矢印のスタイルを @supports (container-type: anchored) の中に入れ、反転の規則も使えるブラウザだけが矢印を出します。
@supports (container-type: anchored) {
.tooltip-content::before {
content: "▼";
position: absolute;
inset-block-end: 0;
}
}
@container anchored(fallback: flip-block) {
.tooltip-content::before {
content: "▲";
inset-block-start: 0;
inset-block-end: auto;
}
}
型3:軽い自前のJavaScript
対話的なHTML機能が未対応の場合、外部ライブラリではなく、機能確認の内側に置いた小さな依存なしのスクリプトで肩代わりします。下の作例が実際にその形です。closedby="any"(背景クリックで閉じる)が使えないブラウザでは、背景のクリックを判定する処理が肩代わりします。
const dialog = document.querySelector('dialog');
if (!('closedBy' in HTMLDialogElement.prototype)) {
dialog.addEventListener('click', (event) => {
if (event.target !== dialog) return;
const rect = dialog.getBoundingClientRect();
const clickedInDialog =
rect.top <= event.clientY &&
event.clientY <= rect.top + rect.height &&
rect.left <= event.clientX &&
event.clientX <= rect.left + rect.width;
if (!clickedInDialog) dialog.close();
});
}
型4:条件付きで読み込むポリフィル
CSSアンカー配置やTemporal APIのような大きな機能は、手書きの肩代わりが現実的ではありません。一方、全員にポリフィルを配ると対応済みのブラウザに無駄なダウンロードが増えます。そこで、対応を確認してから動的に読み込みます。
if (!CSS.supports('anchor-name: --a')) {
await import('@oddbird/css-anchor-positioning');
}
プロジェクトの目標は上書きできる
既定は「Widely availableはそのまま、それ以外はフォールバック付き」です。プロジェクトに別の要件(特定のBaseline年、Electron向け、ポリフィル禁止など)がある場合は、AGENTS.md や CLAUDE.md に方針を書きます。
## Browser support policy
- Target Baseline 2024 or earlier. Omit fallbacks and @supports blocks for features that reached Baseline in or before 2024.
- Allow Baseline Newly available features when paired with a custom fallback of 20 lines or fewer.
- Don't add polyfill dependencies. Prefer CSS @supports rules or built-in HTML fallbacks instead.
確認は、両方の通り道を通す
コードを書くのが半分で、現代的な通り道とフォールバックの通り道の両方を実際のブラウザで確かめるのが残り半分です。1つのブラウザだけでは片方の分岐しか通りません。<dialog closedby="any"> はChromeとFirefoxでは標準動作、SafariではJavaScriptの肩代わりが動きます。記事は、Chrome DevTools for agents、Firefox DevTools MCP、Safari MCP serverを同時につなぎ、1つの流れで3ブラウザを確認する形を紹介しています。
作例:テーマの切り替え
color-scheme と light-dark() の組み合わせです。下の箱は、切り替えると中の面の色も light-dark() で追随します。
<meta name="color-scheme" content="light dark">
.swatch { background: light-dark(#e8f0fe, #3c4043); }
原文を読む:Cross-browser by default: How Baseline fallbacks work in Modern Web Guidance
短縮URL(投稿の記載):https://goo.gle/4kVCkwG / 解決先:https://developer.chrome.com/blog/cross-browser-by-default