ブログ一覧

Modern Web Guidance を入れるなら CLAUDE.md に対応ブラウザを 1行書く

Google Chrome のチームが Microsoft Edge・Mozilla Firefox・MDN のチームと出している Modern Web Guidance(コーディングエージェント向けのスキル)の 1.0 が出ました。250 ほどのブラウザの機能について、書き方のガイドと対応状況をエージェントが必要な分だけ引けるようにするスキルです。Claude Code に Astro のサイトの UI を書かせているので、入れると書かれるコードがどう変わり、Safari や Firefox で動かない書き方が混ざらないかを確かめてみました。

よく頼む UI を 3つ、2回ずつ作らせると、Claude Code はどのガイドのどの規則に沿ったかを応答に書き、フォームにはガイドに沿ったアクセシビリティの処理も付けました。ただ CLAUDE.md に方針を書かないと、ガイドの既定どおり Safari が未対応の新しい機能にもフォールバックを付けて使い、6個中 3個は外部の CDN からポリフィル(未対応のブラウザで新しい機能の代わりをするスクリプト)を読み込みました。困るのはこの CDN からの読み込みで、フォールバックが無く最新の Safari で欠けた物は、スキルなしの 1個に対してスキルありは 0個と、スキルありの方が少なかったです。CLAUDE.md に対応ブラウザを 1行書くと、Claude Code はその方針に合わせてガイドを選び直し、方針のために使わなかったガイドとその理由も応答に書きました。

方針が無いとガイドの例どおり CDN からポリフィルを読み込むこともある

Modern Web Guidance を入れた Claude Code が作った削除の確認モーダルを Chromium で開いた画面

試したのは、よく頼む次の UI を 3つ、1つの index.html で作らせることです。

  • 削除の確認モーダル。背景が暗くなってフェードし、背景のクリックか Esc で閉じる
  • 画面の端で見切れないツールチップ。ボタンを左上・右上・中央・下端に置く
  • 入力し終えてからエラーを出すお問い合わせフォーム。内容の欄は入力に合わせて伸びる

スキルなしと、スキルを .claude/skills/ に置いた場合とで、同じ依頼文と同じツールの許可の設定で 2回ずつ作らせました。Claude Code は 2.1.322、モデルは Sonnet 5.5、modern-web-guidance は 1.0.0 です。

スキルを置くと Claude Code は毎回書く前にガイドを探して読み、応答の最後に、どのガイドに沿ったかを書く節を付けました。スキルの SKILL.md がそう書くよう指示しています。

Chromium では、後で方針を足した分も含めて 24個ともちゃんと動き、差は動きではなく使った機能に出ました。Firefox と Safari の実機では動かしておらず、そちらは使った機能が Baseline(主要なブラウザでの対応状況の区分)でどうなっているかと、フォールバックがあるかをコードから調べています。Baseline では、Chrome・Edge・Firefox・Safari の全部の最新版で使えるようになった機能が Newly available、そこから 30か月たった機能が Widely available です。

スキルなしでも、モーダルは 2回とも <dialog> と showModal() で、<div> で自作したモーダルは 0個でした。内容の欄の伸び縮みも 2回とも field-sizing: content で、未対応のブラウザには JS で伸ばすフォールバックを付け、ツールチップは 2回とも JS で位置を計算しました。1回だけ、モーダルのフェードアウトに Chrome と Edge だけの overlay を使っていて、フォールバックは無く、Firefox と Safari ではフェードアウトが付かずに閉じるだけになります。

スキルありのモーダルは 2回とも、JS なしでボタンからモーダルを開く commandfor と、背景のクリックで閉じる closedby="any" を使い、閉じるアニメーションには overlay を使いました。commandfor が主要な 4ブラウザの最新版で使えるようになったのは 2025-12 で、closedby は Chrome・Edge・Firefox だけで Safari は未対応です。そのうえで、closedBy が無ければ座標で判定する背景クリックの処理と、commandForElement が無ければ esm.run からポリフィルを読み込む処理を書き足しています。

<button type="button" class="danger" command="show-modal" commandfor="confirm">削除</button>
<dialog id="confirm" closedby="any" aria-labelledby="confirm-title" aria-describedby="confirm-desc">
// Invoker Commands 未対応ブラウザ向けポリフィル
if (!('commandForElement' in HTMLButtonElement.prototype)) {
  await import('https://esm.run/invokers-polyfill').catch(() => {});
}

