「見た目は問題ありません」を実際に計算したら、コントラスト比3.48だった|AIの成果物は目視で検証しない

AIに作らせたものを確認するとき、いちばんやりがちなのが画面を見て「問題なさそう」と判断することです。このサイトでも長らくそうしていました。

実際に計算してみたら、ボタンの文字が読みにくさの基準を下回っていました。 見た目は綺麗です。むしろ映えます。数字で見るまで気づけませんでした。

この記事は運営者が実際に計算した値と、検証そのものにかかった実コストの記録です。基準やツールの仕様は変わるため、数値は自分の環境で計算し直してください。

結論:判定できる形にしてから確認する

📌 先に結論 ① 見た目の確認は目視でなく計算。色は数式で合否が出る ② 直すときは色味を保ったまま暗くする。基準に合わせて別の色にしない ③ ブラウザを操作させる検証は桁違いに高い。実測で184回・約31万トークン・約42分で2件

やったこと:色の組み合わせを14ペア、実際に計算した

文字色と背景色の読みやすさは、コントラスト比という値で判定できます。W3Cのアクセシビリティ基準(WCAG)では、本文サイズの文字で 4.5:1 以上が目安とされています。

この値は目で判断するものではなく、相対輝度から計算で出るものです。そこでサイトで使っている色の組み合わせを全部拾い、Node.jsで一括計算させました。

結果、14ペア中2件が基準未達でした。

箇所組み合わせ実測判定
CTAボタン白文字 / #ec5a13(橙)3.48:1❌ 未達
ストアボタン白文字 / #ff0033(赤)3.96:1❌ 未達
本文本文色 / 背景14.1:1
リンクリンク色 / 背景7.3:1

未達の2件は、どちらもいちばん押してほしいボタンでした。 これは偶然ではないと思っています。目立たせようとして彩度の高い色を選ぶと、白文字とのコントラストは下がります。「目立つ」と「読める」は別の話でした。

⚠ 見た目で一番きれいな色が、一番読みにくいことがある 鮮やかな橙や赤は白文字と相性が良く見えます。実際の比は 3.48 と 3.96 で、どちらも 4.5 に届いていませんでした。

直し方:色を変えず、色味を保ったまま暗くする

ここで安易にやると、ブランドの色が変わります。実際にやったのは、色相をほぼ保ったまま明度だけ落とすという直し方でした。

箇所変更前変更後実測
CTAボタン背景#ec5a13 (3.48:1)#c8470c4.81:1
ストアボタン背景#ff0033 (3.96:1)#e6002d4.77:1

どちらも同系色のまま基準を超えました。「基準を満たす別の色」に置き換えたのではなく、「同じ色の、暗いほう」を選んだのが要点です。

そのうえで、もう1つやりました。

📌 明るいほうの色は捨てずに、装飾用として別トークンに残す 文字を載せない場所(線・アイコン・帯)では、明るい #ec5a13 のほうが映えます。文字を載せる色と、載せない色を別の名前で持つことで、両方を成立させました。

色を1つにまとめようとすると、どちらかを妥協することになります。用途で分ければ妥協が要りません。 なお、色コードが :root(変数定義)の外に散らばっていると、この分離自体ができません。散らばった生の色コードを回収した経緯はスキルの選び方と運用に書きました。

そのまま使える頼み方

このやり方は他のサイトでもそのまま使えます。

このサイトで使っている「文字色 / 背景色」の組み合わせを
CSSから全部拾い出してください。

各ペアについて、WCAGの相対輝度の式でコントラスト比を計算し、
「箇所 / 文字色 / 背景色 / 比 / 4.5:1の合否」の表にしてください。

・目視の印象は書かないでください。数値だけ出してください
・何ペア検査したかを必ず出力してください
・未達のものは、色相を保ったまま明度だけ下げた修正案と、
  修正後の比を計算して出してください

「何ペア検査したか」を出させるのを省かないでください。検査対象を1件も拾えていない状態でも、「基準未達は0件です」という出力は成立します。この形の嘘は実際に踏みました(検証スクリプトが対象を0件しか見ていなかった件はClaude Codeの実務での使い方にあります)。

検証そのものにかかるコストを知っておく

「じゃあ全部AIに確認させればいい」とはなりません。確認の方法によって、かかるコストが桁で違います。

上の色の計算は、CSSを読んで計算するだけなので安いです。問題はブラウザを操作させる検証でした。実測です。

条件結果
単独エージェントでブラウザ操作184回のツール呼び出し・約31万トークン・約42分で、処理できたのは2件
2エージェントに並列化相手側から HTTP 503(レート制限)が返り始めた
503が出た後30分以上のクールダウンが要る。すぐ再開すると再び503
タブグループ安定して使えたのは実質2タブまで。4エージェント並列は破綻
サブエージェント1体あたり約47,000〜61,000トークン(4体並列時の実測)

⚠ 並列化は速くならない。むしろ止まる 並列で増えるのは処理量ではなく、同じ相手に対する叩き込みの密度でした。レート制限に当たると、単独より遅くなります。

さらに見落としやすいのがこれです。利用量の上限はアカウント全体で合算されます。 別プロジェクトで走らせているセッションが、いま検証に使いたい枠を食います。「このプロジェクトではそんなに使っていない」は理由になりません。

「安い検証」と「高い検証」を分ける

コストの差がここまで大きいと、何を機械で確認し、何をブラウザで確認するかを先に決めておく価値があります。実際の切り分けです。

確認したいことやり方コスト感
色の読みやすさCSSを読んで計算する安い(ファイルを読むだけ)
リンク切れ・記事間の整合検査スクリプトを1本回す安い
CTAの約束と飛び先の中身の一致検査スクリプトを1本回す安い
計測イベントが実際に送信されているかブラウザで1回だけ捕まえる中(詳細はClaude Codeとは何か
外部サービス上での一括操作ブラウザ操作高い(上の実測のとおり)

上3つに共通するのは、合否が数値か真偽で返ることです。返ってくるものが「印象」ではなく判定なら、機械に任せられます。逆に、ブラウザを延々と操作させる作業は、やる前に「何件処理するのにどれくらいかかるか」を見積もるほうが安全でした。42分で2件という数字を知らずに200件の作業を投げると、途中で上限に当たって止まります。

検証を頼むときに毎回入れている3行

検証した件数を必ず出力してください
判定の根拠になった実際の値(数値・出力・ファイルの該当行)を貼ってください
判定できなかったものは「判定できず」と書いてください。推測で埋めないでください

3行目が効きます。これを書かないと、確認できなかった項目が「問題なし」に混ざります。 「問題なし」と「確認していない」が同じ見た目になるのが、いちばん厄介な失敗でした。

まとめ

  • 見た目の確認は目視でなく計算。実測で14ペア中2件が基準未達(3.48:1 と 3.96:1)
  • 未達だったのはどちらも一番押してほしいボタン。「目立つ」と「読める」は別
  • 直すときは色味を保ったまま暗くする(4.81:1 / 4.77:1)。明るい色は装飾用に別トークンで残す
  • 検証には値段がある。 ブラウザ操作は 184回・約31万トークン・約42分で2件。並列化は503を招いて逆効果
  • 頼むときは検査件数・実際の値・「判定できず」の明示の3点を必ず要求する

同じ「確認したつもり」は、スキルの安全確認でも起きました(スコアだけ見て中身を照合しない)→ AIスキルは他人のコードを自分のPCで動かすこと