ブラウザには、ここ数年で入った HTML・CSS の機能があります。popover、name 付きの <details>、:user-invalid、@container、light-dark() などで、前は JavaScript で自分で書いていた開け閉め、入力の確かめ、明暗の切り替えなどを、ブラウザに任せられます。Google Chrome が公開した modern-web-guidance(文書)は、コーディングエージェントにこうした機能を使わせるための手引き(スキル)です。

私たちは、これを Claude Code(Opus 5.5)に入れた回と入れない回で、確認の窓やメニューのような小さな画面の課題を 6 つ作らせ、その課題に合うブラウザの新しい機能(メニューなら popover)を使うかを数える技術検証をしました。入れると書き方がどう変わり、その分何が増えるのかを書きます。

README によると、実在に近いアプリへの頼みを指針なし・ありでエージェントに解かせ、Playwright で動きやアクセシビリティまで判定したところ、Claude Code(opus-5-5)は通った割合が 57% から 88% に上がったそうです。私たちの課題はそれよりずっと小さく、判定もコードの文字を見るだけなので、物差しが違います。

結論

  • スキルありでは 12 回中 12 回、スキルなしでは 5 回、その課題に合うブラウザの新しい機能を使いました(コードの文字で判定)。差が出たのはメニュー(popover)・FAQ(name 付きの details)・入力の確かめ(:user-invalid)・明暗(light-dark())です。dialog とコンテナクエリは、スキルなしでも使っていました。
  • 同じ dialog でも、スキルなしは焦点を閉じ込める処理を自分で書き、スキルありは指針に沿ってそれを書かずに closedby="any" を使いました。ファイルも短くなりました。
  • その代わり、スキルありは 1 回あたりの時間が 2.3 倍、推定費用が 2.2 倍、出力トークンが 1.9 倍でした。
  • --permission-mode dontAsk で許可を絞ると、モデルが npx の前に環境変数や cd を付けて呼び、許可の形に合わずに断られる回がありました。

試した環境

  • Mac、Claude Code 2.1.322(公式の配布物)、Node 24.15.0
  • モデルは --model opus(claude-opus-5-5)、--effort high
  • modern-web-guidance は、リポジトリのコミット 4dd96834 を取ってきて、スキルありの回だけ --plugin-dir で渡しました。スキルが呼ぶ CLI は npm の modern-web-guidance で、毎回 @latest で取られ、試した時点では 1.0.0 でした
  • 課題 6 つ × スキルなし・あり × 各 2 回 = 24 回。数える前に試しに回した 1 回は数に入れていません(理由は後で書きます)

起こし方は次のとおりで、許した道具はどちらの条件も同じです(--plugin-dir はスキルありの回だけ)。

export DISABLE_TELEMETRY=1                    # Google への送信を止める
export NPM_CONFIG_CACHE=<作業場>/npm-cache
claude -p "<頼み>" --model opus --effort high \
  --setting-sources project --permission-mode dontAsk \
  --output-format stream-json --verbose --no-session-persistence \
  --plugin-dir <取ってきたリポジトリ> \
  --allowedTools Read Write Edit Glob Grep Skill \
    "Bash(npx -y modern-web-guidance@latest *)" \
    "Bash(NPM_CONFIG_CACHE=* npx -y modern-web-guidance@latest *)" \
    "Bash(npx --offline modern-web-guidance@latest *)" \
    "Bash(ls *)"

最初は --safe-mode で起こすことも試しましたが、--plugin-dir で渡したスキルまで読まれませんでした(Haiku にスキルの一覧を出させて確かめました)。そこで --safe-mode は使わず、--setting-sources project でユーザの設定と CLAUDE.md を読まない形にしました。手元の CLAUDE.md が入らないことも、同じやり方で確かめています。

推定費用は、Claude Code が結果に出す見積もり(total_cost_usd、定価での計算)で、請求額ではありません。今回はサブスクリプションの枠の中で回しました。

スキルがエージェントにさせること

