CSS 字母翻牌效果
這篇教學會單純使用 CSS 製作文字跑馬燈效果,不僅會介紹「縮排」和「平移」兩種製作方式,還會說明例如裁切、轉換、縮排、動畫等互相搭配的控制技巧。
快速導覽:
使用虛擬元素產生字母和陰影
字母翻牌效果要產生「翻轉的字母」和「下方陰影」,為了讓程式碼更為簡潔 ( 只寫一次字母 ),可以透過虛擬元素選擇器 ::before
和 ::after
來讀取元素屬性,讀取屬性後根據預設的排列順序,將 ::before
當作陰影,將 ::after
作為字母,詳細說明可以參考範例的註解。
虛擬元素是 CSS 裡唯一可以使用
attr
讀取元素屬性,並透過content
顯示屬性內容的選擇器,參考:虛擬元素選擇器 ( 偽元素 )、content 搭配 attr()。
<!-- 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>
使用 3D 變形產生翻轉效果
如果將剛剛的虛擬元素 ::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 跑馬燈的程式碼並不複雜,但當中會運用不少技巧,例如縮排、轉換、寬度、變數...等,不過只要熟練這些用法,就能輕鬆做出很酷炫的跑馬燈囉。
意見回饋
如果有任何建議或問題,可傳送「意見表單」給我,謝謝~