2024-04-24|閱讀時間 ‧ 約 25 分鐘

使用 CSS 製作簡單的 Flip Card

最近在練習使用 CSS 來製作一些簡單的動畫,以下是我收集資料與實作的成果。

製作一張可以水平翻轉的卡片,這邊會使用 Vue.js 來簡化邏輯,主要是解釋 CSS 的部分。


首先,一張卡片會有正面與反面,程式碼的寫法會是:

<div class="flip-card">
<div class="flip-card-inner">
<div class="flip-card-front">
<button class="flip-card-btn">flip</button>
<h2>Front</h2>
</div>
<div class="flip-card-back">
<button class="flip-card-btn">flip</button>
<h2>Back</h2>
</div>
</div>
</div>

接下來就要設定 CSS:

/* 設定轉動時透視狀態 */
.flip-card {
perspective: 1000px;
}
/* 卡片以 3D 方式呈現 */
.flip-card-inner {
position: relative;
&nbsp; transform-style: preserve-3d;
&nbsp; transition: transform 1s;
&nbsp; transition-timing-function: ease-in-out;
}
/* 卡片翻轉 */
.flip-card-inner.flipped {
transform: rotateY(180deg);
transition: ease-in-out 1s;
}
/* 卡片內容樣式設定 */
.flip-card-front,
.flip-card-back {
position: absolute;
top: 0;
right: 0;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden; /* Safari */
backface-visibility: hidden;
}
/* 卡片背面翻轉 */
.flip-card-back {
transform: rotateY(180deg);
}

以下會說明每個 CSS 屬性存在的目的,如果沒有特殊的情境,每個屬性都只會解釋一次,裡面的數值可根據自己需求改變。

Flip Card

perspective:是 Transform 3D 會用到的屬性,表示 Z軸到觀看者之間的距離。數值越小越容易會有翻轉失真的問題,這是因為觀測者與卡片距離太相近,導致卡片翻轉時超出了觀測者的範圍,所以這邊設定 1000px (可以試著將數值調低來觀看差異)

Flip Card Inner

這裡會把 .flip-card-inner 和 .flip-card-inner.flipped 放在一起說:

.flip-card-inner

  • transform-style: preserve-3d 將這個元件保留在 3D 空間中
  • transition:翻轉的方式會參照 .flip-card-inner.flipped 裡 transform 的設定
  • transition-timing-function:動畫過渡的方式

.flip-card-inner.flipped

  • transform: rotateY(180deg):當觸發翻轉時,會水平翻轉 180 度
  • transition:動畫過渡的方式與時間

Flip Card Front & Back

backface-visibility: hidden;:是將卡片背面的物件隱藏。也因為現在是在 3D 空間下,所以可以看到多出一個 .flip-card-back 裡的設定,這就是將內容設定成卡背的方式

這邊要特別注意,為什麼使用 position: absolute?這是因為backface-visibility 是將卡片背後的內容 hidden,這表示這個元素還是存在,如果不使用 absolute 在卡片翻過去背面後,卡片正面的內容雖然消失但依舊會佔據原本的位置

flip-card-no-absolute

Logic

以 Vue 來說很簡單,只要設定一個 Reactive State 就可以解決:

const isFlipped = ref(false);

const flipCard = () => {
isFlipped.value = !isFlipped.value;
};

再將這個 flipCard 函式套用在想與之互動的方式上(可以是 hover 之類的,這裡我用 button):

<button class="flip-card-btn" @click="flipCard()">
flip
</button>
分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.