시작 오늘 분석할 코드
겉보기엔 똑같아 보이는 두 개의 컨테이너. 안쪽 box1·box2 구조도 같다. 차이는 box1에 적용된 transform-style이 flat인가 preserve-3d인가 단 한 줄. 이 한 줄이 자식 box2의 3D 회전을 살리느냐 죽이느냐를 결정한다.
.container { border: 1px solid black; perspective: 300px; margin-top: 100px; margin-left: 100px; float: left; } .box1 { background: #82cbd8; transform: rotateY(45deg); } .box2 { background: #0d6097; transform-origin: left top; transform: rotateX(45deg); } #tr-style1 { transform-style: flat; } #tr-style2 { transform-style: preserve-3d; } <div class="container"> <div class="box1" id="tr-style1"> <div class="box2"></div> </div> </div>
실제 출력 미리보기 (왼쪽 = flat, 오른쪽 = preserve-3d)
preserve-3d — box2가 자기 X축으로 따로 회전
용어 용어 정리
transform-style자식의 3D 변환을 어떻게 처리할지
flat (기본)자식이 부모 평면에 납작하게 합쳐짐
preserve-3d자식이 자기만의 3D 공간을 유지
perspective시청자~요소 사이 거리 (원근감)
rotateX가로축 회전 — 위아래 뒤집힘
rotateY세로축 회전 — 좌우 뒤집힘
transform-origin변환의 기준점 (기본: 중심)
left top왼쪽 위 모서리를 기준점으로
1 왜 transform-style이 필요한가?
기본 동작은 "납작하게 합치기"다
CSS는 기본적으로 자식 요소가 3D 변환을 해도 부모 평면에 투영해서 그린다. 자식이 회전해도 부모가 보기엔 그냥 평면 그림이라는 뜻. 이게 flat이다.
이 기본을 깨고 자식의 3D를 그대로 살리려면 부모에 transform-style: preserve-3d를 줘야 한다.
flat (기본): parent (회전됨) └ child (회전 시도) → "부모 평면" 위 그림으로 합쳐짐 (자식의 3D는 사라짐) preserve-3d: parent (회전됨) └ child (회전) → 자식이 자기 3D 공간에서 회전 (부모와 자식이 별도 평면)
2 두 컨테이너의 결과가 다른 이유
box1: rotateY(45deg) — 컨테이너 안에서 Y축으로 45도
두 box1 모두 Y축으로 45도 돈다. 컨테이너의 perspective 덕분에 약간 좌우가 기울어져 보인다. 여기까지는 둘 다 동일.
box2: rotateX(45deg) — 차이가 발생하는 지점
box2는 box1의 자식이다. 그래서 box1의 transform-style이 결정적이다.
| box1 설정 |
box2 회전 |
결과 |
flat |
rotateX(45deg) |
box1 평면에 그림처럼 그려짐 — 위아래로 좁아질 뿐 진짜 회전 안 보임 |
preserve-3d |
rotateX(45deg) |
box2가 자기 X축으로 진짜 회전 — 윗변이 멀어지는 입체감 |
3 transform-origin: left top의 의미
왜 이 코드의 box2는 왼쪽 위에서 회전하나?
transform-origin은 변환의 기준점이다. 기본은 요소의 정중앙(50% 50%). left top으로 바꾸면 왼쪽 위 모서리를 축으로 회전한다.
기본 (center): * * | | | 회전 | ← 가운데 핀이 박혀 회전 | | * * left top: *━━━━━* | | 회전 | ← 왼쪽 위 모서리에 핀 ↓ |
이 코드에선 box2의 회전 효과가 왼쪽 위에서 시작해 오른쪽 아래로 펼쳐지는 모양이 된다. 책의 모서리를 잡고 들어 올린 듯한 느낌.
4 perspective는 부모에 줘야 한다
.container에 perspective: 300px
3D 효과의 원근감은 변환되는 요소의 부모(또는 조상)에 perspective를 줘야 작동한다. 이번 코드는 .container에 줬다.
※ 만약 .box1 자체에 perspective를 주면 box1에는 효과가 없고 box2에만 영향. 즉 perspective는 항상 "한 단계 위"에 둔다고 기억하면 된다.
※ 또는 transform 함수 안에 perspective(300px)로 줄 수도 있다 (이전 예제 참고). 이 경우 그 요소 자체에만 적용된다.
5 어떤 상황에 preserve-3d를 쓰나?
flat 적합
- 단일 요소만 3D로 회전
- 안쪽 자식은 그냥 따라가면 충분
- 호버 카드 1장 뒤집기
- 성능 측면 부담 적음
preserve-3d 필요
- 3D 카드 양면 (앞/뒤가 다른 면)
- 큐브, 캐러셀 회전
- 자식들이 각자 다른 3D 회전
- 중첩된 3D 구조
6 자식까지 perspective를 적용하려면
preserve-3d의 진짜 의미는 "부모의 perspective를 자식에게도 전달"하는 것이다. flat은 부모에서 끊고, preserve-3d는 통과시킨다.
.container [perspective: 300px] └ .box1 [transform-style: preserve-3d] → "통과" └ .box2 [rotateX(45deg)] ← perspective 적용된 3D로 보임 vs .container [perspective: 300px] └ .box1 [transform-style: flat (기본)] → "차단" └ .box2 [rotateX(45deg)] ← 그냥 평면 위 합성 그림
7 자주 하는 실수
| 실수 |
증상 |
해결 |
| 변환되는 요소 자체에 perspective |
원근감이 안 보임 |
부모 또는 함수 형태로 사용 |
| preserve-3d를 안 줘서 자식 3D가 죽음 |
중첩 3D가 평면처럼 보임 |
중간 부모에 transform-style: preserve-3d |
| preserve-3d 부모에 overflow: hidden |
3D 공간이 잘려 평면화 |
overflow 제거 또는 별도 wrapper |
| rotateY와 rotateX 혼동 |
의도와 다른 축으로 회전 |
X=가로축, Y=세로축 |
| transform-origin을 깜빡함 |
회전이 항상 중심 기준 |
모서리 회전은 left top 등 명시 |
8 원본의 -webkit-transform 값 차이
잘 보면 원본 코드의 .box1 CSS에는 다음과 같은 차이가 있다.
-webkit-transform:rotateY(45deg); -moz-transform:rotate(45deg); ← 여기만 rotate(2D)! -o-transform:rotateY(45deg); -ms-transform:rotateY(45deg); transform: rotateY(45deg);
※ 원본의 의도하지 않은 오타로 보이는 부분. 파이어폭스(-moz-)에선 2D 평면 회전, 다른 브라우저에선 Y축 3D 회전으로 다르게 보일 수 있다. 모두 rotateY(45deg)로 통일하는 게 맞다.
핵심 한 줄 요약
transform-style자식의 3D를 살릴지 평면화할지 결정
flat (기본)자식이 부모 평면 위 그림처럼 합쳐짐
preserve-3d자식이 자기 3D 공간 유지
perspective변환되는 요소의 부모에 부여
transform-origin변환의 기준점 — 기본 중심, left top 등
중첩 3D큐브·카드 양면 구조 시 preserve-3d 필수
overflow:hidden 주의preserve-3d 영역에 적용하면 3D 죽음
Tags
#transform-style #flat #preserve-3d #perspective #transform-origin #3D공간 #중첩3D #큐브 #카드플립 #backface-visibility #CSS3 #3D변환 #웹개발 #HTML #티스토리
▼ 티스토리 태그 입력란 복사용
transform-style, flat, preserve-3d, perspective, transform-origin, 3D공간, 중첩3D, 큐브, 카드플립, backface-visibility, CSS3, 3D변환, 웹개발, HTML, 티스토리
댓글