想起「少年賭神在賭桌上翻開撲克牌的一角,後面神眼朱老九偷看牌
」的橋段,那種翻不壞的撲克牌真令我著迷,心想如果用純 CSS 來做個翻牌效果,當年的賭神應該就是我了吧!( 想太多 ) 不過說正經的,這個效果是我在逛 Codepen 的時候看到的,但再回首已經找不到,就像那份逝去的初戀一樣~ 當初覺得沒有寫得很好,就重寫一個並使用 em
相對單位,翻牌效果就能適應不同的文字大小囉!
這篇教學會單純透過「虛擬元素」和「屬性值」來簡化程式碼,搭配「em」相對長度單位,讓翻牌效果適應各種大小文字,並透過 3D 轉換、變形、動畫樣式等互相搭配,產生與眾不同的 CSS 製作字母翻牌效果。
字母翻牌效果要產生「翻轉的字母」和「下方陰影」,為了讓程式碼更為簡潔 ( 只寫一次字母 ),可以透過虛擬元素選擇器 ::before
和 ::after
來讀取元素屬性,讀取屬性後根據預設的排列順序,將 ::before
當作陰影,將 ::after
作為字母,詳細說明可以參考範例的註解。
- 虛擬元素是 CSS 裡唯一可以使用
attr
讀取元素屬性 ( 現在部分瀏覽器已經讓attr
支援全樣式囉 ),並透過content
顯示屬性內容的選擇器,參考:虛擬元素選擇器 ( 偽元素 )、content 搭配 attr()。- 線上展示:https://codepen.io/oxxo/pen/mydqrjM
<!-- HTML 程式碼 -->
<h2 text="A"></h2>
<h2 text="B"></h2>
<h2 text="C"></h2>
<!-- CSS 程式碼 -->
<style>
body {
background: #888;
padding: 50px;
}
h2 {
position: relative;
margin: 0;
padding: 0;
font-size: 150px; /* 文字尺寸會繼承到子元素和虛擬元素 */
line-height: 0.8; /* 文字行高會繼承到子元素和虛擬元素 */
}
h2::before, h2::after {
content: attr(text); /* 讀取並顯示元素的 text 屬性 */
top: 0;
}
h2::before {
position: relative; /* 因為元素本身沒有內容,使用 relative 讓虛擬元素撐開元素 */
left: 5px; /* 陰影稍微位移 */
color: #000; /* 陰影顏色黑色 */
}
h2::after {
position: absolute; /* 因為翻轉時會改變尺寸,所以使用 absolute 使其不會影響尺寸,並蓋在陰影上方 */
left: 0;
color: #fff; /* 文字白色 */
}
</style>
如果將剛剛的虛擬元素 ::after
套用 CSS 的 transform
,讓字母圍繞 Y 軸旋轉後,就能做出「字母翻轉」的效果,實際操作時必須搭配 3D 變換轉用的樣式 perspective
、perspective-origin
、transform-style
和 transform-origin
,才能做到逼真的翻轉效果,詳細說明可參考下方範例註解。
<!-- HTML 程式碼 -->
<!-- 注意有額外使用 class 為 camera 的 div 包覆 h2-->
<div class="camera"><h2 text="A"></h2></div>
<div class="camera"><h2 text="B"></h2></div>
<div class="camera"><h2 text="C"></h2></div>
<!-- CSS 程式碼 -->
<style>
body {
background: #888;
padding: 50px;
}
.camera {
display: inline-block; /* 幫助排版,看自己需求也可以移除這行 */
font-size: 150px; /* 字體大小移動到這裡,為了讓 perspective:3em 有參考依據 */
line-height: 0.8; /* 行高跟隨字體大小移動到這邊 */
perspective-origin: 50% 50%; /* 攝影機中心點對齊中心 */
perspective: 3em; /* 攝影機透視距離為 3em = 150px x 3 */
}
h2 {
position: relative;
margin: 0;
padding: 0;
cursor: pointer; /* 改成手形游標,讓 hover 更明顯 */
transform-style: preserve-3d; /* 使用 preserve-3d 模試,將子元素擺放在同一個 3D 空間裡 */
}
h2::before, h2::after {
content: attr(text);
top: 0;
transform-origin: 0 0 0; /* 轉換中心點為左上角 */
pointer-events: none; /* 禁止與滑鼠互動,因為 3D 旋轉時的尺寸空間會變大 */
}
h2::before {
position: relative;
left: 5px;
color: #000;
}
h2::after {
position: absolute;
left: 0;
color: #fff;
transform: rotateY(-5deg); /* 預設稍微翻 -5deg */
transition: .3s; /* 加上轉場時間 */
}
h2:hover::after {
color: #eee;
transform: rotateY(-30deg); /* hover 發生時翻轉 -30deg */
}
</style>
剛剛的程式碼基本上已經完成了字母翻牌效果,最後只需要將畫面稍作修飾,就能做出滿有趣的字母翻牌效果,下方範例是使用 hover
觸發字母翻牌效果。
<!-- HTML 程式碼 -->
<div class="box">
<div class="camera"><h2 text="A"></h2></div>
<div class="camera"><h2 text="B"></h2></div>
<div class="camera"><h2 text="C"></h2></div>
</div>
<div class="box">
<div class="camera c100"><h2 text="O"></h2></div>
<div class="camera c100"><h2 text="X"></h2></div>
<div class="camera c100"><h2 text="X"></h2></div>
<div class="camera c100"><h2 text="O"></h2></div>
</div>
<!-- CSS 程式碼 -->
<style>
body {
background: linear-gradient(to top, #d30, #fc0); /* 使用漸層背景 */
width: 100vw;
height: 100vh;
padding: 50px 0;
}
.box {
margin: 20px auto; /* 水平置中 */
width: max-content; /* 寬度為最大內容寬 */
}
.camera {
display: inline-block; /* 幫助排版,看自己需求也可以移除這行 */
font-size: 150px; /* 字體大小移動到這裡,為了讓 perspective:3em 有參考依據 */
line-height: 0.8; /* 行高跟隨字體大小移動到這邊 */
perspective-origin: 50% 50%; /* 攝影機中心點對齊中心 */
perspective: 3em; /* 攝影機透視距離為 3em = 150px x 3 */
}
.c100 {font-size: 100px;} /* 額外增加可以改變字體大小的類別 */
h2 {
position: relative;
margin: 0;
padding: 0;
cursor: pointer; /* 改成手形游標,讓 hover 更明顯 */
transform-style: preserve-3d; /* 使用 preserve-3d 模試,將子元素擺放在同一個 3D 空間裡 */
}
h2::before, h2::after {
content: attr(text); /* 讀取並顯示元素的 text 屬性 */
top: 0;
transform-origin: 0 0 0; /* 轉換中心點為左上角 */
pointer-events: none; /* 禁止與滑鼠互動,因為 3D 旋轉時的尺寸空間會變大 */
}
h2::before {
position: relative; /* 因為元素本身沒有內容,使用 relative 讓虛擬元素撐開元素 */
left: 5px; /* 陰影稍微位移 */
color: #000; /* 陰影顏色黑色 */
}
h2::after {
position: absolute; /* 因為翻轉時會改變尺寸,所以使用 absolute 使其不會影響尺寸,並蓋在陰影上方 */
left: 0;
color: #fff; /* 文字白色 */
transform: rotateY(-5deg); /* 預設稍微翻 -5deg */
transition: .3s; /* 加上轉場時間 */
}
h2:hover::after {
color: #eee;
transform: rotateY(-30deg); /* hover 發生時翻轉 -30deg */
}
</style>
純 CSS 翻牌效果運用到許多 CSS 技巧,例如轉換、動畫、屬性值...等,只要熟練這些用法,就能輕鬆做出很有趣的翻牌效果囉。
- 原文參考:CSS 字母翻牌效果
- 延伸閱讀:CSS 教學大全