강의 출처 : Memory Cards | CSS Effects, Local Storage - Brad Traversy
카드의 앞 뒤 면을 뒤집을 수 있는 3D 효과 구현하기.
아래의 카드를 클릭하면,
카드의 뒷면이 나오는 효과.
코드는 아래와 같다.
HTML
<h1>
Memory Cards
<button id="show" class="btn btn-small">
<i class="fas fa-plus"></i> Add New Card
</button>
</h1>
<div id="cards-container" class="cards">
</div>
<div class="navigation">
<button id="prev" class="nav-button">
<i class="fas fa-arrow-left"></i>
</button>
<p id="current"></p>
<button id="next" class="nav-button">
<i class="fas fa-arrow-right"></i>
</button>
</div>
CSS
.cards {
perspective: 1000px;
position: relative;
height: 300px;
width: 500px;
max-width: 100%;
}
.card {
position: absolute;
opacity: 0;
font-size: 20px;
top: 0;
left: 0;
height: 100%;
width: 100%;
transform: translateX(50%) rotateY(-10deg);
transition: transform 0.4s ease, opacity 0.4s ease;
}
.card.active {
cursor: pointer;
opacity: 1;
z-index: 10;
transform: translateX(0) rotateY(0deg);
}
.inner-card {
box-shadow: 0 1px 10px rgba(0, 0, 0, 0.3);
border-radius: 4px;
height: 100%;
width: 100%;
position: relative;
transform-style: preserve-3d;
transition: transform 0.4s ease;
}
.card.show-answer .inner-card {
transform: rotateX(180deg);
}
.inner-card-front,
.inner-card-back {
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
width: 100%;
background: #fff;
}
.inner-card-front {
transform: rotateX(0deg);
z-index: 2;
}
.inner-card-back {
transform: rotateX(180deg);
}
.inner-card-front::after,
.inner-card-back::after {
content: "\f021 Flip";
font-family: "Font Awesome 5 Free", Lato, sans-serif;
position: absolute;
top: 10px;
right: 10px;
font-weight: bold;
font-size: 16px;
color: #ddd;
}
JS
const cardsData = [{question:"What is PHP?", answer: "Programming Language"}];
// Create all cards
function createCards() {
cardsData.forEach((data, index) => createCard(data, index));
}
// Create a single cards in DOM
function createCard(data, index) {
const card = document.createElement("div");
card.classList.add("card");
if (index === 0) {
card.classList.add("active");
}
card.innerHTML = `
<div class="inner-card">
<div class="inner-card-front">
<p>${data.question}</p>
</div>
<div class="inner-card-back">
<p>${data.answer}</p>
</div>
</div>
`;
card.addEventListener("click", () => card.classList.toggle("show-answer"));
// Add to DOM cards
cardsEl.push(card);
cardsContainer.appendChild(card);
updateCurrentText();
}
// Show number of cards
function updateCurrentText() {
currentEl.innerText = `${currentActiveCard + 1}/${cardsEl.length}`;
}
createCards();
3D - 카드를 위아래로 뒤집는 효과를 만들기 위한 핵심포인트는 perspective와 trasform-style, backface-visibility, rotateX이다.
.cards{ perspective : 1000px}
.inner-card {transform-style: preserve-3d;}
.card.show-answer .inner-card {
transform: rotateX(180deg);
}
.inner-card-front,
.inner-card-back {
backface-visibility: hidden;}
.inner-card-front{transform: rotateX(0);}
.inner-card-back{transform: rotateX(180deg);}
큰 container인 cards의 perspective를 설정함으로써 3d효과를 준다.
perspective는 깊이감을 표현하는 속성으로 Z축의 변화를 보여준다.
값이 낮을수록 가까이에서 보는 느낌을 주는데 즉, 3D 효과가 더 부각된다.
자식요소인 .inner-card의 transform-style을 preserve-3d를 설정함으로써 3d공간 배치를 한다.
transform-style은 자식요소를 3d공간에 배치시킬 것인지, 평평하게 배치시킬 것인지를 정한다.
.inner-card-front와 .inner-card-back에서 backface-visibility: hidden을 함으로써 뒷면을 보이지 않게끔 해준다.
CSS backface-visibility 속성은 요소의 뒷면이 사용자를 향할 때 보여야 하는지 지정한다.
.card에 show-answer class 여부에 따라 x축의 rotate 각도가 바뀌는 로직이다.