デザインの様式を、動くデモ・効く理由・実装で踏んだ罠つきで解剖する図鑑。
様式名: オーガニック・シェイプ / トースト通知
「壊れた例」を押すと、この様式が成立しなくなる条件を実物で見られます。
| 対象 | 文字色 | 背景 | 実効背景 | 比 | 判定 |
|---|---|---|---|---|---|
| 見出し(成功ウォッシュ上) | #243038 | #eef7f1 | #eef7f1 | 12.35:1 | AA 合格 |
| アイコン緑(成功ウォッシュ上) | #1f6b4a | #eef7f1 | #eef7f1 | 5.89:1 | AA 合格 |
| アイコン赤(エラーウォッシュ上) | #9c2b34 | #fbeced | #fbeced | 6.52:1 | AA 合格 |
| アイコン青(情報ウォッシュ上) | #375f8a | #eaf1fb | #eaf1fb | 5.83:1 | AA 合格 |
| 本文(成功ウォッシュ上) | #4a5a63 | #eef7f1 | #eef7f1 | 6.55:1 | AA 合格 |
<!doctype html>
<html lang="ja"><head><meta charset="utf-8"><title>オーガニック・シェイプ トースト通知 デモ</title><style>
*{box-sizing:border-box;margin:0;padding:0}
:root{
--page:#edf0ee;
--ink:#243038;
--sub:#4a5a63;
--ok-bg:#eef7f1; --ok:#1f6b4a;
--err-bg:#fbeced; --err:#9c2b34;
--info-bg:#eaf1fb; --info:#375f8a;
}
body{background:var(--page);color:var(--ink);min-height:340px;padding:26px 28px;
font-family:system-ui,-apple-system,"Hiragino Kaku Gothic ProN","Yu Gothic",sans-serif}
h3{font-size:15px;letter-spacing:.02em;margin-bottom:4px}
.lead{font-size:12px;color:var(--sub);line-height:1.8;max-width:34em;margin-bottom:20px}
.stack{display:flex;flex-direction:column;gap:14px;max-width:26em}
.toast{position:relative;display:flex;gap:12px;align-items:flex-start;padding:14px 40px 14px 16px;
/* border-radiusの8値指定で角を非対称に崩す。17より崩し幅は控えめ(通知の輪郭は保つ) */
border-radius:30px 42px 28px 46px / 40px 26px 44px 30px;
box-shadow:0 6px 18px rgba(36,48,56,.08)}
.toast.ok{background:var(--ok-bg)}
.toast.err{background:var(--err-bg)}
.toast.info{background:var(--info-bg)}
.icon{flex:none;width:26px;height:26px;border-radius:50%;display:flex;align-items:center;justify-content:center;
font-size:14px;font-weight:800;color:#fff}
.toast.ok .icon{background:var(--ok)}
.toast.err .icon{background:var(--err)}
.toast.info .icon{background:var(--info)}
.body h4{font-size:13px;margin-bottom:3px}
.toast.ok h4{color:var(--ok)}
.toast.err h4{color:var(--err)}
.toast.info h4{color:var(--info)}
.body p{font-size:12px;color:var(--sub);line-height:1.6}
/* 閉じるボタン:視覚サイズは20pxでも、当たり判定はpaddingで44px相当を確保する。
ブロブの丸みに合わせて当たり判定まで削らない */
.close{position:absolute;top:6px;right:6px;width:44px;height:44px;border:0;background:none;
color:var(--sub);font-size:15px;cursor:pointer;display:flex;align-items:center;justify-content:center}
.close:hover{color:var(--ink)}
.close:focus-visible{outline:2px solid var(--ink);outline-offset:-2px;border-radius:50%}
/* 自動消滅の残り時間バー。hoverまたはfocus-withinで一時停止する(WCAG 2.2.1) */
.timer{position:absolute;left:16px;right:40px;bottom:6px;height:3px;border-radius:999px;background:rgba(0,0,0,.08);overflow:hidden}
.timer::after{content:"";display:block;height:100%;width:100%;transform-origin:left;
animation:shrink 6s linear forwards}
.toast.ok .timer::after{background:var(--ok)}
.toast.err .timer::after{background:var(--err)}
.toast.info .timer::after{background:var(--info)}
.toast:hover .timer::after,.toast:focus-within .timer::after{animation-play-state:paused}
@keyframes shrink{from{transform:scaleX(1)}to{transform:scaleX(0)}}
@media (prefers-reduced-motion:reduce){.timer::after{animation:none;transform:scaleX(1)}}
.note{margin-top:20px;font-size:11px;line-height:1.75;color:var(--sub);max-width:36em}
.note code{background:#fff;padding:1px 5px;border-radius:3px;font-family:ui-monospace,Consolas,monospace}
</style></head><body>
<h3>消える前に読めるか、読み上げられるか</h3>
<p class="lead">通知の縁は8値指定で軽く崩し、地色は淡いウォッシュ、見出し・アイコンは濃色で常時AAを確保する。自動消滅はホバー・フォーカス中は止まる。</p>
<div class="stack" aria-label="通知">
<div class="toast ok" role="status">
<div class="icon" aria-hidden="true">✓</div>
<div class="body"><h4>保存しました</h4><p>変更内容はすべて反映されています。</p></div>
<button class="close" type="button" aria-label="この通知を閉じる">×</button>
<div class="timer" aria-hidden="true"></div>
</div>
<div class="toast err" role="alert">
<div class="icon" aria-hidden="true">!</div>
<div class="body"><h4>送信に失敗しました</h4><p>通信環境を確認してもう一度お試しください。</p></div>
<button class="close" type="button" aria-label="この通知を閉じる">×</button>
<div class="timer" aria-hidden="true"></div>
</div>
<div class="toast info" role="status">
<div class="icon" aria-hidden="true">i</div>
<div class="body"><h4>新しいお知らせがあります</h4><p>アップデート内容をご確認ください。</p></div>
<button class="close" type="button" aria-label="この通知を閉じる">×</button>
<div class="timer" aria-hidden="true"></div>
</div>
</div>
<p class="note">
<code>role="status"</code>/<code>role="alert"</code> でスクリーンリーダーに通知内容を届け、
<code>:hover</code>・<code>:focus-within</code> でタイマーを一時停止する(WCAG 2.2.1)。
種類の違いはアイコン形状とテキストで示し、色(縁のウォッシュ)だけに頼らない。
</p>
</body></html>