反応する庭
チェックボックスとラジオボタンの状態に:has()で庭全体が応答する。夜にすれば月が昇り、札を選べば花が咲く。JavaScriptは一切使っていない。
上部のスイッチを切り替えると庭が変化します
お使いのブラウザは:has()に未対応のため、この庭はスイッチに反応しません。
対応ブラウザ
コード
表示中のコードは作品の実行に使われているものと同一ソースです。そのままコピーして試せます。
/* 反応する庭: フォーム要素の状態に:has()で庭全体が応答する。JSは不使用 */
.work-has-garden {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
background: #0c0d12;
}
/* ---- 操作パネル ---- */
.hg-controls {
position: absolute;
top: 12px;
left: 50%;
transform: translateX(-50%);
z-index: 20;
display: flex;
align-items: center;
gap: 8px;
padding: 8px 14px;
border: 1px solid rgba(255, 255, 255, 0.15);
border-radius: 999px;
background: rgba(8, 9, 14, 0.72);
backdrop-filter: blur(6px);
}
.hg-legend {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip-path: inset(50%);
}
.hg-chip {
display: inline-flex;
align-items: center;
gap: 5px;
color: #d8d8de;
font-size: 12px;
cursor: pointer;
white-space: nowrap;
}
.hg-chip input {
accent-color: #f2a5b8;
}
.hg-sep {
width: 1px;
height: 16px;
background: rgba(255, 255, 255, 0.2);
}
/* ---- 昼の庭 ---- */
.hg-scene {
position: absolute;
inset: 0;
}
.hg-sky {
position: absolute;
inset: 0;
background: linear-gradient(180deg, #7fc4e8 0%, #bfe3ef 60%, #eaf2d9 100%);
transition: filter 1.2s ease, opacity 1.2s ease;
}
.hg-sun {
position: absolute;
top: 16%;
left: 16%;
width: 11%;
aspect-ratio: 1;
border-radius: 50%;
background: radial-gradient(circle, #fff6d8 30%, #ffd166 70%);
box-shadow: 0 0 44px rgba(255, 209, 102, 0.8);
transition: transform 1.2s ease, opacity 1.2s ease;
}
.hg-moon {
position: absolute;
top: 14%;
right: 18%;
width: 9%;
aspect-ratio: 1;
border-radius: 50%;
background: radial-gradient(circle at 35% 35%, #fdf7e3, #e5d9a8);
box-shadow: 0 0 34px rgba(253, 247, 227, 0.5);
opacity: 0;
transform: translateY(60px);
transition: transform 1.2s ease, opacity 1.2s ease;
}
.hg-stars {
position: absolute;
inset: 0 0 40% 0;
background-image:
radial-gradient(1.5px 1.5px at 12% 30%, #fff, transparent),
radial-gradient(1px 1px at 28% 12%, #fff, transparent),
radial-gradient(1.5px 1.5px at 44% 38%, #fff, transparent),
radial-gradient(1px 1px at 58% 18%, #fff, transparent),
radial-gradient(1.5px 1.5px at 71% 42%, #fff, transparent),
radial-gradient(1px 1px at 86% 26%, #fff, transparent),
radial-gradient(1px 1px at 35% 55%, #fff, transparent),
radial-gradient(1.5px 1.5px at 92% 52%, #fff, transparent);
opacity: 0;
transition: opacity 1.4s ease;
}
.hg-hill {
position: absolute;
left: -10%;
right: -10%;
bottom: -32%;
height: 62%;
border-radius: 50% 50% 0 0;
transition: filter 1.2s ease;
}
.hg-hill-back {
bottom: -26%;
background: #8fbf6a;
filter: brightness(0.92);
}
.hg-hill-front {
background: #79ad55;
}
/* ---- 花 ---- */
.hg-flower {
position: absolute;
bottom: 18%;
width: 8px;
height: 22%;
transition: filter 1.2s ease;
}
.hg-f1 { left: 18%; height: 24%; }
.hg-f2 { left: 34%; height: 19%; bottom: 14%; }
.hg-f3 { left: 52%; height: 26%; bottom: 16%; }
.hg-f4 { left: 68%; height: 20%; bottom: 12%; }
.hg-f5 { left: 84%; height: 23%; bottom: 15%; }
.hg-stem {
position: absolute;
left: 50%;
bottom: 0;
width: 4px;
height: 100%;
transform: translateX(-50%);
border-radius: 4px;
background: linear-gradient(180deg, #4d8a3d, #2f6b2a);
}
/* 花頭: repeating-conic-gradientの花弁と中心の芯 */
.hg-head {
position: absolute;
top: 0;
left: 50%;
width: 54px;
height: 54px;
border-radius: 50%;
background:
radial-gradient(circle, #ffd166 0 22%, transparent 23%),
repeating-conic-gradient(from 0deg,
#f2a5b8 0deg 24deg, #fbd3dd 24deg 45deg);
transform: translate(-50%, -40%) scale(0.22);
transform-origin: center;
filter: saturate(0.5) brightness(0.85);
transition: transform 0.9s cubic-bezier(0.34, 1.56, 0.64, 1), filter 0.9s ease;
}
/* ---- 状態1: 三分咲き(radioに:has()で応答) ---- */
.work-has-garden:has(.hg-bloom:checked) .hg-f1 .hg-head,
.work-has-garden:has(.hg-bloom:checked) .hg-f3 .hg-head,
.work-has-garden:has(.hg-bloom:checked) .hg-f5 .hg-head {
transform: translate(-50%, -40%) scale(0.85);
filter: saturate(1) brightness(1);
}
/* ---- 状態2: 満開 ---- */
.work-has-garden:has(.hg-full:checked) .hg-head {
transform: translate(-50%, -40%) scale(1);
filter: saturate(1.15) brightness(1.05)
drop-shadow(0 0 10px rgba(242, 165, 184, 0.6));
}
/* ---- 状態3: 夜(checkboxに:has()で応答) ---- */
.work-has-garden:has(.hg-night:checked) .hg-sky {
filter: hue-rotate(150deg) saturate(0.55) brightness(0.32);
}
.work-has-garden:has(.hg-night:checked) .hg-sun {
transform: translateY(140px);
opacity: 0;
}
.work-has-garden:has(.hg-night:checked) .hg-moon {
transform: translateY(0);
opacity: 1;
}
.work-has-garden:has(.hg-night:checked) .hg-stars {
opacity: 0.9;
}
.work-has-garden:has(.hg-night:checked) .hg-hill,
.work-has-garden:has(.hg-night:checked) .hg-flower {
filter: brightness(0.45) saturate(0.7);
}
/* 夜の満開は花明かりに */
.work-has-garden:has(.hg-night:checked):has(.hg-full:checked) .hg-head {
filter: brightness(0.9) saturate(1.1)
drop-shadow(0 0 14px rgba(255, 214, 224, 0.8));
}
/* ---- :has()非対応ブラウザへの告知 ---- */
@supports not selector(:has(input)) {
.work-has-garden .work-warn {
display: block;
}
.work-has-garden .hg-controls {
opacity: 0.45;
}
}