リポジトリには、SKILL.md と、指針を書いた guides/ の Markdown(約 200 の使い方)が入っていて、Claude Code や Codex などのプラグインとしての置き方がそろっています。SKILL.md は、HTML・CSS・画面の JS の作業の初めに npx -y modern-web-guidance@latest search "<2〜5 語>" で指針を探し、retrieve "<id>" で取り出し、それに沿って書き、最後の報告に「### Modern Web Guidance」の節を設けて使った指針を書くよう指示しています。CLI の本体はリポジトリには無く、npm から取られます。

課題と数え方

課題は英語で、どれも同じ書き出しに動きだけを足しました。スキルの説明と指針が英語なので、課題も英語に揃えています。API や要素の名前は言っていません。たとえばメニューの課題はこうです。

Build index.html (a single file, plain HTML, CSS and JavaScript, no libraries or frameworks): a ‘More’ button that toggles a small menu with three links (Edit, Duplicate, Archive) shown right below the button. Clicking anywhere else or pressing Escape closes the menu.

訳: index.html を作る(1 つのファイルで、素の HTML・CSS・JavaScript。ライブラリやフレームワークは使わない): 「More」ボタンを押すと、3 つのリンク(Edit・Duplicate・Archive)の小さなメニューがボタンのすぐ下に開き、もう一度押すと閉じる。ほかの所をクリックするか Escape を押しても閉じる。

課題頼んだ動き数えた物
確認の窓Cancel・Esc・外で閉じる。焦点を中に<dialog> と showModal
メニュー真下に 3 リンク。外・Esc で閉じるpopover
FAQ1 つ開くと前の物が閉じるname 付き <details>
入力の確かめ触った後だけ誤り。一致まで送らない:user-invalid
カード自分の幅で横並び・縦積み@container
明暗システムに従い、ボタンでも切替light-dark()

判定は、できた HTML・CSS・JS の文字に、表の「数えた物」があるかだけを見ました(popover なら、popover 属性・popovertarget・showPopover など)。ついでに、dialog の closedby、メニューのアンカー位置決め(anchor-name・position-anchor)なども見ました。

スキルありは 12 回中 12 回、スキルなしは 5 回

課題ごとに、その課題に合うブラウザの新しい機能(メニューなら popover)を使った回を数えた結果です(各 2 回中)。

課題スキルなしスキルあり
確認の窓22
メニュー02
FAQ02
入力の確かめ02
カード22
明暗12
計5/1212/12

スキルなしでも、確認の窓では 2 回とも <dialog> と showModal を、カードでは 2 回とも @container を使っていました。明暗は 2 回のうち 1 回が light-dark() を使っています。つまり、スキルなしでもブラウザの新しい機能をまったく知らないわけではありません。差が出たのは残りの課題でした。

  • メニュー: スキルなしの 2 回は、ボタンの aria-expanded の書き換え、クリックでの開閉、外側のクリックと Escape で閉じる処理を自分で書いて、同じ動きを作っていました。スキルありの 2 回は popover を使い、そのうち 1 回は、メニューを More の真下に置くのにアンカー位置決めも使いました。
  • FAQ: スキルなしの 2 回は <details> を使わず、質問をボタンにして開閉を書いていました。スキルありの 2 回は、4 つの <details> に同じ name を付け、1 つだけ開く動きをブラウザに任せました。
  • 入力の確かめ: スキルなしの 2 回は、欄を触ったかどうかを JS で覚えて誤りを出す形でした。スキルありの 2 回は :user-invalid を使い、setCustomValidity も使っていました。

メニューの違いを、形だけ並べます。出力そのものではなく、違いが分かるように要所を書いた物です。

// スキルなしの回の形: 開閉も閉じ方も自分で持つ
more.addEventListener("click", toggleMenu);           // aria-expanded を書き換える
document.addEventListener("click", closeIfOutside);   // 外のクリックで閉じる
document.addEventListener("keydown", closeOnEscape);  // 閉じたら More に焦点を戻す
<!-- スキルありの回の形: 開閉と閉じ方は popover に任せる -->
<button popovertarget="more-menu">More</button>
<div id="more-menu" popover>…Edit・Duplicate・Archive…</div>