スキルありのツールチップは 2回とも、ホバーとフォーカスで出す属性の interestfor(Chrome・Edge 149 からだけ)と、Safari が未対応の popover="hint"、CSS アンカーポジショニングを使いました。1回は、未対応のブラウザ向けに unpkg から popover と interestfor のポリフィルを読み込む処理を書いています。

最新の Safari で動かない機能(closedby・interestfor・popover="hint"・overlay のどれか)を使ったのはスキルなしで 6個中 1個、スキルありで 6個中 4個でした。ただ、フォールバックが無く最新の Safari で欠ける物があったのはスキルなしの overlay の 1個だけで、スキルありは 0個です。スキルありの 4個はどれもフォールバックを付けていて、Widely available でない機能にはフォールバックを書くという、方針が無いときのガイドの既定どおりでした。

困るのは、外部の CDN からポリフィルを読み込んだ 3個です(スキルなしは 0個)。CDN の URL はガイドから来ていて、ツールチップのガイド interest-triggered-tooltips の例は await import("https://unpkg.com/interestfor@latest") と CDN から読みます。モーダルのガイドの例は import('invokers-polyfill'); // npm install invokers-polyfill と npm で入れる形で、1つの index.html で作らせたので Claude Code が esm.run の URL にしました。

外部の CDN から読み込むスクリプトは、その CDN が書き換えられたときにそのままサイトに入ります。2024 年には polyfill.io のドメインの持ち主が替わって悪いスクリプトを配り、Cloudflare は polyfill.io を外すよう呼びかけました。

README には、学習データの古い書き方のせいで膨らみがちな JavaScript を、ブラウザのネイティブの機能に置き換えさせるとあり、作者も Show HN で「以前は 50行の JS(か依存)が要った物をブラウザが持っている」と書いています。この 3つの UI では、JavaScript の行数(空行とコメントを除き、2回の平均)はモーダルが 22行から 55.5行、ツールチップが 45行から 46.5行、フォームが 41行から 77.5行と、モーダルとフォームで増え、ツールチップはほぼ同じでした。

モーダルで増えたのは新しい機能に付けたフォールバックとポリフィルの読み込みで、フォームで増えたのは、ガイド required-field-feedback と accessible-error-announcement に沿って :user-invalid に合わせて aria-invalid と aria-describedby を付け外す、アクセシビリティのための JS です。

CLAUDE.md に対応ブラウザを 1行書くと方針に合わせてガイドを選び直す

スキルの SKILL.md は、対応ブラウザの方針を AGENTS.md や CLAUDE.md に書くよう勧めていて、方針があればガイドの対応状況を見てフォールバックを省いてよいとしています。そこでスキルを置いたまま、Claude Code を動かすディレクトリの CLAUDE.md に次のどちらかを書き、同じ 3つの UI を 2回ずつ作らせました。

**対応ブラウザ:** Baseline Widely available の機能だけを使う。それ以外の新しい機能とポリフィルは使わない。外部の CDN からスクリプトを読み込まない。
**対応ブラウザ:** 最新版の Chrome・Edge・Safari・Firefox だけに対応する。古いブラウザ向けのフォールバックやポリフィルは書かない。
CLAUDE.md の対応ブラウザの 1行で、最新の Safari で動かない機能と外部の CDN からのポリフィルを使った数が変わる

「Widely available の機能だけ」の 6個は、closedby・commandfor・@starting-style・overlay・popover・interestfor・CSS アンカーポジショニング・field-sizing をどれも使わず、外部の CDN からの読み込みも 0個でした。モーダルは <dialog> と showModal() に座標の判定で背景のクリックを拾う形で、フェードは 1回が @keyframes、もう 1回が transition と transitionend です。フォームの :user-invalid は 2026-05 に Widely available になっていて、使っています。

使わなかったガイドとその理由は、応答の Modern Web Guidance の節に書かれていました。モーダルの 1回目の応答には「closedby は Widely available ではないため使わず、ガイドのクリック座標判定を採用しました」「ガイドの @starting-style / allow-discrete / overlay 方式は Widely available ではないため使わず、@keyframes と閉じる直前の .closing クラスで代替しました」とあります。

