AIで作るデジタル商品の販売ページで、薄い注記を止める。文字色を3組だけ測った

AIで作るデジタル商品の販売ページで、薄い注記を止める。文字色を3組だけ測った

淡いグレーの注記は、余白が多い販売ページによくなじみます。けれど、白い背景では見た目より早く読めなくなります。AIに販売ページの下書きを頼むと、商品名や見出しには目が行きますが、「更新方法は購入後の案内で確認」のような短い補足は後回しになりがちです。

今回は、架空のデジタル商品の販売ページを想定しました。実在する購入者、販売実績、商品ページは使っていません。本文、リンク、注記の3組だけを合成の色で測り、基準を下回る注記を止める見本です。

きれいな注記ほど見落とす

AIへ「落ち着いた配色」と頼むと、薄いグレーが候補に混ざります。背景が白なら、画面上では控えめに見えます。しかし控えめであることと、読めることは別です。

W3CのWCAG 2.2は、通常サイズの文字と背景のコントラスト比を少なくとも4.5:1としています。大きな文字には別の基準がありますが、商品説明、利用条件、更新の案内を小さな注記として置くなら、通常文字として先に測る方が安全です。

今回、本文用の#5F6368、リンク用の#0066CC、注記用の#9AA0A6を並べました。注記はほかの2色より明るいだけに、数値を見るまで弱さは分かりにくいです。色名や印象で判断せず、販売前に止める条件を1つ置きます。

通す条件を4.50:1に固定する

この見本で調べるのは、文字色と背景色の組だけです。文字の大きさ、フォントの太さ、ボタンの枠、画像の上の文字は扱いません。それらは別の確認に分けます。

色の相対輝度からコントラスト比を計算し、4.50:1未満なら終了コード1で止めます。#RRGGBBの6桁以外も失敗として扱います。AIが提案した色を使うかどうかは、この検査の後で人が決めます。

次のコードを$TMPDIR/contrast-lab/check_contrast.pyとして保存しました。$TMPDIRは、その場で消してよい一時ディレクトリです。販売ページの原稿や顧客データは入力しません。

check_contrast.py
import sys


def channel(value: str) -> float:
    n = int(value, 16) / 255
    return n / 12.92 if n <= 0.04045 else ((n + 0.055) / 1.055) ** 2.4


def luminance(color: str) -> float:
    value = color.removeprefix("#")
    if len(value) != 6 or any(ch not in "0123456789abcdefABCDEF" for ch in value):
        raise ValueError(f"invalid color: {color}")
    r, g, b = (channel(value[index:index + 2]) for index in (0, 2, 4))
    return 0.2126 * r + 0.7152 * g + 0.0722 * b


def ratio(foreground: str, background: str) -> float:
    light, dark = sorted((luminance(foreground), luminance(background)), reverse=True)
    return (light + 0.05) / (dark + 0.05)


def main() -> int:
    if len(sys.argv) != 4:
        print("usage: check_contrast.py ROLE FOREGROUND BACKGROUND")
        return 2
    role, foreground, background = sys.argv[1:]
    value = ratio(foreground, background)
    if value < 4.5:
        print(f"NG role={role} foreground={foreground} background={background} ratio={value:.2f}:1 required=4.50:1")
        return 1
    print(f"OK role={role} foreground={foreground} background={background} ratio={value:.2f}:1 required=4.50:1")
    return 0


raise SystemExit(main())

本文とリンクは通り、注記を止めた

同じ白背景に対して、本文とリンクを先に実行しました。その後、薄い注記を白と少し青みのある背景で調べます。注記は背景を変えても4.50:1に届きませんでした。

cd "$TMPDIR/contrast-lab"
python3 --version
python3 check_contrast.py 本文 '#5F6368' '#FFFFFF'; printf 'body_exit=%s\n' "$?"
python3 check_contrast.py リンク '#0066CC' '#FFFFFF'; printf 'link_exit=%s\n' "$?"
python3 check_contrast.py 注記 '#9AA0A6' '#FFFFFF'; printf 'muted_exit=%s\n' "$?"
python3 check_contrast.py 注記 '#9AA0A6' '#F5F7FA'; printf 'muted_tinted_exit=%s\n' "$?"
Python 3.13.5
OK role=本文 foreground=#5F6368 background=#FFFFFF ratio=6.05:1 required=4.50:1
body_exit=0
OK role=リンク foreground=#0066CC background=#FFFFFF ratio=5.57:1 required=4.50:1
link_exit=0
NG role=注記 foreground=#9AA0A6 background=#FFFFFF ratio=2.64:1 required=4.50:1
muted_exit=1
NG role=注記 foreground=#9AA0A6 background=#F5F7FA ratio=2.46:1 required=4.50:1
muted_tinted_exit=1

本文とリンクは合格しました。注記は白背景で2.64:1、薄い青みのある背景では2.46:1でした。背景を少し変えれば読める、という期待は外れました。明るい色をさらに明るい背景へ重ねると、比は上がりません。

この失敗を検査として残す利点は、好みの議論を小さくできることです。色が「柔らかい」かどうかではなく、注記として使う候補が4.50:1を満たすかだけを先に確認します。満たさなければ、濃い色へ替えるか、文字を注記扱いにしない位置へ移します。

AIへの依頼と、機械で見る範囲を分ける

AIには「白背景で、本文とリンクと補足を読み分けやすくしたい」と用途を渡せます。ただし、生成された16進色をそのまま公開条件にしません。提案は候補、検査の終了コードは止める条件です。

販売ページの色は、次の3段に分けます。

  • 商品名と見出し: ブランドの表現を含めて、人が画面で確認します。
  • 本文とリンク: 背景との組をこの検査へ通します。
  • 補足と利用条件: 小さい文字になりやすいので、本文と同じ4.50:1未満を許しません。

この区切りなら、AIが色を増やしても、先に確認すべき組が見えます。一方で、比が合格でも読みやすさを保証はしません。細すぎる書体、文字の上に重なる写真、リンクであることが色だけに依存する設計は、数値だけでは分かりません。

販売前に残る確認

今回の小さな検査は、WCAG適合を宣言するものではありません。通常文字の前景色と背景色を比較するだけです。大きな見出し、画像内の文字、ホバー時の色、キーボード操作時のフォーカス表示は別に確かめます。

デジタル商品の利用条件、対応環境、更新方法は、購入前の確認項目です。薄い文字で目立たせない前に、本文へ入れるべき情報かを見直します。AIの下書きでページを早く作るほど、最後に残す短い文を数値で止める役目が大きくなります。

出典

この記事をシェア