スキルありの回は、使った新しい機能に対応していないブラウザ向けに、代わりの処理も足していました。FAQ の name の代わりをする小さな script や、light-dark() の前に置いた普通の色などです。最後の報告には SKILL.md の指示どおり「### Modern Web Guidance」の節があり、使った指針の ID(dialog・accordion など)と、指針の文の短い引用が並んでいました。

2 つの条件で起きたことを流れにすると、次の図になります。点線は、npx が断られた 2 回の道筋です(後で書きます)。

スキルなし・ありで起きたこと

同じ dialog でも、焦点の扱いが違った

確認の窓は、どちらの条件でも 2 回とも <dialog> と showModal を使ったので、数の上では差がありません。ところが中身を読むと、作り方が違いました。

確認の窓スキルなし(2 回)スキルあり(2 回)
焦点の閉じ込め自分で書いた書かない
Esc の処理1 回は自分でも書いた書かない
外のクリックscript で判定closedby="any"
ファイルの行数193〜201 行133〜152 行

スキルなしの 2 回は、Tab のキーを拾って焦点を窓の中に閉じ込める処理を自分で書いていました。スキルありの 2 回は、指針の dialog の項にある、焦点の閉じ込めや Esc の処理は足さない(ブラウザがやる)という指示に沿ってそれを書かず、外側のクリックで閉じるのは closedby="any"、ボタンは <form method="dialog"> にしていました。closedby に対応していないブラウザ向けには、代わりの処理として、押した所と離した所がどちらも窓の外かを見る短い script を足しています。

数えるだけなら同じ「dialog を使った」でも、その上に自分で何を重ねたかは別の話です。数で差が出なかった課題も、中身を読んで比べると違いが見えました。

時間と推定費用は約 2.2〜2.3 倍

書き方が変わった代わりに、1 回あたりの量は増えました。

12 回の平均スキルなしスキルあり倍率
出力トークン3,9517,4041.9 倍
時間42.1 秒96.0 秒2.3 倍
推定費用$0.207$0.4562.2 倍

24 回の推定費用の合計は $7.95(スキルなし $2.48、スキルあり $5.47)で、試しに回した 1 回の $0.24 は別です。

どの課題でもスキルありのほうが時間がかかった。全体の平均はなし 42.1 秒、あり 96.0 秒。カードはありで 163.9 秒、メニューはなし 26.5 秒からあり 102.9 秒。

課題ごとの時間(2 回の平均)で見ると、増え方は一様ではありません。確認の窓は 1.3 倍、FAQ は 1.7 倍で済んだのに対し、メニューは 3.9 倍でした。入力の確かめ・カード・明暗は、スキルありで 96〜168 秒かかっています。

札が一枚多い荷物を門番が止め、脇で小さなロボットが書棚の案内書を読んでいる絵

許可を絞ると、npx の呼び方の揺れで断られる

スキルは 12 回とも呼ばれましたが、npx の retrieve で指針を取り出すところまで行ったのは 10 回でした。残りの 2 回は、npx の呼び出しが許可の一覧に合わずに断られていました。

数える前に、確認の窓(スキルあり)を 1 回試しました。このときの npx の許可は Bash(npx -y modern-web-guidance@latest *) だけでした。モデルは次のように環境変数を頭に付け、2 本のコマンドを ; でつないで呼んだので、許可の形に合わず、dontAsk で断られました。

NPM_CONFIG_CACHE=/tmp/npm-cache npx -y modern-web-guidance@latest … ; …

SKILL.md 自身が、~/.npm に書けないときは NPM_CONFIG_CACHE=/tmp/npm-cache を付けるよう書いています。スキルの指示に従うほど、この前置きが付くことになります。そこで Bash(NPM_CONFIG_CACHE=* npx -y modern-web-guidance@latest *) を許可に足し、環境変数を頭に付けた形が通ることを Haiku で確かめてから、試しの回は数に入れずに 24 回を回しました。数えた回でも 6 回(確認の窓 1・FAQ 2・メニュー 1・明暗 2)はこの前置きを付けて呼び、足した形で通っています。なお、断られた試しの回も、SKILL.md を読んだだけで closedby="any" を使っていました(1 回の観察です)。

