Prompt Share
Apple風ガラスUI(Liquid Glass)デザイン実装スキル
SKILL定義 (Markdown)
name: liquid-glass-ui
description: Apple の Liquid Glass に着想を得た「すりガラス質感」のUIをWeb標準技術で実装するためのスキル。ナビゲーションバー、カード、ボタン、ドック、モーダルなどに半透明・ぼかし・光沢のマテリアル表現を適用したいとき、または既存UIのガラス表現が「安っぽい/読みにくい/重い」ときに使う。CSS(backdrop-filter)を前提とし、React/Vue/Tailwind いずれの環境でも適用できる。
Apple風ガラスUI(Liquid Glass)デザイン
概要
Apple が iOS 26 / macOS 26 世代で導入した Liquid Glass は、「板状の半透明パネル」ではなく 背後のコンテンツを屈折・彩度強調しながら透かすレンズ状のマテリアル として設計されている。Web でこれを再現する際、backdrop-filter: blur() を掛けただけの実装は必ず「ただの曇りガラス」に見える。
本物らしさを決めるのは以下の4点であり、ぼかし量ではない。
- 彩度の持ち上げ(saturate)— 背後の色が生きたまま透ける
- エッジのハイライト(inset の1pxライン)— レンズの縁が光る
- 背後のコンテンツ— 透かす対象がない場所にガラスは成立しない
- 可読性のための地力(コントラスト確保)
Apple の意匠そのものを複製するのではなく、上記の物理的な振る舞いを Web 標準で再現する。
適用判断
使うべき場面
- 写真・グラデーション・動画・地図など、情報量のある背景の上に重なるレイヤー(ナビバー、ドック、フローティングパネル、オーバーレイ)
- スクロールでコンテンツが下を通過する固定ヘッダー/ツールバー
- 「浮いている」ことを伝えたい一時的UI(モーダル、トースト、ポップオーバー)
使ってはいけない場面
- 単色の白/薄グレー背景 → ガラスが透かすものがなく、単なる灰色の箱になる
- 長文の本文、表、フォームの入力領域 → 可読性コストが利得を上回る
- 画面の大半を覆う面積 → GPU コストが跳ね、かつ質感が安くなる
- 情報密度の高い管理画面 → 境界が曖昧になり操作精度が落ちる
判断基準:そのパネルを取り除いたとき、背後に見せる価値のある絵があるか。 無いなら不透明なサーフェスを使う。
実装手順
Step 1. 背景を先に作る
ガラスより先に 透かす対象 を用意する。無地の背景しかない場合は、ぼかした大きめの色ブロブ(radial-gradient を2〜3枚重ねる)を敷く。これが Liquid Glass の見えを 8 割決める。
Step 2. ベースマテリアルを当てる
assets/liquid-glass.css の .glass を適用する。構成要素は以下:
| 要素 | 役割 | 目安 |
|---|---|---|
backdrop-filter: blur() |
背後の分離 | 16–32px(大きい面ほど大きく) |
backdrop-filter: saturate() |
背後の色を生かす | 160–200% |
| 半透明の地色 | 可読性の下支え | light: 白 50–65% / dark: 濃色 40–55% |
border: 1px |
レンズの外縁 | 白 45–60%(dark は 10–18%) |
inset ハイライト |
上端の光の入り | 上 白60% / 下 白12% |
| 外側シャドウ | 浮遊感 | 大きくぼかして低不透明度 |
Step 3. スペキュラハイライトを重ねる
::before に斜め方向の白のグラデーションを敷く(左上 45% → 途中 8% → 0%)。これが無いと平坦な半透明板に見える。コンテンツは z-index: 1 で上に置くこと。
Step 4. 角丸と階層を整える
- 角丸は大きめ(パネル 20–28px、ボタンは pill)
- ガラスの入れ子は 1 段まで。 ガラスの上にガラスを重ねると、内側がぼかし済みの出力を再サンプリングして濁る
- 兄弟要素として並べるのは可。親子で重ねない
Step 5. モーションを付ける
- 押下:
transform: scale(.96)、イージングはcubic-bezier(.32,.72,0,1) - ホバー:わずかな浮上(translateY -1px)+ シャドウ拡大
- blur 値はアニメーションさせない(毎フレーム再合成が走り確実に落ちる)。動かすのは
transformとopacityのみ
Step 6. 可読性とフォールバックを検証する
必須。詳細は reference/checklist.md。
可読性(最優先事項)
ガラスは背景次第でコントラストが変動するため、最悪ケースの背景で検証する。
- 本文テキストは 4.5:1、大きい文字・アイコンは 3:1 を、想定される最も明るい背景と最も暗い背景の両方で満たす
- 満たせない場合は「ぼかしを強める」のではなく 地色の不透明度を上げる。ぼかしはコントラストを改善しない
- テキストに
text-shadowを足して誤魔化さない。滲んで安く見える @media (prefers-reduced-transparency: reduce)と(prefers-contrast: more)で不透明サーフェスに切り替える(実装済み)
パフォーマンス / 既知の落とし穴
backdrop-filterは GPU 合成コストが高い。同時に画面内へ置くのは 3–4 枚までを目安にする- 祖先要素に
filter/backdrop-filter/ 一部のtransformがあると、子のbackdrop-filterが効かない・崩れる backdrop-filterを持つ要素は新しいスタッキングコンテキストを作る。z-indexの前提が変わる点に注意- Safari は
-webkit-backdrop-filterの併記が必要 border-radiusを効かせるには、はみ出す子要素側でoverflow: hiddenを検討する- 未対応環境向けに
@supports not (backdrop-filter: blur(1px))の分岐を必ず置く
アンチパターン
| NG | 直し方 |
|---|---|
| 全パーツをガラスにする | ガラスは画面内 1–2 種類の役割に限定し、他は不透明にする |
| 無地背景の上に置く | 背景に色を作る、またはガラスをやめる |
| blur だけ強くする(60px+) | blur を 20px 前後に戻し、saturate と地色不透明度で質感を出す |
| 縁のハイライトが無い | 1px border + inset ハイライトを入れる。これが最も効く |
| ガラスの多段ネスト | 1 段に潰す |
| 白文字を明るい背景のガラスに載せる | 地色を濃色側に切り替えるか、文字色を反転する |
完了条件
- 明るい背景・暗い背景の両方でコントラスト基準を満たす
- ライト/ダーク両モードで確認済み
-
prefers-reduced-transparencyで不透明にフォールバックする - ガラスのネストが 1 段以下
- 画面内の
backdrop-filter要素が 4 枚以下 - blur 値をアニメーションしていない
- Safari 接頭辞を併記済み
同梱リソース
assets/liquid-glass.css— トークンと.glass/ バー / カード / ボタン / ドックの実装一式reference/checklist.md— レビュー用チェックリストと調整早見表
追加リソース2ファイル
/* ============================================================
Liquid Glass UI — base material & components
Apple の Liquid Glass に着想を得た Web 標準実装
============================================================ */
/* ---------- 1. Design tokens ---------- */
:root {
--glass-blur: 24px;
--glass-saturate: 180%;
--glass-tint: 255 255 255; /* 地色 RGB */
--glass-alpha: 0.55; /* 地色の不透明度 = 可読性のつまみ */
--glass-radius: 22px;
--glass-border: rgba(255, 255, 255, 0.55);
--glass-hi-top: rgba(255, 255, 255, 0.60);
--glass-hi-bottom: rgba(255, 255, 255, 0.12);
--glass-shadow: 0 12px 40px rgba(0, 0, 0, 0.18);
--glass-text: #10131a;
--glass-ease: cubic-bezier(0.32, 0.72, 0, 1);
}
@media (prefers-color-scheme: dark) {
:root {
--glass-tint: 22 24 28;
--glass-alpha: 0.48;
--glass-border: rgba(255, 255, 255, 0.14);
--glass-hi-top: rgba(255, 255, 255, 0.22);
--glass-hi-bottom: rgba(255, 255, 255, 0.05);
--glass-shadow: 0 16px 48px rgba(0, 0, 0, 0.50);
--glass-text: #f2f4f8;
}
}
/* ---------- 2. 透かす背景を作る(必須) ---------- */
/* ガラスは背後に情報が無いと成立しない。無地ページには敷いておく。 */
.glass-backdrop {
position: relative;
min-height: 100%;
background-color: #eef1f6;
background-image:
radial-gradient(60% 55% at 18% 22%, rgba(120, 170, 255, 0.85), transparent 70%),
radial-gradient(55% 50% at 82% 30%, rgba(255, 140, 190, 0.70), transparent 70%),
radial-gradient(70% 60% at 50% 92%, rgba(120, 235, 210, 0.65), transparent 72%);
}
@media (prefers-color-scheme: dark) {
.glass-backdrop { background-color: #0b0d12; }
}
/* ---------- 3. ベースマテリアル ---------- */
.glass {
position: relative;
isolation: isolate;
color: var(--glass-text);
background: rgb(var(--glass-tint) / var(--glass-alpha));
-webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
border: 1px solid var(--glass-border);
border-radius: var(--glass-radius);
box-shadow:
var(--glass-shadow),
inset 0 1px 0 var(--glass-hi-top),
inset 0 -1px 0 var(--glass-hi-bottom);
}
/* スペキュラハイライト:これが無いと平坦な半透明板に見える */
.glass::before {
content: "";
position: absolute;
inset: 0;
z-index: 0;
border-radius: inherit;
pointer-events: none;
background: linear-gradient(
150deg,
rgba(255, 255, 255, 0.45) 0%,
rgba(255, 255, 255, 0.08) 34%,
rgba(255, 255, 255, 0) 60%
);
}
/* コンテンツはハイライトより上に置く */
.glass > * {
position: relative;
z-index: 1;
}
/* 背景が激しい場合の可読性補強(ぼかしではなく地色で稼ぐ) */
.glass--solidify { --glass-alpha: 0.78; }
/* ---------- 4. コンポーネント ---------- */
/* 固定ナビゲーションバー */
.glass-bar {
--glass-blur: 30px;
--glass-radius: 0px;
position: sticky;
top: 0;
z-index: 100;
display: flex;
align-items: center;
gap: 16px;
padding: 12px 20px;
border-inline: none;
border-top: none;
}
/* フローティングカード / パネル */
.glass-card {
padding: 20px 22px;
}
/* ボタン(pill) */
.glass-btn {
--glass-radius: 999px;
--glass-blur: 16px;
display: inline-flex;
align-items: center;
gap: 8px;
padding: 10px 20px;
font: inherit;
font-weight: 590;
cursor: pointer;
transition:
transform 0.28s var(--glass-ease),
box-shadow 0.28s var(--glass-ease),
background-color 0.28s var(--glass-ease);
}
.glass-btn:hover {
transform: translateY(-1px);
background: rgb(var(--glass-tint) / calc(var(--glass-alpha) + 0.12));
}
.glass-btn:active { transform: scale(0.96); }
.glass-btn:focus-visible {
outline: 2px solid currentColor;
outline-offset: 3px;
}
/* ドック / ツールバー */
.glass-dock {
--glass-radius: 26px;
position: fixed;
left: 50%;
bottom: 24px;
transform: translateX(-50%);
display: flex;
gap: 6px;
padding: 8px;
}
/* ドック内の項目はガラスを重ねない(ネスト禁止)。透明なチップにする。 */
.glass-dock__item {
position: relative;
z-index: 1;
border: 0;
border-radius: 18px;
padding: 10px 14px;
background: rgb(var(--glass-tint) / 0.28);
color: inherit;
cursor: pointer;
transition: background-color 0.2s var(--glass-ease), transform 0.2s var(--glass-ease);
}
.glass-dock__item:hover { background: rgb(var(--glass-tint) / 0.5); }
.glass-dock__item:active { transform: scale(0.94); }
/* ---------- 5. フォールバック(必須) ---------- */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
.glass { background: rgb(var(--glass-tint) / 0.94); }
}
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
.glass {
background: rgb(var(--glass-tint) / 0.97);
-webkit-backdrop-filter: none;
backdrop-filter: none;
}
.glass::before { display: none; }
}
@media (prefers-reduced-motion: reduce) {
.glass-btn,
.glass-dock__item { transition: none; }
.glass-btn:hover { transform: none; }
}
# Liquid Glass レビューチェックリスト
## A. 成立条件
- [ ] ガラスの背後に、透かす価値のある絵(写真・グラデーション・スクロールするコンテンツ)がある
- [ ] ガラスを使う役割が画面内で 1〜2 種類に絞られている
- [ ] 本文・表・入力欄など「読ませる/操作させる」領域はガラスの上に載っていない
## B. 質感
- [ ] `saturate()` が 160〜200% で入っている(blur だけになっていない)
- [ ] 1px の border と inset ハイライトで縁が光っている
- [ ] スペキュラハイライト(斜めの白グラデ)が入っている
- [ ] 外側シャドウが「大きくぼかして低不透明度」になっている(濃く小さい影は安く見える)
- [ ] 角丸が十分に大きい(パネル 20〜28px / ボタンは pill)
## C. 可読性
- [ ] 想定される **最も明るい背景** で本文 4.5:1 を満たす
- [ ] 想定される **最も暗い背景** で本文 4.5:1 を満たす
- [ ] アイコン・境界線が 3:1 を満たす
- [ ] `text-shadow` による誤魔化しをしていない
- [ ] ライト / ダーク両モードで確認済み
## D. アクセシビリティ
- [ ] `prefers-reduced-transparency: reduce` で不透明にフォールバックする
- [ ] `prefers-contrast: more` に対応している
- [ ] `prefers-reduced-motion: reduce` でモーションを止めている
- [ ] フォーカスリングがガラス上でも視認できる
## E. パフォーマンス
- [ ] 画面内の `backdrop-filter` 要素が 4 枚以下
- [ ] blur 値をアニメーションしていない(動かすのは transform / opacity のみ)
- [ ] ガラスのネストが 1 段以下
- [ ] 祖先に `filter` / `transform` が無いことを確認した
- [ ] `-webkit-backdrop-filter` を併記した
- [ ] スクロール・リサイズ時にカクつきが出ないか実機で確認した
---
## 症状別 調整早見表
| 症状 | 原因 | 対処 |
|---|---|---|
| ただの灰色の箱に見える | 背後に透かすものが無い | 背景にグラデーション/写真を敷く。無理ならガラスをやめる |
| 眠い・くすんで見える | 彩度が落ちている | `saturate()` を 180% 付近まで上げる |
| 平坦な半透明板に見える | 縁とハイライトが無い | 1px border + inset ハイライト + スペキュラを追加 |
| 文字が読みにくい | 地色が薄すぎる | `--glass-alpha` を上げる(blur を上げても改善しない) |
| 内側のパネルが濁る | ガラスの多段ネスト | 内側は半透明チップに置き換える |
| スクロールが重い | backdrop-filter が多すぎる | 枚数を減らす / blur を下げる / 固定要素のみに限定 |
| 効果が突然消える | 祖先の filter・transform | 祖先のスタイルを外すか、ガラス要素を階層外に出す |
| 影が安っぽい | 影が小さく濃い | ぼかしを大きく、不透明度を 0.15〜0.20 に下げる |
Discover more
おすすめのプロンプト
Webアプリ開発 効率化チェックリスト
Webアプリ開発の効率化 目的 個人・小規模チームでのWebアプリ開発において、無駄な手戻りや作業時間を減らし、 リリースまでのスピードを上げるための実践的なチェックリストとTips集。 1. 環境構築を高速化する プロジ…
詳しく見るデータ加工用汎用SKILL
目的 ここにSKILLの目的を記述 前提条件 必要なデータや環境 使用方法 SKILLの呼び出し方や引数 手順 1. 手順1 2. 手順2 期待出力 出力例やフォーマット 注意点 留意すべきポイント
詳しく見る高品質な画像生成プロンプト設計スキル
高品質な画像生成プロンプト設計スキル ユーザーの要望を、画像生成AIが解釈しやすい具体的な制作指示へ変換するスキルです。人物、商品、風景、広告、イラスト、UIモックアップ、図解、SNS素材などに対応します。 目的 曖昧な依…
詳しく見る