07Ruy băng holographic trên bảng giá
Dải ruy băng vắt qua góc bảng giá lấp lánh như lá thiếc, khi rê chuột lắc nhẹ và ánh sáng quét ngang qua.
Dùng choBảng giá giảm giá, thẻ ruy băng hàng mới, huy hiệu khuyến mãi
rotate(35deg) 리본@keyframes swaybackground-position 스윕

<main class="stage">
<div class="tag is-demo" tabindex="0">
<span class="tag__ribbon" aria-hidden="true">NEW</span>
<div class="tag__body">
<span class="tag__price">290.000₫</span>
</div>
</div>
</main>@use "../../../../site/static/demo-tokens" as *;
$duration: $dur-base; // 리본이 흔들리는 시간
$easing: $ease-out;
$color: $subject-blue; // 사용 안 함(참고용)
@include stage($stage-orange);
.tag {
position: relative;
width: min(140px, 46vw);
aspect-ratio: 4 / 3;
border-radius: $r-card;
background: $stage-paper;
box-shadow: $shadow-press;
overflow: hidden;
display: grid;
place-items: center;
outline: none;
cursor: pointer;
}
.tag__ribbon {
position: absolute; top: 14px; right: -34px;
width: 120px; padding: 4px 0;
text-align: center;
transform: rotate(35deg);
background: repeating-linear-gradient(115deg, #dcb9d1 0 10%, #b9d9dc 10% 20%, #c8dcb9 20% 30%, #dcdab9 30% 40%);
background-size: 220% 220%;
background-position: 0 0;
font-size: 10px; font-weight: 800; letter-spacing: .05em; color: $stage-ink; font-family: inherit;
box-shadow: 0 2px 6px rgba($stage-ink, .25);
transition: transform $duration $easing, background-position $duration $easing;
}
.tag__price { font-weight: 700; font-size: 15px; color: $stage-ink; font-family: inherit; }
.tag:hover .tag__ribbon,
.tag:focus-visible .tag__ribbon { transform: rotate(30deg) translateY(-2px); background-position: 100% 40%; }
.tag.is-demo .tag__ribbon { animation: ribbon-sway $dur-loop $easing infinite; }
@keyframes ribbon-sway {
0%, 15% { transform: rotate(35deg) translateY(0); background-position: 0 0; }
40% { transform: rotate(28deg) translateY(-3px); background-position: 100% 40%; }
65% { transform: rotate(38deg) translateY(2px); background-position: 0 100%; }
90%, 100% { transform: rotate(35deg) translateY(0); background-position: 0 0; }
}
@media (prefers-reduced-motion: reduce) {
.tag__ribbon { transition: none; }
.tag.is-demo .tag__ribbon { animation: none; }
}html, body {
margin: 0;
overflow: hidden;
}
.stage {
box-sizing: border-box;
min-height: 100vh;
display: grid;
place-items: center;
margin: 0;
background: #ff4d1f;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
padding: clamp(8px, 4vw, 24px);
}
.tag {
position: relative;
width: min(140px, 46vw);
aspect-ratio: 4/3;
border-radius: 16px;
background: #ffffff;
box-shadow: 0 6px 12px rgba(23, 20, 26, 0.32);
overflow: hidden;
display: grid;
place-items: center;
outline: none;
cursor: pointer;
}
.tag__ribbon {
position: absolute;
top: 14px;
right: -34px;
width: 120px;
padding: 4px 0;
text-align: center;
transform: rotate(35deg);
background: repeating-linear-gradient(115deg, #dcb9d1 0 10%, #b9d9dc 10% 20%, #c8dcb9 20% 30%, #dcdab9 30% 40%);
background-size: 220% 220%;
background-position: 0 0;
font-size: 10px;
font-weight: 800;
letter-spacing: 0.05em;
color: #17141a;
font-family: inherit;
box-shadow: 0 2px 6px rgba(23, 20, 26, 0.25);
transition: transform 300ms ease-out, background-position 300ms ease-out;
}
.tag__price {
font-weight: 700;
font-size: 15px;
color: #17141a;
font-family: inherit;
}
.tag:hover .tag__ribbon,
.tag:focus-visible .tag__ribbon {
transform: rotate(30deg) translateY(-2px);
background-position: 100% 40%;
}
.tag.is-demo .tag__ribbon {
animation: ribbon-sway 2s ease-out infinite;
}
@keyframes ribbon-sway {
0%, 15% {
transform: rotate(35deg) translateY(0);
background-position: 0 0;
}
40% {
transform: rotate(28deg) translateY(-3px);
background-position: 100% 40%;
}
65% {
transform: rotate(38deg) translateY(2px);
background-position: 0 100%;
}
90%, 100% {
transform: rotate(35deg) translateY(0);
background-position: 0 0;
}
}
@media (prefers-reduced-motion: reduce) {
.tag__ribbon {
transition: none;
}
.tag.is-demo .tag__ribbon {
animation: none;
}
}import type { CSSProperties } from "react";
import styles from "./PriceTagRibbon.module.scss";
export type PriceTagRibbonProps = {
ribbon: string;
price: string;
/** 리본이 흔들리는 시간 (기본 300ms) */
duration?: number;
easing?: string;
/** 사용 안 함(참고용) */
color?: string;
};
type Vars = CSSProperties & { "--duration"?: string; "--easing"?: string; "--color"?: string };
export default function PriceTagRibbon({
ribbon,
price,
duration = 300,
easing = "ease-out",
color = "#2f6df6",
}: PriceTagRibbonProps) {
const vars: Vars = { "--duration": `${duration}ms`, "--easing": easing, "--color": color };
return (
<div className={styles.tag} style={vars} tabIndex={0}>
<span className={styles.ribbon} aria-hidden="true">{ribbon}</span>
<div className={styles.body}>
<span className={styles.price}>{price}</span>
</div>
</div>
);
}07 Ruy băng holographic trên bảng giá — Diện tích đo được 1.608% · khung hình chuyển động 19/23Nguyên tác GODRICH · SCSS và React nằm trong tệp zip · 9 hiệu ứng CSS Holographic Card Effect copy-paste
Bài viết chứa demo này
9 hiệu ứng CSS Holographic Card Effect copy-pasteHiệu ứng css holographic card effect giả lập cách lá thiếc phản chiếu ánh sáng theo góc nhìn, chỉ bằng CSS — lấp lánh nh Xem tất cả demo trong bài này


