01Bồng bềnh trôi (fuwafuwa)
Chỉ cần gắn `.o-float` là badge chậm rãi lên xuống bằng translateY kèm rotate nhẹ, như badge hàng mới tự thở, luôn báo hiệu sự hiện diện của mình.
Dùng choBadge hàng mới, chip báo khuyến mãi, mũi tên gợi ý onboarding
translateYrotate 3deg2.8s

<main class="stage">
<div class="badge o-float">
<span class="badge__dot" aria-hidden="true"></span>
Hàng mới
</div>
<span class="tag">Bồng bềnh</span>
</main>@use "../../../../site/static/demo-tokens" as *;
// ── 변수 3개. 변형은 이것만 바꾼다 ──────────────────────
$duration: 2.8s;
$easing: ease-in-out;
$color: $subject-blue;
// ── 데모 무대 ───────────────────────────────
@include stage($stage-ink);
.stage { position: relative; }
.badge {
display: inline-flex;
align-items: center;
gap: $sp-2;
padding: $sp-3 $sp-6;
border-radius: $r-pill;
background: $subject-cream;
color: $stage-ink;
font-weight: 700;
font-size: clamp(16px, 4.5vw, 20px);
line-height: 1;
font-family: inherit;
box-shadow: $shadow-raised;
}
.badge__dot {
width: 10px;
height: 10px;
border-radius: 50%;
background: $color;
flex: none;
}
.tag {
position: absolute;
top: $sp-4;
right: $sp-4;
padding: $sp-1 $sp-3;
border-radius: $r-sm;
background: rgba(255, 255, 255, .12);
color: $subject-cream;
font-weight: 700;
font-size: 12px;
line-height: 1;
font-family: inherit;
letter-spacing: .04em;
}
// ── .o-float 하나만 붙이면 어떤 요소든 떠오른다 ─────
.o-float {
animation: o-float $duration $easing infinite;
}
@keyframes o-float {
0%, 100% { transform: translateY(0) rotate(0deg); }
50% { transform: translateY(-14px) rotate(-3deg); }
}
// ── 접근성 ──────────────────────────────────────────
@media (prefers-reduced-motion: reduce) {
.o-float { animation: none; }
}html, body {
margin: 0;
overflow: hidden;
}
.stage {
box-sizing: border-box;
min-height: 100vh;
display: grid;
place-items: center;
margin: 0;
background: #17141a;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
padding: clamp(8px, 4vw, 24px);
}
.stage {
position: relative;
}
.badge {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 12px 24px;
border-radius: 999px;
background: #fff7e6;
color: #17141a;
font-weight: 700;
font-size: clamp(16px, 4.5vw, 20px);
line-height: 1;
font-family: inherit;
box-shadow: 0 14px 24px rgba(23, 20, 26, 0.32);
}
.badge__dot {
width: 10px;
height: 10px;
border-radius: 50%;
background: #2f6df6;
flex: none;
}
.tag {
position: absolute;
top: 16px;
right: 16px;
padding: 4px 12px;
border-radius: 8px;
background: rgba(255, 255, 255, 0.12);
color: #fff7e6;
font-weight: 700;
font-size: 12px;
line-height: 1;
font-family: inherit;
letter-spacing: 0.04em;
}
.o-float {
animation: o-float 2.8s ease-in-out infinite;
}
@keyframes o-float {
0%, 100% {
transform: translateY(0) rotate(0deg);
}
50% {
transform: translateY(-14px) rotate(-3deg);
}
}
@media (prefers-reduced-motion: reduce) {
.o-float {
animation: none;
}
}import type { CSSProperties, ReactNode } from "react";
import styles from "./FloatBadge.module.scss";
export type FloatBadgeProps = {
children: ReactNode;
/** 한 번 오가는 데 걸리는 시간 (기본 2800ms) */
duration?: number;
/** CSS easing (기본 ease-in-out) */
easing?: string;
/** 점 색 */
color?: string;
};
type Vars = CSSProperties & {
"--duration"?: string;
"--easing"?: string;
"--color"?: string;
};
export default function FloatBadge({
children,
duration = 2800,
easing = "ease-in-out",
color = "#2f6df6",
}: FloatBadgeProps) {
const vars: Vars = {
"--duration": `${duration}ms`,
"--easing": easing,
"--color": color,
};
return (
<div className={styles.badge} style={vars}>
<span className={styles.dot} aria-hidden="true" />
{children}
</div>
);
}01 Bồng bềnh trôi (fuwafuwa) — Diện tích đo được 3.606% · khung hình chuyển động 23/23Nguyên tác GODRICH · SCSS và React nằm trong tệp zip · 9 css bounce animation — dán một dòng là chạy
Bài viết chứa demo này
9 css bounce animation — dán một dòng là chạycss bounce animation là chuyển động cho phần tử nổi lên, nảy, rung và đung đưa như đang sống. Chín mục gọi theo từ tượng Xem tất cả demo trong bài này

