04액체 채움 (물결 수면)
버튼 아래에서 색이 차오르는데 수면이 평평하지 않고 물결 모양으로 흔들립니다. 물결 도형을 제자리에서 돌리면서 동시에 위로 올려 만듭니다.
쓰임장바구니 담기처럼 누르면 무언가 채워진다는 느낌을 색만으로 전하고 싶은 커머스 버튼
물결 타일translateoverflow

<main class="stage">
<button class="liq is-demo" type="button">
<span class="liq__wave" aria-hidden="true"></span>
<span class="liq__label">장바구니 담기</span>
</button>
</main>@use "../../../../site/static/demo-tokens" as *;
// 변형은 이 세 줄만 바꾼다
$duration: $dur-loop;
$easing: $ease-spring;
$color: $subject-mint;
@include stage($stage-yellow);
.liq {
position: relative;
overflow: hidden;
isolation: isolate;
border: 0;
cursor: pointer;
padding: $sp-4 $sp-8;
border-radius: $r-pill;
background: $subject-cream;
box-shadow: inset 0 0 0 2px $subject-ink;
color: $subject-ink;
font-family: inherit;
font-size: clamp(15px, 4.5vw, 19px);
font-weight: 800;
}
// 수면이 평평하지 않은 이유: 완전한 원이 아니라 네 모서리를 42% 둥글린 정사각형을 통째로 돌린다
.liq__wave {
position: absolute;
left: 50%;
bottom: 0;
width: 260px;
height: 260px;
border-radius: 42%;
background: $color;
transform: translate(-50%, 100%);
}
.liq__label { position: relative; }
.liq.is-demo .liq__wave { animation: liq-rise $duration $easing infinite; }
// rotate 가 0deg 에서 360deg 로 끝나 마지막 프레임과 첫 프레임의 그림이 같다
@keyframes liq-rise {
0% { transform: translate(-50%, 100%) rotate(0deg); }
52% { transform: translate(-50%, 68%) rotate(180deg); }
66% { transform: translate(-50%, 68%) rotate(230deg); }
100% { transform: translate(-50%, 100%) rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
.liq.is-demo .liq__wave { animation: none; transform: translate(-50%, 68%); }
}html, body {
margin: 0;
overflow: hidden;
}
.stage {
box-sizing: border-box;
min-height: 100vh;
display: grid;
place-items: center;
margin: 0;
background: #ffd23f;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
padding: clamp(8px, 4vw, 24px);
}
.liq {
position: relative;
overflow: hidden;
isolation: isolate;
border: 0;
cursor: pointer;
padding: 16px 32px;
border-radius: 999px;
background: #fff7e6;
box-shadow: inset 0 0 0 2px #17141a;
color: #17141a;
font-family: inherit;
font-size: clamp(15px, 4.5vw, 19px);
font-weight: 800;
}
.liq__wave {
position: absolute;
left: 50%;
bottom: 0;
width: 260px;
height: 260px;
border-radius: 42%;
background: #4cd4a6;
transform: translate(-50%, 100%);
}
.liq__label {
position: relative;
}
.liq.is-demo .liq__wave {
animation: liq-rise 2s cubic-bezier(0.2, 0.8, 0.2, 1) infinite;
}
@keyframes liq-rise {
0% {
transform: translate(-50%, 100%) rotate(0deg);
}
52% {
transform: translate(-50%, 68%) rotate(180deg);
}
66% {
transform: translate(-50%, 68%) rotate(230deg);
}
100% {
transform: translate(-50%, 100%) rotate(360deg);
}
}
@media (prefers-reduced-motion: reduce) {
.liq.is-demo .liq__wave {
animation: none;
transform: translate(-50%, 68%);
}
}import type { CSSProperties } from "react";
import styles from "./LiquidFillButton.module.scss";
export type LiquidFillButtonProps = {
label?: string;
duration?: number;
easing?: string;
color?: string;
};
type Vars = CSSProperties & { "--duration"?: string; "--easing"?: string; "--color"?: string };
export default function LiquidFillButton({
label = "Add to cart",
duration = 2000,
easing = "cubic-bezier(.2,.8,.2,1)",
color = "#4cd4a6",
}: LiquidFillButtonProps) {
const vars: Vars = { "--duration": `${duration}ms`, "--easing": easing, "--color": color };
return (
<button type="button" className={styles.liq} style={vars}>
<span className={styles.wave} aria-hidden="true" />
<span className={styles.label}>{label}</span>
</button>
);
}04 액체 채움 (물결 수면) — 측정 누적면적 6.315% · 움직인 프레임 13/23GODRICH 원작 · zip 에 SCSS·React 포함 · css 버튼 hover 효과 모음 9종 — 수상작에서 반복되는 기법
이 데모가 속한 글
css 버튼 hover 효과 모음 9종 — 수상작에서 반복되는 기법css 버튼 hover 효과 모음은 마우스를 올렸을 때 버튼이 어떻게 반응하는지를 기법별로 나눠 정리한 것입니다. 아홉 개 중 하나는 누르는 순간 버튼 폭이 원으로 줄어 스피너가 돌고, 끝나면 체크가 그려진 뒤 원래 이 글의 데모 전부 보기

