관리 메뉴

웹솔루션개발 26년 노하우! 해피CGI의 모든것

[해피CGI][cgimall] CSS만으로 구현한 인터랙티브 3D 카드 효과 본문

웹프로그램밍 자료실/기타 자료

[해피CGI][cgimall] CSS만으로 구현한 인터랙티브 3D 카드 효과

해피CGI윤실장 2026. 5. 13. 09:04

마우스 움직임에 따라 카드가 자연스럽게 기울어지며
입체적으로 반응하는 3D 인터랙션 효과를 CSS로 구현한 예제입니다.

transform, perspective, hover 속성을 활용하여
별도의 JavaScript 없이도 카드가 실제로 움직이는 듯한 동적인 UI 효과를 표현할 수 있습니다.

카드형 레이아웃, 서비스 소개 영역, 상품 리스트 등 다양한 UI 디자인에 적용하기 좋으며,
간단한 코드만으로도 세련된 인터랙션을 구현할 수 있는 효과적인 예제입니다.




HTML 구조

- const DATA = [

- '1540968221243-29f5d70540bf', 

- '1596135187959-562c650d98bc', 

- '1628944682084-831f35256163', 

- '1590013330451-3946e83e0392', 

- '1590421959604-741d0eec0a2e', 

- '1572613000712-eadc57acbecd', 

- '1570097192570-4b49a6736f9f', 

- '1620789550663-2b10e0080354', 

- '1617775623669-20bff4ffaa5c', 

- '1548600916-dc8492f8e845', 

- '1573824969595-a76d4365a2e6', 

- '1633936929709-59991b5fdd72'

- ];

- const N = DATA.length;

 

.scene

.a3d(style=`--n: ${N}`)

- for(let i = 0; i < N; i++)

img.card(src=`https://images.unsplash.com/photo-${DATA[i]}?w=280` 

         style=`--i: ${i}` alt='jellyfish')

 

//- generates this kind of HTML:

//- <div class="scene">

//- <div class="a3d" style="--n: 12">

//- <img class="card" src="image0.jpg" style="--i: 0" alt="image description"/>

//- <img class="card" src="image1.jpg" style="--i: 1" alt="image description"/>

//- <!-- the rest of the cards -->

//- </div>

//- </div>



CSS 소스

/* ====== Relevant CSS ====== */

.scene, .a3d { display: grid }

 

.scene {

/* prevent scrollbars */

overflow: hidden;

/* for 3D look; smaller = more extreme effect */

perspective: 35em;

mask: /* lateral fade */

linear-gradient(90deg, 

#0000, red 20% 80%, #0000)

}

 

.a3d {

place-self: center /* middle align */;

/* don't flatten 3D transformed children 

* of this parent having its own 3D transform */

transform-style: preserve-3d;

animation: ry 32s linear infinite

}

/* simplest y axis rotation */

@keyframes ry { to { rotate: y 1turn } }

 

.card {

/* base card width, you may change this */

--w: 17.5em;

/* compute base angle corresponding to a card */

--ba: 1turn/var(--n); /* in the future: sibling-count() */

grid-area: 1/ 1 /* stack in same one grid cell */;

width: var(--w);

aspect-ratio: 7/ 10;

object-fit: cover;

border-radius: 1.5em;

/* don't want to see back of cards in front of screen plane */

backface-visibility: hidden;

/* need to use a transform chain here, cannot use separate 

* rotate & translate properties because they'd be applied 

* in wrong order (translate, then rotate) for what we need */

transform: 

/* rotate around y axis; in the future: sibling-index() */

rotatey(calc(var(--i)*var(--ba)))

/* only after that translate along z axis with minus */

translatez(calc(-1*(.5*var(--w) + .5em)/tan(.5*var(--ba))))

}

 

@media (prefers-reduced-motion: reduce) {

.a3d { animation-duration: 128s }

}

 

/* ====== General page prettifying and layout ====== */

html, body { display: grid }

 

html { height: 100% }

 

body { background: #fff3ed }

 

 

Comments