[css] css 3D

한지원·2021년 1월 28일
0

유튜브 1분 코딩의 css3D시크릿 강의영상을 참고하였습니다.

transform | perspective

transform-fonction mdn
html

<body>
	<div class="stage">
		<div class="box">BOX</div>
	</div>
</body>

css

.stage {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100vw;
  height: 100vh;
  perspective: 400px; /*transform원근 조절해주는것*/
}

.box {
  width: 50px;
  height: 70px;
  background: blanchedalmond;
  transform: rotateY(50deg); /*Y축 기준으로 50도 회전*/
}

transform: rotateY(50deg) 는 box가 Y축으로 50도 회전하는 것을 나타내고
perspective: 400px은 박스의 원근을 나타낸다. 숫자가 작을 수록 가까이에 있는 것이고 왜곡이 커진다.

이 때 박스의 수를 늘려보자.

<body>
	<div class="stage">
		<div class="box">BOX1</div>
		<div class="box">BOX2</div>
	</div>
</body>

박스의 수를 늘리고 다시한번 실행을 시켜보면 box1과 box2의 모양에 약간의 차이가 있음을 알 수 있다. css에서 perspective를 부모요소인 stage에 적용시켰기 때문인데 이것을 자식에게 옮겨주면 박스의 왜곡된 모양이 같아진다.

.stage {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100vw;
  height: 100vh;
}

.box {
  width: 50px;
  height: 70px;
  background: blanchedalmond;
  transform: perspective(400px) rotateY(50deg);
}

다시 박스 하나로 돌아와서
자바스크립트를 이용해 박스를 클릭할 시 box가 뒤집어지는 이벤트를 추가하자.
js

var box = document.querySelector('.box');
box.addEventListener('click', function(){
	document.body.classList.toggle('flipped');
})

css

.box {
  width: 50px;
  height: 70px;
  background: blanchedalmond;
  /* transform: rotateY(0deg); */
  transition: 1s;
}

.flipped .box {
  transform: rotateY(180deg);
}

javascript에서 flipped 클래스를 box가 아닌 body에 넣은 이유는 transform을 적용시키고자 하는 다른 요소가 있는 등 다른 효과들을 더 추가하고 싶을 때 코드의 수정을 최소화시킬 수 있기 때문이다.
예를 들어 박스가 뒤집힐 때 background-color도 변경되게 하고싶다면 css에

.flipped {
  background-color: black;
}

만 추가해주면 된다.

회전하는 축을 지정하기

transform-origin

transform-origin mdn
transform-origin: x축위치 y축위치

.box {
  width: 50px;
  height: 70px;
  background: blanchedalmond;
  transform: rotateY(0deg);
  transform-origin: right top; /*여기선 top생략 가능*/
  transition: 1s;
}

.flipped .box {
  transform: rotateY(180deg);
}

앞면과 뒷면의 내용을 달리하고싶을 때
두개의 box를 생성한 뒤 하나는 180도 회전시켜주고 두 박스의 포지션을 같게 하여 하나의 위치에 포개어 준다.

위의 css코드에서 perspective 속성을 stage 클래스에 넣어줬는데 이렇게되면 stage의 자식 요소인 box에만 적용이 되고 box의 자식 요소에는 적용이 안된다.

이럴 땐 box클래스의 자식요소에도 3d 효과를 보존시켜주기 위해 box클래스에 transform-style: preserve-3d를 넣어준다.
html

	<div class="stage">
		<div class="box">
			<div class="box-side front">Front</div>
			<div class="box-side back">Back</div>
		</div>
	</div>

css

.box {
  position: relative;
  width: 50px;
  height: 70px;
  background: blanchedalmond;

  transform: rotateY(0deg);
  transform-style: preserve-3d;
  transition: 1s;
}

.flipped .box {
  transform: rotateY(180deg);
}

.box-side {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}

.front {
  background: blanchedalmond;
}

.back {
  background: slateblue;
  color: white;
  transform: rotateY(180deg);
}

변화를 확인하기 위해 위의 코드에서 back의 transfrom: rotateY(180deg)부분만 아래처럼 잠깐 바꿔보았다.

.back {
  background: slateblue;
  color: white;
  transform: rotateY(40deg);
}

각 박스의 뒷모습은 안보이게 해주기
backface-visibility: hidden
두개의 카드에 모두 포함된 클래스인 box-side에 해당 속성을 추가해준다.

영상에서는 위의 코드를 추가하기 전에 카드가 뒤집힐 때 두 면이 빠르게 번갈아 보여지는 현상이 있었는데 영상으로부터 2년이 지난 현재는 따로 추가해주지 않아도 별 문제가 없다.

심지어 값을 visible로 설정해주어도 아무문제가 안나타난다. 뭘까

인줄 알았으나 확대해서 보니 visible에서는 미세하게 back의 색이 보인다.

z축 이동

transform: translateZ()
괄호 안에는 원하는 크기 넣어주기

응용

앞에서 공부한 기능을 이용하여 입체적인 로그인 박스를 만들어 볼 것이다.(간단히)

우연히 강의 영상을 보게되었는데 2년 전이지만 프로젝트를 할 때 넣어보고 싶은 재미있는 요소들에 대한 설명이 많아서 굉장히 유익했다.
재밌당

0개의 댓글