「最新の 4ブラウザだけ」の 6個は、interestfor と popover="hint" をどちらも使わず、外部の CDN からの読み込みも 0個でした。ツールチップの 1回目の応答には「ガイドは interestfor と popover="hint" を勧めていますが、ガイドによると Firefox と Safari は未対応です。CLAUDE.md でポリフィルを禁止されているため、popover="manual" に最小限の JS(ホバー、フォーカス、Escape の処理)を組み合わせました」とあります。

ただ「最新の 4ブラウザだけ」でも、モーダルは 2回とも Safari が未対応の closedby と overlay を使い、Safari 向けの座標の判定と、Firefox・Safari ではフェードアウトの代わりに消す処理を書きました。図で「最新の 4ブラウザだけ」が 2/6 なのはこのモーダルの 2個で、どちらもフォールバックが付いています。

応答には「最新の Safari は closedby 未対応なので、座標判定による背景クリックの補完だけを残しました」とあり、ガイド light-dismiss-a-dialog も、closedby が未対応のブラウザには背景のクリックで閉じるフォールバックを必ず書くよう求めています。

ツールチップは方針で JS の量が分かれました。Widely available だけでは CSS アンカーポジショニングを使えずに JS で位置を計算して 59.5行になり、最新の 4ブラウザだけでは位置合わせを CSS アンカーポジショニング(Safari 26・Firefox 147 から)と @position-try にして 32行(1回目は 18行)でした。

既存のコードには、1.0 で入った legacy-scan で古い書き方を探せます。ガイド 33本から作った 35個の固定のルールでコードをチェックするコマンドで、見るのはガイド全体の約 20% だと出力にも書かれます。ネットワークも API キーも要らず、1サイト約 1秒で終わります。私が運用している Astro のサイト 13個にかけると 6サイトで計 9件見つかり、うち 5件は @media (prefers-color-scheme: dark) で色を上書きしているのに color-scheme が無いという指摘でした。legacy-scan も <dialog> を背景のクリックで閉じる自作の処理には Safari 未対応の closedby="any" を勧めるので、直させるなら CLAUDE.md の方針と照らし合わせることになります。

試していないのは、WCAG 準拠のチェック、React や Astro の部品の中で書かせた場合、Claude Code 以外のエージェント、legacy-scan の結果をエージェントに直させる流れです。WCAG については、Adrian Roselli がこのスキルで作らせた部品が WCAG を満たさなかった例と、Baseline がアクセシビリティの対応を追っていないことを挙げています。

相手にするブラウザに合わせて CLAUDE.md の 1行を選ぶ

この 3つの UI でスキルを入れて得られたのは、使った理由と使わなかった理由が応答に毎回並ぶことと、フォームにガイドに沿ったアクセシビリティの処理が付いたこと、「最新の 4ブラウザだけ」では CSS アンカーポジショニングでツールチップの JS が減ったことです。アクセシビリティの処理が付いたのはフォームで、理由を毎回読めるのはレビューのときで、ツールチップの JS が減ったのは最新版のブラウザだけを相手にする場合でした。スキルなしでも <dialog> や field-sizing は使っていたので、古い書き方が新しくなるという差はこの 3つでは小さく、払った手間は 1回あたりの時間が約 1.5〜2倍、読み込んだトークンが約 3〜5倍でした。

相手にするブラウザごとに書く 1行と、この 3つの UI で起きたことは次のとおりです。

  • Safari 26 より前の iPhone や Mac も相手にするサイト: 「Widely available の機能だけ」の 1行。新しい機能は使わず CDN からの読み込みも 0個で、ツールチップの位置は JS で計算する(59.5行)
  • 最新版のブラウザだけでよいサイト(社内の管理画面など): 「最新の 4ブラウザだけ」の 1行。ただしモーダルは Safari 未対応の closedby を使い、ガイドが必須としている Safari 向けのフォールバックが残った。Chrome と Edge だけの interestfor は外れ、CSS アンカーポジショニングでツールチップの JS は 32行(1回は 18行)に減った

この 3つの UI では、何も書かないと CDN から読み込んだ物が 6個中 3個あったので、避けたければ「外部の CDN からスクリプトを読み込まない」も 1行に入れる必要があります。

この記事をシェア