CSS 홀로그램 카드 효과 9가지 — 스티커·뱃지·티켓
CSS 홀로그램 효과는 각도에 따라 빛이 다르게 반사되는 홀로그램 재질을, CSS 그라디언트와 애니메이션만으로 흉내 내는 기법입니다. 포켓몬 카드처럼 빛나는 표면을 눈으로는 자주 보지만 막상 코드로 옮기려면 막막한 경우가 많아서, 카드·스티커·뱃지·티켓 등 아홉 가지를 실제로
자동 재생 · 눌러서 해당 항목으로 · 전부 한 zip
- 01 카드 홀로그램 마우스 틸트
- 02 스티커 모서리 필 + 홀로그램 스윕
- 03 인증 배지 홀로그램 링
- 04 홀로그램 텍스트 (무지개 색 회전)
- 05 티켓 스텁 홀로그램 스탬프
- 06 정품 인증 씰 (톱니 테두리)
- 07 가격표 리본 홀로그램
- 08 아바타 홀로그램 상태 링
- 09 로딩 배지 홀로그램 시머
아홉 개는 인기 순서가 아니라 홀로그램 재질이 실제 화면에서 등장하는 순서로 놓았습니다. 상품 카드가 커서를 따라 빛나며 시선을 붙잡고(01), 스티커가 장식으로 붙고(02), 원형 배지가 신뢰를 확인해 주고(03), 타이틀 텍스트가 분위기를 잡은 뒤(04), 티켓이 구매를 확정하고(05), 정품 씰이 진짜임을 증명하고(06), 가격표 리본이 구매를 유도하고(07), 아바타 링이 사용자의 정체성을 표시하고(08), 마지막으로 로딩 배지가 기다리는 동안 화면을 채웁니다(09).
| 번호 | 이름 | 무엇이 움직이나 | JS |
|---|---|---|---|
| 01 | 카드 홀로그램 마우스 틸트 | 하이라이트 위치, 카드 rotateX·rotateY |
8줄 |
| 02 | 스티커 모서리 필 + 홀로그램 스윕 | 모서리 transform, 시트 background-position |
없음 |
| 03 | 인증 배지 홀로그램 링 | 링 conic-gradient 회전 |
없음 |
| 04 | 홀로그램 텍스트 | filter: hue-rotate, background-position |
없음 |
| 05 | 티켓 스텁 홀로그램 스탬프 | 스탬프 회전·scale 펄스 |
없음 |
| 06 | 정품 인증 씰 | clip-path 씰 회전 속도 |
없음 |
| 07 | 가격표 리본 홀로그램 | 리본 rotate·background-position |
없음 |
| 08 | 아바타 홀로그램 상태 링 | 링 conic-gradient 회전 |
없음 |
| 09 | 로딩 배지 홀로그램 시머 | 대각선 띠 background-position, 점 scale |
없음 |
01카드 홀로그램 마우스 틸트
카드에 커서를 올리면 커서 위치를 따라 무지개빛 하이라이트가 표면을 스치고, 카드 전체가 그 방향으로 살짝 기웁니다. 한정판 상품 카드나 포켓몬 카드처럼 보여주고 싶은 굿즈 상세 페이지에 씁니다. :hover만으로는 정확한 커서 좌표를 못 읽어서 pointermove 8줄로 --mx·--my·--rx·--ry 네 개의 커스텀 프로퍼티만 갱신합니다.
.holo-card {
transform: perspective(700px) rotateX(var(--rx)) rotateY(var(--ry));
transition: transform $duration $easing;
}
.holo-card__shine {
background: conic-gradient(from 0deg, #ff5ecb, #5ef1ff, #a3ff5e, #fff45e, #ff5ecb);
background-position: var(--mx) var(--my);
mix-blend-mode: color-dodge;
}
c.addEventListener('pointermove', function(e){
var r=c.getBoundingClientRect(), mx=(e.clientX-r.left)/r.width*100, my=(e.clientY-r.top)/r.height*100;
c.style.setProperty('--mx', mx+'%'); c.style.setProperty('--my', my+'%');
c.style.setProperty('--rx', ((my/100)-.5)*-14+'deg'); c.style.setProperty('--ry', ((mx/100)-.5)*14+'deg');
});
02스티커 모서리 필 + 홀로그램 스윕
스티커 카드 한쪽 모서리가 평소에도 살짝 들려 있다가, 호버하면 그 밑으로 무지개 시트가 대각선으로 훑고 지나갑니다. 다이어리·플래너 스티커 목업이나 상품 배지형 스티커 미리보기에 어울립니다.
.sticker__peel {
clip-path: polygon(100% 0, 0 0, 100% 100%);
transform-origin: 100% 0;
transform: rotate(-6deg) translate(2px, -2px);
}
.sticker:hover .sticker__peel {
transform: rotate(-16deg) translate(6px, -6px);
}
.sticker__shine {
background: repeating-linear-gradient(115deg, transparent 0 10%,
#ff5ecb 10% 12%, #5ef1ff 12% 14%, #a3ff5e 14% 16%, #fff45e 16% 18%, transparent 18% 30%);
background-size: 260% 260%;
}
03인증 배지 홀로그램 링
원형 배지 테두리를 따라 무지개빛이 쉬지 않고 한 바퀴씩 돕니다. 정품 인증 배지, 검증된 판매자 표시, 한정판 굿즈 스탬프에 씁니다. mask-image로 링 모양만 남기고 conic-gradient가 각도에 따라 색을 바꿔서 실제 홀로그램 필름의 반사와 비슷하게 보입니다.
.v-badge__ring {
background: conic-gradient(from 0deg, #ff5ecb, #5ef1ff, #a3ff5e, #fff45e, #ff5ecb);
mask: radial-gradient(farthest-side, transparent calc(100% - 8px), #000 calc(100% - 8px));
animation: ring-spin 2s linear infinite;
}
@keyframes ring-spin { to { transform: rotate(360deg); } }
04홀로그램 텍스트
글자에 무지개 그라디언트를 입히고 filter: hue-rotate를 계속 돌려서, 인쇄된 홀로그램 스티커 글자처럼 색이 쉬지 않고 바뀝니다. 이벤트 페이지 타이틀이나 한정판 상품명, 홀로그램 콘셉트 배너에 씁니다.
.holo-text {
background: linear-gradient(90deg, #ff5ecb, #5ef1ff, #a3ff5e, #fff45e, #ff5ecb);
background-size: 300% 100%;
background-clip: text;
color: transparent;
animation: holo-hue 2s linear infinite, holo-slide 2s linear infinite;
}
@keyframes holo-hue { to { filter: hue-rotate(360deg); } }
@keyframes holo-slide { to { background-position: 300% 50%; } }
05티켓 스텁 홀로그램 스탬프
티켓 반쪽에 찍힌 원형 스탬프가 conic-gradient로 은은하게 돌고, 호버하면 살짝 커지며 빛이 강해집니다. 콘서트·행사 티켓 UI나 디지털 입장권 진위 표시에 씁니다. 회전 애니메이션과 확대 애니메이션을 서로 다른 요소에 나눠 걸어야 두 움직임이 충돌하지 않습니다.
.stampwrap {
transition: transform $duration $easing;
}
.stampwrap:hover { transform: scale(1.15); filter: brightness(1.2); }
.stamp {
background: conic-gradient(from 0deg, #ff5ecb, #5ef1ff, #a3ff5e, #fff45e, #ff5ecb);
animation: spin 3s linear infinite;
}
06정품 인증 씰
별 모양 톱니 테두리를 clip-path로 자르고 그 위에 무지개 그라디언트를 얹어 천천히 돌립니다. 호버하면 회전 속도가 빨라집니다. 정품 인증 스티커, 공식 굿즈 씰, 품질 보증 배지에 씁니다.
.seal__shape {
clip-path: polygon(50% 0%, 61% 12%, 75% 6%, 78% 20%, 93% 20%, 90% 35%, 100% 43%,
90% 55%, 96% 68%, 82% 70%, 80% 85%, 65% 80%, 58% 93%, 50% 82%);
background: conic-gradient(from 0deg, #ff5ecb, #5ef1ff, #a3ff5e, #fff45e, #ff5ecb);
animation: seal-spin 2s linear infinite;
}
.seal:hover .seal__shape { animation-duration: 700ms; }
07가격표 리본 홀로그램
가격표 모서리에 걸린 리본이 홀로그램 재질로 빛나고, 호버하면 살짝 흔들리며 빛이 리본 위를 스쳐 지나갑니다. 할인 가격표, 신상품 리본 태그, 프로모션 배지에 씁니다.
.tag__ribbon {
transform: rotate(35deg);
background: repeating-linear-gradient(115deg,
#ff5ecb 0 10%, #5ef1ff 10% 20%, #a3ff5e 20% 30%, #fff45e 30% 40%);
background-size: 220% 220%;
transition: transform $duration $easing, background-position $duration $easing;
}
.tag:hover .tag__ribbon { transform: rotate(30deg) translateY(-2px); background-position: 100% 40%; }
08아바타 홀로그램 상태 링
프로필 아바타 테두리에 conic-gradient 링이 천천히 돌아 '프리미엄'·'온라인' 같은 특별한 상태를 표시합니다. 프리미엄 회원 아바타 테두리, 라이브 방송 중 표시, VIP 프로필 배지에 씁니다. 03번 인증 배지와 같은 mask-image 기법이지만 안쪽에 아바타 이미지를 넣는다는 점이 다릅니다.
.avatar-wrap__ring {
background: conic-gradient(from 0deg, #ff5ecb, #5ef1ff, #a3ff5e, #fff45e, #ff5ecb);
mask: radial-gradient(farthest-side, transparent calc(100% - 6px), #000 calc(100% - 6px));
animation: ring-spin 2s linear infinite;
}
@keyframes ring-spin { to { transform: rotate(360deg); } }
09로딩 배지 홀로그램 시머
처리 중임을 알리는 배지 위로 무지개빛 대각선 띠가 반복해서 스치며, 끝나기 전까지 계속 반짝입니다. 결제 처리 중 배지, 업로드·동기화 진행 표시, AI 생성 대기 상태에 씁니다.
.loading-badge__shine {
background: repeating-linear-gradient(115deg, transparent 0 12%,
rgba(255,94,203,.55) 12% 16%, rgba(94,241,255,.55) 16% 20%, rgba(163,255,94,.55) 20% 24%, transparent 24% 36%);
background-size: 260% 260%;
animation: shimmer-sweep 2s linear infinite;
}
@keyframes shimmer-sweep { to { background-position: -260% -260%; } }
어디서 깨지는가 (함정)
mix-blend-mode: color-dodge를 쓰는 01번은 카드 뒤 배경이 밝을수록 하이라이트가 과하게 밝아집니다. 배경이 순백에 가까우면 color-dodge가 거의 흰 화면을 태워 버려서, 카드 자체에 어두운 그라디언트($stage-ink 계열)를 깔아 대비를 맞춰야 합니다. 또 03·06·08번처럼 conic-gradient 회전을 쓰는 항목은 애니메이션 대상이 transform: rotate()뿐이라 @property 없이도 모든 브라우저에서 매끄럽게 도는 반면, 01번의 하이라이트 이동은 실제로 커서를 움직일 때는 background-position을 전환(transition)하는 방식이고, 격자에 자동 재생되는 미리보기 루프에서만 별도로 @keyframes로 값을 직접 지정했습니다 — 커스텀 프로퍼티(--mx)를 그대로 키프레임에 넣으면 @property 등록 없이는 Safari 16.4 미만에서 끊겨 보일 수 있어, 이 미리보기 루프만큼은 background-position 자체를 애니메이션했습니다. 이 아홉 개 파일의 압축 비밀번호는 5tktgjj6이고, 문장 속에 평범하게 적어 두었으니 눈으로 찾아 붙여 넣으면 됩니다.
접근성
아홉 개 전부 prefers-reduced-motion: reduce에서 반복 애니메이션과 전환을 끄고 마지막 상태 근처에서 멈춥니다. 01은 기울기·하이라이트 전환이 사라지고 하이라이트만 은은하게 남고, 02는 모서리가 살짝 들린 채 고정되고, 03·08은 링 회전이 멈추고, 04는 그라디언트가 한 색 배치에서 정지하고, 05·06·07·09는 회전·스윕·펄스가 멈추고 정적인 형태만 남습니다. 01번의 pointermove 기울기는 키보드 사용자에게는 애초에 발동하지 않으므로 :focus-visible에 하이라이트만 켜지는 대체 상태를 따로 넣었습니다. mix-blend-mode 지원 범위는 MDN 문서에서 확인할 수 있습니다. 카드 호버 효과를 더 보고 싶다면 이전에 올린 카드 호버 모음과 홀로그램과 결이 비슷한 텍스트 그라디언트 모음도 함께 보면 좋습니다.
FAQ
01번 마우스 틸트는 마우스가 없는 터치 기기에서 어떻게 됩니까?
pointermove는 마우스·펜·터치를 모두 같은 이벤트로 받기 때문에 손가락으로 카드를 드래그해도 하이라이트가 따라옵니다. 드래그 없이 탭만 하는 경우에는 @media (hover: none)에서 :active 상태로 하이라이트만 살짝 켜지는 대체 동작을 넣어 뒀습니다.
03·08번 링 애니메이션은 @property 없이도 부드럽게 돕니까?
네. 두 항목 모두 애니메이션 대상이 커스텀 프로퍼티가 아니라 transform: rotate()이기 때문에 @property 등록 없이도 모든 최신 브라우저에서 매끄럽게 보간됩니다. @property가 필요한 쪽은 커스텀 프로퍼티 자체를 키프레임 값으로 넣을 때뿐입니다.
React 판에서 01번은 상태(state)를 씁니까?
아니요. HoloCardMouseTilt는 useState를 쓰지 않고 useRef로 DOM을 직접 잡아 style.setProperty로 커스텀 프로퍼티를 갱신합니다. 포인터가 움직일 때마다 리렌더링이 일어나면 성능이 떨어지기 때문에, 리액트 트리를 다시 그리지 않고 CSS 값만 바꾸는 방식을 택했습니다.