「癒し」を表現する
ゆらぎ・呼吸・浮遊。見ている人の緊張をほどく、ゆっくりと繊細な動きの表現テクニック。
このページについて
- 「癒しの表現」とは:長い周期・小さな振幅・低彩度を組み合わせ、生体リズム(呼吸・ゆらぎ)に寄り添う動きで安心感を作る表現。「動いていることに気づかないほど穏やか」が品質の目安。
- こんな時に使う:スパ・サロン・ヨガ/瞑想アプリ・ヘルスケア・カウンセリング・寝具/アロマ系EC・お寺/神社サイト。
- 関連タグ:🌊 海🌺 温かみ(準備中)🌳 木漏れ日(準備中)
- AIへの伝え方のコツ:「癒し系で」では伝わらない。「周期7秒以上」「振幅±5px」「ease-in-out」「パステル低彩度」のように、ゆっくり・小さく・淡くを数値で指定すると意図通りになる。
表現の引き出し
🎨 呼吸するグラデーション
📝 表現の語彙
💬 AIへの指示テンプレ
🎯 似合うシーン
瞑想/マインドフルネスアプリ・スパ・ヨガスタジオ・カウンセリング・睡眠系サービス
🔧 実装手法
非対称な呼吸リズムの@keyframes(吸う4s/キープ2s/吐く6s)+ 異周期の色レイヤー重ね(12s/19s/23s/29s)+ 低彩度パステル
📄 コード例を見る
<div class="breath-stage">
<div class="breath-layer"></div>
<div class="hue-layer"></div>
<div class="soft-orb orb-a"></div>
<div class="soft-orb orb-b"></div>
<div class="soft-orb orb-c"></div>
</div>.breath-stage {
position: relative;
height: 180px;
border-radius: 8px;
overflow: hidden;
/* 低彩度パステル(薄ラベンダー→薄青→薄緑) */
background: linear-gradient(160deg, #e8e3f4 0%, #dce9f0 50%, #e5efe4 100%);
}
/* 呼吸レイヤー:中央やや上が明るい光が12秒周期で明滅 */
.breath-layer {
position: absolute;
inset: 0;
background: radial-gradient(circle at 50% 35%,
rgba(255, 253, 245, 0.5) 0%, rgba(255, 253, 245, 0) 70%);
animation: breathe 12s ease-in-out infinite;
}
/* 対称のsin波にしない:吸う4秒→止める2秒→吐く6秒(4-7-8呼吸法に近い非対称リズム) */
@keyframes breathe {
0% { opacity: 0; } /* 吐き切った状態 */
33% { opacity: 1; } /* 4秒かけて吸う */
50% { opacity: 1; } /* 2秒キープ */
100% { opacity: 0; } /* 6秒かけて吐く */
}
/* 色相の移ろい:周期19秒の薄桃レイヤー。12秒とのズレで重なりが毎回変わり、単調にならない */
.hue-layer {
position: absolute;
inset: 0;
background: radial-gradient(circle at 72% 78%,
rgba(244, 219, 231, 0.3) 0%, rgba(244, 219, 231, 0) 65%);
animation: hueDrift 19s ease-in-out infinite;
}
@keyframes hueDrift {
0%, 100% { opacity: 0.15; }
50% { opacity: 1; }
}
/* 微かな光の玉:ほぼ気づかない動きが「生きている」気配を作る */
.soft-orb {
position: absolute;
border-radius: 9999px;
background: #fffdf5;
filter: blur(25px);
}
.orb-a { top: 28px; left: 16%; width: 64px; height: 64px; opacity: .22;
animation: orbDrift 23s ease-in-out infinite alternate; }
.orb-b { top: 92px; left: 64%; width: 46px; height: 46px; opacity: .18;
animation: orbDrift 29s ease-in-out infinite alternate-reverse; }
.orb-c { top: 58px; left: 42%; width: 70px; height: 70px; opacity: .15;
animation: orbDrift 26s ease-in-out infinite alternate; animation-delay: -9s; }
@keyframes orbDrift {
from { transform: translate(0, 0); }
to { transform: translate(14px, -10px); }
}
@media (prefers-reduced-motion: reduce) {
.breath-layer, .hue-layer, .soft-orb { animation: none; }
}🎨 浮遊する光の玉
📝 表現の語彙
💬 AIへの指示テンプレ
🎯 似合うシーン
ナイトイベント・ウェディング・アロマ/キャンドル系EC・ホテル・記念日サービス
🔧 実装手法
radial-gradientの無輪郭光球 + blur/opacityによる被写界深度 + 縦・横・明滅の3軸独立周期の合成
📄 コード例を見る
// 光の玉7個。擬似乱数((i * 7919) % 100 方式)で個体差をつける
const FIREFLY_COLORS = [
[255, 251, 235], [254, 243, 199], [253, 246, 227], [255, 255, 255],
];
const orbs = Array.from({ length: 7 }, (_, i) => {
const j1 = ((i * 7919) % 100) / 100;
const j2 = ((i * 104729) % 100) / 100;
const size = 8 + j1 * 48; // 8〜56px
const [r, g, b] = FIREFLY_COLORS[i % 4];
return {
size,
left: 8 + ((i * 37) % 78), // % 不等間隔
top: 14 + ((i * 53) % 58), // %
blur: 2 + (size / 56) * 14, // 大きいほどボケる(手前のボケ)
base: 0.9 - (size / 56) * 0.55, // 大きいほど薄い(被写界深度)
bg: `radial-gradient(circle, rgba(${r},${g},${b},0.9) 0%,
rgba(${r},${g},${b},0.4) 40%, rgba(${r},${g},${b},0) 70%)`,
driftY: 11 + j1 * 12, // 縦の漂い 11〜23s
driftX: 7 + j2 * 12, // 横の漂い 7〜19s(縦と必ず違う周期)
twinkle: 5 + j1 * 8, // 明滅 5〜13s
delay: -(j2 * 20),
};
});
<div className="firefly-stage">
{orbs.map((o, i) => (
// 縦・横・明滅を別レイヤーに分けて3軸を独立合成(機械感の排除)
<div key={i} className="orb-y"
style={{ left: `${o.left}%`, top: `${o.top}%`,
animationDuration: `${o.driftY}s`, animationDelay: `${o.delay}s` }}>
<div className="orb-x"
style={{ animationDuration: `${o.driftX}s`, animationDelay: `${o.delay / 2}s` }}>
<div className="orb"
style={{ width: o.size, height: o.size, background: o.bg,
filter: `blur(${o.blur}px)`, "--base": o.base,
animationDuration: `${o.twinkle}s` }} />
</div>
</div>
))}
</div>.firefly-stage {
position: relative;
height: 180px;
border-radius: 8px;
overflow: hidden;
/* 夜の青灰。真っ黒にしない柔らかい夜 */
background: linear-gradient(180deg, #1e2a3a 0%, #2d3e50 60%, #3a4a5c 100%);
}
.orb-y { position: absolute; animation: floatY 15s ease-in-out infinite; }
.orb-x { animation: floatX 11s ease-in-out infinite; }
/* 輪郭のない、中心から溶けるような光(radial-gradientで作る) */
.orb {
border-radius: 9999px;
animation: orbTwinkle 7s ease-in-out infinite;
}
@keyframes floatY {
0%, 100% { transform: translateY(-12px); }
50% { transform: translateY(12px); }
}
@keyframes floatX {
0%, 100% { transform: translateX(-18px); }
50% { transform: translateX(18px); }
}
/* 明滅は基準値の±30%でゆっくり */
@keyframes orbTwinkle {
0%, 100% { opacity: calc(var(--base) * 0.7); }
50% { opacity: var(--base); }
}
@media (prefers-reduced-motion: reduce) {
.orb-y, .orb-x, .orb { animation: none; }
}🎨 ゆれる植物
📝 表現の語彙
💬 AIへの指示テンプレ
🎯 似合うシーン
オーガニック系EC・ハーブ/茶葉ブランド・ナチュラル系サロン・園芸・環境系NPO
🔧 実装手法
SVG pathの2段rotate(茎全体+上半分の位相差)によるしなり + animation-delayの順次ズラしで風の波
📄 コード例を見る
// 草6本。高さ・色・周期をバラし、delayは左→右へ順にズラす(風の波)
const plants = [
{ x: 56, h: 104, color: "#8fa882", sw: 2.6, dur: 7, delay: 0, bud: false },
{ x: 116, h: 142, color: "#7d9471", sw: 3, dur: 8.5, delay: -0.6, bud: true },
{ x: 172, h: 88, color: "#a4b594", sw: 2.2, dur: 6, delay: -1.1, bud: false },
{ x: 232, h: 126, color: "#8fa882", sw: 2.8, dur: 9, delay: -1.7, bud: false },
{ x: 296, h: 150, color: "#7d9471", sw: 3, dur: 7.5, delay: -2.2, bud: true },
{ x: 352, h: 96, color: "#b5c2a5", sw: 2.2, dur: 6.5, delay: -2.8, bud: false },
];
<svg viewBox="0 0 420 180" width={420} height={180}>
{plants.map((p) => {
const half = p.h * 0.5;
return (
<g key={p.x} transform={`translate(${p.x},174)`}>
{/* 茎全体:根元支点の rotate ±2.5deg */}
<g className="stem" style={{ "--dur": `${p.dur}s`, "--delay": `${p.delay}s` }}>
<path d={`M0,0 Q4,${-half * 0.6} 1,${-half}`}
stroke={p.color} strokeWidth={p.sw} fill="none" strokeLinecap="round" />
<g transform={`translate(1,${-half})`}>
{/* 茎の上半分:わずかに遅れた位相で追加のrotate(しなり) */}
<g className="stem-upper">
<path d={`M0,0 Q-4,${-half * 0.5} -1.5,${-half}`}
stroke={p.color} strokeWidth={p.sw * 0.6} fill="none" strokeLinecap="round" />
<path d={`M0,${-half * 0.4} Q9,${-half * 0.4 - 7} 13,${-half * 0.4 - 17}
Q4,${-half * 0.4 - 10} 0,${-half * 0.4}`} fill={p.color} opacity={0.85} />
{p.bud && <circle cx={-1.5} cy={-half - 2.5} r={3.5} fill="#d9c2cc" />}
</g>
</g>
</g>
</g>
);
})}
</svg>.meadow-stage {
position: relative;
height: 180px;
border-radius: 8px;
overflow: hidden;
/* 生成り→薄抹茶。和の余白感 */
background: linear-gradient(180deg, #f7f4ed 0%, #eef0e4 100%);
}
.meadow-ground {
position: absolute;
bottom: 0; left: 0; right: 0;
height: 8px;
background: #e3e6d6;
}
/* 茎全体:根元固定で ±2.5deg */
.stem {
transform-box: fill-box;
transform-origin: bottom center;
animation: sway var(--dur) ease-in-out infinite;
animation-delay: var(--delay);
}
/* 上半分:-0.4s 遅れた位相で ±1.5deg を重ねる → 根元が動いてから先端が遅れてついてくる */
.stem-upper {
transform-box: fill-box;
transform-origin: bottom center;
animation: swayUpper var(--dur) ease-in-out infinite;
animation-delay: calc(var(--delay) - 0.4s);
}
@keyframes sway {
0%, 100% { transform: rotate(-2.5deg); }
50% { transform: rotate(2.5deg); }
}
@keyframes swayUpper {
0%, 100% { transform: rotate(-1.5deg); }
50% { transform: rotate(1.5deg); }
}
/* 花粉・胞子の気配(小さな光の粒がごくゆっくり漂う) */
.pollen {
position: absolute;
border-radius: 9999px;
background: #fffdf0;
filter: blur(1px);
animation: pollenDrift 21s ease-in-out infinite alternate;
}
@keyframes pollenDrift {
from { transform: translate(0, 0); }
to { transform: translate(12px, -14px); }
}
@media (prefers-reduced-motion: reduce) {
.stem, .stem-upper, .pollen { animation: none; }
}🎨 水面の波紋
📝 表現の語彙
💬 AIへの指示テンプレ
🎯 似合うシーン
温泉/旅館・茶道/和文化・スパ・瞑想・サウンドセラピー・日本酒ブランド
🔧 実装手法
同心円3本組のease-out拡大 + 多地点・異周期のランダム発生 + 背景の微細な明度ゆらぎ(周期17s)
📄 コード例を見る
// 波紋の発生点5箇所。周期6〜14sでバラし「いつどこに落ちるか分からない」リズム
const ripples = [
{ left: "22%", top: "38%", cycle: 6, delay: -2 },
{ left: "68%", top: "26%", cycle: 8.5, delay: -5 },
{ left: "45%", top: "64%", cycle: 11, delay: -1 },
{ left: "84%", top: "70%", cycle: 14, delay: -8 },
{ left: "12%", top: "76%", cycle: 9.5, delay: -6.5 },
];
<div className="pond-stage">
<div className="light-band" /> {/* 静止した光の帯(水面の質感) */}
<div className="pond-shimmer" /> {/* 水面の微動(周期17sの明度ゆらぎ) */}
{ripples.map((r, i) => (
<div key={i} className="ripple-point" style={{ left: r.left, top: r.top }}>
{/* 雫の気配:波紋の直前に小さな白い点が一瞬現れる */}
<div className="drop"
style={{ animationDuration: `${r.cycle}s`, animationDelay: `${r.delay}s` }} />
{/* 1本の輪ではなく、0.25秒差で広がる同心円3本組 */}
{[0, 1, 2].map((n) => (
<div key={n} className="ripple-ring"
style={{ animationDuration: `${r.cycle}s`,
animationDelay: `${r.delay + 0.3 + n * 0.25}s` }} />
))}
</div>
))}
</div>.pond-stage {
position: relative;
height: 180px;
border-radius: 8px;
overflow: hidden;
/* 青磁色の静かな水面 */
background: linear-gradient(165deg, #dce8e8 0%, #c5d8d4 50%, #b2c9c4 100%);
}
.light-band {
position: absolute;
inset: 0;
background: linear-gradient(115deg,
rgba(255,255,255,0) 30%, rgba(255,255,255,0.2) 46%, rgba(255,255,255,0) 60%);
}
/* 完全静止だと「画像」に見えるため、ごくわずかな明度のゆらぎを入れる */
.pond-shimmer {
position: absolute;
inset: 0;
background: radial-gradient(circle at 60% 40%,
rgba(255,255,255,0.5) 0%, rgba(255,255,255,0) 70%);
animation: shimmer 17s ease-in-out infinite;
}
@keyframes shimmer {
0%, 100% { opacity: 0.02; }
50% { opacity: 0.07; }
}
.ripple-point { position: absolute; }
.ripple-ring {
position: absolute;
top: 0; left: 0;
border: 1.5px solid rgba(255, 255, 255, 0.55);
border-radius: 9999px;
transform: translate(-50%, -50%);
opacity: 0;
/* ease-out が重要:波紋は最初速く、徐々に減速して消える(物理的に正しい) */
animation: rippleExpand 9s ease-out infinite;
}
/* 拡大は周期の先頭35%で完了し、残りは静寂。線は広がるほど細く・薄く */
@keyframes rippleExpand {
0% { width: 0; height: 0; opacity: 0; border-width: 2.5px; }
2% { opacity: 0.8; }
35% { width: 130px; height: 130px; opacity: 0; border-width: 0.5px; }
100% { width: 130px; height: 130px; opacity: 0; border-width: 0.5px; }
}
.drop {
position: absolute;
width: 3px; height: 3px;
border-radius: 9999px;
background: #ffffff;
transform: translate(-50%, -50%);
opacity: 0;
animation: dropHint 9s linear infinite;
}
@keyframes dropHint {
0% { opacity: 0; }
1% { opacity: 0.9; }
3% { opacity: 0; }
100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
.pond-shimmer, .ripple-ring, .drop { animation: none; }
}よくある質問
癒し系の動きで一番やりがちな失敗は?
「速すぎる・大きすぎる」こと。一般的なUIアニメーション(0.3s〜1s)の感覚で作ると、癒しではなく「賑やか」になります。周期は最低4秒以上、移動は±10px以内、と意識的に1桁遅く・小さくするのがコツです。「動いていることに気づかれないくらい」がちょうどいい目安です。
ゆっくりした動きはユーザーを待たせない?
待たせません。本ページの表現はすべて「環境装飾」であり、コンテンツの表示やインタラクションをブロックしません。読み込み完了を待つスピナーとは役割が違うので、ゆっくりでも問題ありません。むしろ操作の邪魔をしない控えめさが大切です。
癒し表現とパフォーマンスの両立は?
transform と opacity のみを使えば、長周期アニメーションの負荷はごく小さいです。blurは要素数が多いと重くなるため、blur要素は5〜8個程度に抑えます。また「画面外では停止」(Intersection Observer)を入れると、長いページでも安心です。
AIに「癒し系のサイト」を頼むと派手になってしまう
「癒し」という言葉はAIにとって解釈の幅が広すぎます。本ページの各カードにある数値(周期12秒・振幅±10px・低彩度パステル・ease-in-out)をそのまま指示に含めると、意図の精度が大きく上がります。表現名(呼吸するグラデーション・波紋)で指定するのも有効です。