それでも、数えた 24 回のうち 2 回(メニューと入力の確かめの、それぞれ 1 回目)は、モデルが今度は cd を頭に付けて呼び、断られました。

cd /tmp && NPM_CONFIG_CACHE=/tmp/npm-cache npx -y modern-web-guidance@latest search "form validation error messages" …

この 2 回はどちらも、Glob と Read でプラグインのフォルダの guides/ を探し、指針の Markdown(入力の確かめでは guides/forms/validate-input-after-interaction.md など)を直接読んで、同じようにブラウザの新しい機能を使いました。Read と Glob は許していたので、この道が残っていました。cd を付けた形は許可に足していないので、どう書けば通るかは確かめていません。

許可の一覧でスキルの CLI を通すつもりなら、モデルが付ける前置き(環境変数・cd)まで見込んでおく必要があります。許可に書いた形どおりに呼ばれるとは限らず、断られても作業は進むので、ほかの道に流れたことに気づきにくい所です。

動きは確かめていない

判定はコードの文字だけで、作った画面が頼んだとおりに動くかは確かめていません。README の評価は Playwright で計算されたスタイルや動き、アクセシビリティまで見ているので、物差しが違います。12 回中 12 回は、その機能がコードに書かれていた回数で、正しく動いた回数ではありません。

また、許可を絞っていたので、モデル自身もブラウザでは確かめられていません。どちらの条件でも、いくつかの回でヘッドレスの Chrome でスクリーンショットを撮る・ブラウザを探す、といったコマンドを打っては断られ、最後の報告にブラウザで試していないと書いていました。

入れるときに気をつけること

  • 画面の作業が多いなら、入れる価値はあります。 今回の課題では、ブラウザの機能で済む所を JS で組む回が減り、確認の窓のファイルも短くなりました。
  • 時間と推定費用は 2 倍ほどになります。 今回の平均では時間が 2.3 倍、推定費用が 2.2 倍でした。
  • dontAsk などで許可を絞るなら、 npx の呼び方の揺れ(環境変数や cd の前置き)まで許可に書くか、プラグインのフォルダの guides/ を Read で読めるようにしておきます。
  • 送信を止めるなら DISABLE_TELEMETRY=1 を付けます。 リポジトリの説明によると、CLI は匿名の利用情報(入れた数・呼んだエージェントの名前・取り出した指針の ID・エージェントが作った検索語)を Google に送り、利用者の頼みの文は送らないそうです。今回は 24 回ともこれを付けて回しました。
  • できた画面の動きは自分で確かめます。 ブラウザの新しい機能を使っていても、動くかどうかは別に見る必要があります。

確かめていないこと

  • 作った画面が頼んだとおりに動くか(Escape で閉じる・1 つだけ開く・送らせない、など)。判定はコードの文字だけです。
  • 課題は小さな 1 ファイルの新規作成だけです。Chrome の評価は、実在に近いアプリへの手入れです。
  • 課題を日本語で頼んだら、結果が変わるか。課題は英語でだけ頼みました。
  • 回数は各 2 回だけです。モデルは Opus 5.5、effort は high だけで、ほかのエージェント(Codex など)は試していません。
  • 送信を止めた形(DISABLE_TELEMETRY=1)以外では動かしていません。npm の CLI は毎回 @latest で取っていて、版を固定していません(試した時点では 1.0.0)。
  • スキルを入れたとき、Web と関係ない作業で呼ばれてしまうか。SKILL.md には、呼ばない場面も書かれています。

おわりに

modern-web-guidance を入れると、小さな画面の課題では Claude Code(Opus 5.5)が popover や name 付きの details を自分から使うようになりました。一方で、時間と費用は倍ほどかかり、許可の書き方に気を配る必要もあり、動くかどうかは自分で見る必要が残ります。そこまで含めて、入れるかを決めるのがよさそうです。

※ Claude Code と modern-web-guidance の振る舞い、送信の扱いは執筆時点の情報で、いまは変わっている可能性があります。