9 transform
1. 개요
CSS의 transform 속성은 요소의 2D 또는 3D 변환을 적용합니다. 이 변환은 요소의 크기, 위치, 회전 등을 변경할 수 있습니다.
2. 기본문법
2.1. 2D
| 함수 | 설명 |
|---|---|
translate(x, y) | 요소를 x축과 y축을 따라 이동시킵니다. |
rotate(angle) | 요소를 주어진 각도만큼 회전시킵니다. |
scale(x, y) | 요소의 크기를 조정합니다. |
skew(x-angle, y-angle) | 요소를 기울입니다. |
matrix(n,n,n,n,n,n) | 2D 변환을 위한 행렬입니다. translate, scale, rotate 등을 한 번에 적용할 수 있습니다. |
transform-origin | 변환 요소의 기준점을 설정합니다. transform-origin: x y z; 형태로 사용하며, x, y는 좌표를 지정하고, z는 깊이를 지정합니다. |
2.2. 3D
| 속성/함수 | 설명 |
|---|---|
translate3d(x, y, z) | 요소를 x, y, z축을 따라 이동시킵니다. |
rotate3d(x, y, z, angle) | 3차원 공간에서 요소를 회전시킵니다. x, y, z는 회전축을 정의하고, angle은 회전 각도를 정의합니다. |
scale3d(x, y, z) | 요소의 크기를 3차원 공간에서 조정합니다. (다른 3차원 트랜스폼이 없는 경우 특별히 스케일링할 것이 없기 때문에 가시적인 효과를 얻을수 없습니다.) |
perspective(n) | 요소에 원근법 변환을 적용합니다. n 값은 시점의 거리를 정의하며, 작은 값일수록 더 강한 원근 효과를 나타냅니다. |
matrix3d(n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n) | 3D 변환을 위한 4x4 행렬입니다. translate3d, scale3d, rotate3d 등을 한 번에 적용할 수 있습니다. |
transform-origin | 변환 요소의 기준점을 설정합니다. transform-origin: x y z; 형태로 사용하며, x, y는 좌표를 지정하고, z는 깊이를 지정합니다. |
perspective-origin | 원근법 변환의 시점을 설정합니다. perspective-origin: x y; 형태로 사용하며, x, y는 좌표를 지정합니다. |
2.2.1. perspective
- Perspective 값이 크면 멀어서 작게, 작으면 가까워서 크게보임. (값은 0보다 커야함)
- 사람의 시지각은 멀리 떨어진 사물은 작게, 가까이 있는 사물은 크게 보인다.
2.2.2. perspective-origin
사용자의 시선 위치를 조정하여 소실점적용
3. 응용예제
3.1. 다양한 transform
- 코드
- HTML
- CSS
1<div class="transform_container">2 <div class="origin">3 <div class="rotatex"></div>4 </div>5 <div class="origin">6 <div class="rotatey"></div>7 </div>8 <div class="origin">9 <div class="rotatez"></div>10 </div>11 <div class="origin">12 <div class="rotatexyz"></div>13 </div>14</div>시작
1.transform_container {2 width: 800px;3 margin: 20px auto;4}5.origin {6 width: 100px;7 height: 100px;8 margin: 40px;9 border: 1px solid black;10 display: inline-block;11}12.origin > div {13 width: 100px;14 height: 100px;15 background-color: orange;16 transition: all 3s; /* 3초 동안 회전하도록 트랜지션 적용 */17}STEP1
1.rotatex:hover {2 transform: rotateX(55deg); /* x축으로 55도 회전 */3}4.rotatey:hover {5 transform: rotateY(55deg); /* y축으로 55도 회전 */6}7.rotatez:hover {8 transform: rotateZ(55deg); /* z축으로 55도 회전 */9}10.rotatexyz:hover {11 transform: rotate3d(0, 1.2, -1.5, 55deg); /* x,y,z축으로 55도 회전 */12}3.2. 예제: 회전하는 코알라
- 예제
- HTML
- CSS
backface 미리보기
1<div class="transform_container">2 <img src="http://qwerew.cafe24.com/images/koala1.png" alt="icon" />3</div>1.transform_container {2 width: 200px;3 margin: 30px auto;4}5img {6 width: 100%;7 border: 1px solid #ccc;8 border-radius: 50%;9 box-shadow: 5px 5px 63px 2px #00000040;10 animation: rotateAnimal 2.5s infinite alternate; /* rotateAnimal 애니메이션 2.5초 동안 실행. 무한 반복 */11 animation-play-state: paused;12 animation-fill-mode: forwards;13}14img:hover {15 animation-play-state: running;16}17@keyframes rotateAnimal {18 from {19 transform: perspective(200px) rotateY(0deg);20 }21 50% {22 transform: perspective(200px) rotateY(-180deg);23 }24 to {25 transform: perspective(200px) rotateY(-360deg);26 }27}-
transform: perspective(200px)VSperspective:200px둘다 3D 공간의 z축 깊이를 설정한다
- 문법이 다르다
transform: perspective(200px): transform 속성에 값으로 작성하는 방식 다른 transform 속성과 함께 사용시 띄어쓰기로 구분하여 작성해야 한다.perspective:200px: perspective 속성에 값을 작성하는 방식
- 선언 대상이 다르다
transform: perspective(200px): 원근감을 적용할 요소에 직접 작성perspective:200px: 원근감을 적용할 요소의 부모요소에 작성
- 문법이 다르다
3.2.1. 예제: 카드뒤집기
- 예제
- HTML
- CSS
1<div class="card">2 <div class="front"><span>A♥</span> ♥ <span>A♥</span></div>3 <div class="back">뒤집어🐨</div>4</div>1body {2 font-size: 200%;3 margin: 100px;4 color: #eee;5 background-color: #fafafa;6}7div.card {8 width: 176px;9 height: 246px;10 margin: 0 auto;11 cursor: pointer;12}13div.card div {14 position: absolute;15 width: 160px;16 height: 230px;17 font-size: 2em;18 text-align: center;19 line-height: 230px;20 color: #c00;21 background-color: #fff;22 border-radius: 5px;23 box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.5), 2px 2px 35px rgba(0, 0, 0, 0.1);24 transition: all 1s ease;25}26div.card div span {27 position: absolute;28 left: 0;29 top: 0;30 font-size: 0.5em;31 width: auto;32 line-height: 1em;33}34div.card div span:last-child {35 left: auto;36 top: auto;37 right: 0;38 bottom: 0;39 transform: rotate(180deg);40}41div.card div.back {42 font-size: 0.8em;43 color: #fff;44 background: #36c;45}46
47div.card {48 perspective: 400px;49}50div.card div {51 backface-visibility: visible;52 backface-visibility: hidden;53}54div.card div.back {55 transform: rotateY(0deg);56}57div.card div.front {58 transform: rotateY(-180deg);59}60div.card:hover div.back {61 transform: rotateY(-180deg);62}63div.card:hover div.front {64 transform: rotateY(0deg);65}backface-visibility- 요소의 뒷쪽에서 앞면이 보이게 할지 정하는 속성- 값:
visible | hidden | initial | inherit
3.3. 예제 hover시 커지는 이미지
- 코드
- HTML
- CSS
1<div class="transform_container">2 <img src="https://qwerew.cafe24.com/images/1.jpg" />3 <span> 트랜스폼 알아보기 </span>4</div>시작
1div.transform_container {2 width: 50%;3 margin: 200px auto;4}5div.transform_container img {6 transition: all 0.35s;7 width: 100%;8}STEP1 [transform3D적용]
1div.transform_container:hover img {2 div.transform_container {3 perspective: 1000px;4 border: 1px solid;5 }6 transform: translate3D(100px, 100px, 200px);7}STEP2 [perspective-origin]
1div.transform_container {2 perspective: 500px;3 perspective-origin: 50% 50%;4}5div.transform_container:hover img {6 transform: translate3D(0px, 0px, 200px);7}STEP3 [scale]
translateZ와 함께 사용
1div {2 perspective-origin: 0px 10px;3}4div img {5 transform: scaleZ(1);6}7
8div:hover img {9 transform: translateZ(200px) scaleZ(5);10}3.4. 마우스위치에 대응하는 애니메이션
- 코드
- HTML
- CSS
- JS
1<div id="top">2 <div class="perspective">3 <div class="card">4 <div class="thumb"></div>5 <h2>코알라 만져보고 싶어요</h2>6 <span>코알라 너무 좋아</span>7 </div>8 </div>9</div>1@import url(https://qwerewqwerew.github.io/source/style/reset.css);2body {3 background: linear-gradient(to right, #ffffff, #f8dce2);4 color: #fff;5 display: flex;6 align-items: center;7 justify-content: center;8 height: 100vh;9 font-family: 'Pretendard';10}11
12.perspective {13 width: 100%;14 perspective: 1000px;15}16
17#top {18 width: 100%;19 height: 100%;20 display: flex;21 align-items: center;22 justify-content: center;23 margin: auto;24}25
26.card {27 width: 270px;28 height: 413px;29 margin: auto;30 box-shadow: 0 70px 63px -60px #494848;31 transform-style: preserve-3d;32 transition: transform 0.05s linear;33}34
35.card .thumb {36 background: #e99fb6 url(https://qwerew.cafe24.com/images/koala1.png) center center;37 background-size: 150px;38 height: 100%;39 width: 100%;40 border-radius: 15px;41}42
43.card .thumb:after {44 background: inherit;45 content: '';46 display: block;47 position: absolute;48 left: -60px;49 top: 40px;50 width: 100%;51 height: 108%;52 z-index: -1;53 filter: blur(55px);54}55
56.card h2 {57 position: absolute;58 top: 0;59 left: -60px;60 font-size: 40px;61 font-weight: 900;62 color: transparent;63 transform: translateZ(80px);64 background: linear-gradient(to right, #e98b89, #547fc0);65 -webkit-background-clip: text;66 -webkit-text-fill-color: transparent;67}68
69.card span {70 position: absolute;71 bottom: 40px;72 right: -280px;73 font-size: 37px;74 font-weight: 600;75 transform: translateZ(35px);76}77
78img {79 margin: auto;80 display: block;81 border-radius: 15px;82}1var o = $('.card');2var o2 = $('h2');3$('#top').on('mousemove', function (t) {4 console.log(t);5 var e = -($(window).innerWidth() / 2 - t.pageX) / 30,6 n = ($(window).innerHeight() / 2 - t.pageY) / 10;7 o.attr('style', `transform: rotateY(${e}deg) rotateX(${n}deg)`);8 o2.attr({ style: `transform: rotateY(${e * 0.5}deg) rotateX(${n}deg) translateZ(20px) translateX(${n * 1.5}px)` });9});3.5. 3차원 공간에서 회전하는 이미지
3.5.1. css 버전
- 코드
- HTML
- CSS
가로, 세로 200픽셀인 8장의 사진을 이용해 Y축을 기준으로 회전하 는 애니메이션을 제작하고 클릭하면 멈추도록 효과 적용
스타일에 변수를 이용해 순서대로 숫자로 지정 html 에 작성한 변수는 아래처럼 동작한다
1<!-- .box>(span>img)*8 -->2
3<div class="box">4 <span style="--i: 1"><img src="imgs/1.jpg" alt="" /> </span> <span style="--i: 2"><img src="imgs/2.jpg" alt="" /> </span> <span style="--i: 3"><img src="imgs/3.jpg" alt="" /></span> <span style="--i: 4"><img src="imgs/4.jpg" alt="" /></span> <span style="--i: 5"><img src="imgs/5.jpg" alt="" /></span> <span style="--i: 6"><img src="imgs/6.jpg" alt="" /></span> <span style="--i: 7"><img src="imgs/7.jpg" alt="" /></span> <span style="--i: 8"><img src="imgs/8.jpg" alt="" /></span>5</div>mdn “body”를 플렉스로 지정하고 배경은 방사형그레디언트를 적용한 후 스크롤했을 때 고정되도록 “background-attachment” 속성 값 을 “fixed”로 지정한다.
transform-style: 3차원 공간에서 요소(element)의 공간에 표시 또는 평면적으로 표시 할지 결정한다.
transform-style: flat;평면으로 표시transform-style: preserve-3d;공간으로 표시8개의 이미지는
span태그에 인라인스타일 속성값으로 커스텀스타일을 적용 하고 값은 “1”부터 “8”까지의 숫자로 정의되어 있으므로img1은 Y축으로 45 도 회전하고 Z축으로 400픽셀이동되어 표시되면 입체적으로 보여진다.
1* {2 margin: 0;3 padding: 0;4 box-sizing: border-box;5}6body {7 display: flex;8 justify-content: center;9 height: 2000px;10 background: radial-gradient(#2c5364, #0f2027);11 background-attachment: fixed;12}13.box {14 position: relative;15 top: 30vh;16 width: 200px;17 height: 200px;18 transform-style: preserve-3d;19 animation: animate 20s linear infinite;20}21@keyframes animate {22 0% {23 transform: perspective(1000px) rotateY(0deg);24 }25 100% {26 transform: perspective(1000px) rotateY(360deg);27 }28}29.box span {30 position: absolute;31 top: 0;32 left: 0;33 width: 100%;34 height: 100%;35 transform-origin: center;36 transform-style: preserve-3d;37 transform: rotateY(calc(var(--i) * 45deg)) translateZ(400px);38 -webkit-box-reflect: below 0px linear-gradient(transparent, transparent, #0009);39}40.box span img {41 position: absolute;42 top: 0;43 left: 0;44 width: 100%;45 height: 100%;46 object-fit: cover;47}48.item {49 position: fixed;50 left: 0;51 width: 300px;52 height: 300px;53 background-color: #fff;54}3.5.2. js 버전
- 코드
- html
- js
1<div class="box">2 <span><img src="imgs/1.jpg" alt="" /></span><span><img src="imgs/2.jpg" alt="" /></span><span><img src="imgs/3.jpg" alt="" /></span><span><img src="imgs/4.jpg" alt="" /></span><span><img src="imgs/5.jpg" alt="" /></span><span><img src="imgs/6.jpg" alt="" /></span><span><img src="imgs/7.jpg" alt="" /></span><span><img src="imgs/8.jpg" alt="" /></span>3</div>4<script src="1.js"></script>1const span = document.querySelectorAll('span');2span.forEach((el, idx) => {3 el.setAttribute('style', `--i:${idx - 1}`);4});3.6. 추가예제
| 제목1 | 제목2 |
|---|---|
| 01-perspective | [01-perspective ](https://qwerewqwerew.github.io/source/css/2-transform/step0/01-perspective.html ) |
| 02-perspective() | 02-perspective() |
| 03-translatez | [03-translatez ](https://qwerewqwerew.github.io/source/css/2-transform/step0/03-translatez.html ) |
| 04-perspective-origin | 04-perspective-origin |
| 05-preserve-3d | [05-preserve-3d ](https://qwerewqwerew.github.io/source/css/2-transform/step0/05-preserve-3d.html ) |
| 06-playing-card | 06-playing-card |
| 07-rotate-x-rotate-y | 07-rotate-x-rotate-y |
| 08-rotate3d.htm | [08-rotate3d.htm ](https://qwerewqwerew.github.io/source/css/2-transform/step0/08-rotate3d.htm ) |
| 09-rotate3d-2 | 09-rotate3d-2 |
| 10-translate3d | 10-translate3d |
| 11-scalez | [11-scalez ](https://qwerewqwerew.github.io/source/css/2-transform/step0/11-scalez.html ) |
| 12-3d-cube | [12-3d-cube ](https://qwerewqwerew.github.io/source/css/2-transform/step0/12-3d-cube.html ) |
| 13-animated-3d-cube | 13-animated-3d-cube |