搜尋

CSS 雙色立體文字跑馬燈

這篇教學會使用 CSS 的虛擬元素選擇器,搭配 CSS animation 動畫、CSS 變數、CSS transform 的 3D 變形和平移,實作非常吸睛又有趣的雙色立體文字跑馬燈。

快速導覽:

CSS 教學 - CSS 雙色立體文字跑馬燈

製作雙色文字

CSS 製作雙色文字最常見的方式,是使用具有同樣文字的兩個 div,搭配 overflow: hidden 和文字的定位,就能將不同顏色的文字互相組合成雙色字,但因為這個範例最終需要呈現「會動又立體」的文字,會使用「CSS 變數」和「虛擬元素」互相搭配,讓後續編輯或調整更為方便,主要步驟如下,詳細說明可參考範例註解。

  • 將 CSS 變數設定在 HTML 元素的 style 屬性中
  • 透過虛擬元素讀取 CSS 變數內容,這樣只需撰寫一次內容。
  • 設定元素 overflow: hidden 隱藏超過範圍的虛擬元素。
  • 使用 translateX 搭配百分比單位調整虛擬元素位置,組合成雙色文字 ( 只有 transform 平移的百分比是元素本身寬度 )。
  • 更多參考:CSS 變數虛擬元素選擇器translate() 平移calc() 基本數學運算

線上展示:https://codepen.io/oxxo/pen/ogNEdzV

<!-- HTML 程式碼 -->
<!-- 設定兩個變數 --text 和 --w 負責文字和一半的寬度 -->
<div class="d" style="--text:'OXXO.STUDIO'; --w: 250px;">
  <div style="--c1: #f00; --ct1: #fff;"></div>
  <div style="--c2: #0c0; --ct2: #050;"></div>
</div>
<br>
<div class="d" style="--text:'TAIWAN'; --w: 200px;">
  <div style="--c1: #fff; --ct1: #0a0;"></div>
  <div style="--c2: #0a0; --ct2: #fff;"></div>
</div>
<br>
<div class="d" style="--text:'YES'; --w: 100px;">
  <div style="--c1: #fc0; --ct1: #000;"></div>
  <div style="--c2: #000; --ct2: #fc0;"></div>
</div>

<!-- CSS 程式碼 -->
<style>
  .d {
    display: inline-block;    /* 改為 inline-block 讓浮動內容可以撐開高度 */
    width: max-content;       /* 寬度為內容最大寬度 */
    font-family: impact, arial-black;  /* 設定成比較粗的字體 */
    font-size: 80px;
  }
  .d div {
    position: relative;       /* 讓內容絕對定位 */
    width: var(--w);          /* 寬度為變數 --w 寬度 */
    float: left;              /* 左右浮動 */
    overflow: hidden;         /* 超過範圍隱藏 */
    border: 1px solid #000;   /* 邊框 */
  }
  .d div:nth-child(1) {
    background: var(--c1);    /* 左邊 div 背景紅色,讀取變數 --c1 內容 */
  }
  .d div:nth-child(2) {
    background: var(--c2);    /* 右邊 div 背景綠色,讀取變數 --c2 內容 */
  }
  .d div::before {
    width: max-content;       /* 虛擬元素寬度為最大內容寬度 */
    display: block;           /* 改為 block ( 預設為 inline ) */
    content: var(--text);     /* 內容是變數 --text 內容 */
    line-height: 1;           /* 行高和字體大小相同 */
  }
  .d div:nth-child(1)::before {
    color: var(--ct1);        /* 左邊文字白色,讀取變數 --ct1 內容 */
    /* 運用 translateX 計算定位,特別注意此處的百分比單位是乘以「元素本身寬度」,並非父元素 */
    transform: translateX(calc(-50% + var(--w)));
  }
  .d div:nth-child(2)::before {
    color: var(--ct2);        /* 右邊文字深綠色,讀取變數 --ct2 內容 */
    /* 運用 translateX 計算定位,特別注意此處的百分比單位是乘以「元素本身寬度」,並非父元素 */
    transform: translateX(-50%);
  }
</style>

CSS 教學 - CSS 雙色立體文字跑馬燈 - 製作雙色文字

製作雙色文字跑馬燈

將範例程式碼加入 CSS 動畫 animation 讓「虛擬元素」進行平移,為了方便調整,在 HTML 元素裡新增一個 --s 變數作為動畫持續時間,並照下方規則設定動畫位置:

左邊 div 右邊 div
起始位置 父元素寬度 x 2 父元素寬度
結束位置 虛擬元素本身寬度 x -100% 虛擬元素本身寬度 x -100% - 父元素寬度

參考:CSS 動畫 animation

線上展示:https://codepen.io/oxxo/pen/KwKQRNq

<!-- HTML 程式碼 -->
<!-- 設定兩個變數 --text 和 --w 和 --s 負責文字和一半的寬度 -->
<div class="d" style="--text:'OXXO.STUDIO'; --w: 250px; --s: 5s;">
  <div style="--c1: #f00; --ct1: #fff;"></div>
  <div style="--c2: #0c0; --ct2: #050;"></div>
</div>
<br>
<div class="d" style="--text:'TAIWAN'; --w: 200px; --s: 10s;">
  <div style="--c1: #fff; --ct1: #0a0;"></div>
  <div style="--c2: #0a0; --ct2: #fff;"></div>
</div>
<br>
<div class="d" style="--text:'YES'; --w: 100px; --s: 2s;">
  <div style="--c1: #fc0; --ct1: #000;"></div>
  <div style="--c2: #000; --ct2: #fc0;"></div>
</div>

<!-- CSS 程式碼 -->
<style>
  .d {
    display: inline-block;    /* 改為 inline-block 讓浮動內容可以撐開高度 */
    width: max-content;       /* 寬度為內容最大寬度 */
    font-family: impact, arial-black;  /* 設定成比較粗的字體 */
    font-size: 80px;
  }
  .d div {
    position: relative;       /* 讓內容絕對定位 */
    width: var(--w);          /* 寬度為變數 --w 寬度 */
    float: left;              /* 左右浮動 */
    overflow: hidden;         /* 超過範圍隱藏 */
    border: 1px solid #000;   /* 邊框 */
  }
  .d div:nth-child(1) {
    background: var(--c1);    /* 左邊 div 背景紅色,讀取變數 --c1 內容 */
  }
  .d div:nth-child(2) {
    background: var(--c2);    /* 右邊 div 背景綠色,讀取變數 --c2 內容 */
  }
  .d div::before {
    width: max-content;       /* 虛擬元素寬度為最大內容寬度 */
    display: block;           /* 改為 block ( 預設為 inline ) */
    content: var(--text);     /* 內容是變數 --text 內容 */
    line-height: 1;           /* 行高和字體大小相同 */
  }
  .d div:nth-child(1)::before {
    color: var(--ct1);        /* 左邊文字白色,讀取變數 --ct1 內容 */
    /* 運用 translateX 計算定位,特別注意此處的百分比單位是乘以「元素本身寬度」,並非父元素 */
    animation: oxxo1 var(--s) infinite linear;
  }
  .d div:nth-child(2)::before {
    color: var(--ct2);        /* 右邊文字深綠色,讀取變數 --ct2 內容 */
    /* 運用 translateX 計算定位,特別注意此處的百分比單位是乘以「元素本身寬度」,並非父元素 */
    animation: oxxo2 var(--s) infinite linear;
  }
  @keyframes oxxo1 {
    0% {transform: translateX(calc( 2 * var(--w)));}  /* 左邊虛擬元素起始值 */
    100% {transform: translateX(-100%);}
  }
  @keyframes oxxo2 {
    0% {transform: translateX(var(--w));}             /* 右邊虛擬元素起始值 */
    100% {transform: translateX(calc(-100% - var(--w)));}
  }
</style>

CSS 教學 - CSS 雙色立體文字跑馬燈 - 製作雙色文字跑馬燈

使用 transform 製作雙色立體文字跑馬燈

延伸範例程式碼,在 HTML 裡使用一個類別為「camera」的 div 包覆雙色文字跑馬燈,這個 div 主要會設定 3D 變形的「攝影機視角」,接著將最外層類別為「d」的 div虛擬元素設定為「上蓋」和「陰影」,就能做出漂亮的雙色立體文字跑馬燈。

線上展示:https://codepen.io/oxxo/pen/VYwQxPJ

<!-- HTML 程式碼 -->
<!-- 使用 camera 包覆剛剛的 HTML -->
<div class="camera">
  <div class="d" style="--text:'OXXO.STUDIO'; --w: 250px; --s: 5s;">
    <div style="--c1: #f00; --ct1: #fff;"></div>
    <div style="--c2: #0c0; --ct2: #050;"></div>
  </div>
  <br>
  <div class="d" style="--text:'TAIWAN'; --w: 250px; --s: 10s;">
    <div style="--c1: #fff; --ct1: #0a0;"></div>
    <div style="--c2: #0a0; --ct2: #fff;"></div>
  </div>
  <br>
  <div class="d" style="--text:'YES'; --w: 250px; --s: 2s;">
    <div style="--c1: #fc0; --ct1: #000;"></div>
    <div style="--c2: #000; --ct2: #fc0;"></div>
  </div>
</div>

<!-- CSS 程式碼 -->
<style>
  .camera {
    width: max-content;
    margin: 50px auto;
    perspective: 500px;          /* 攝影機視角 */
    perspective-origin: 50% 20%; /* 攝影機中心 */ 
  }
  .d {
    display: inline-block;
    position: relative;
    width: max-content;
    font-family: impact, arial-black;
    font-size: 80px;
    transform-style: preserve-3d; /* 將內容視為同一個 3D 空間 *
    transform: rotateX(-10deg);   /* 繞 X 軸旋轉 10 deg */
  }
  .d div {
    position: relative;
    width: var(--w);
    float: left;
    overflow: hidden;
    border: 1px solid #000;
  }
  .d::before, .d::after {
    position: absolute;  /* 虛擬元素作為上蓋和影子進行絕對定位 */
    content: "";
    width: var(--w);     /* 長寬相同,產生一個正方形區域 */
    height: var(--w);
    top: 0;
    left: 0;
    background: #666;
  }
  .d:nth-of-type(1) {z-index: 3;}            /* 最上方 */
  .d:nth-of-type(1)::after {display: none;}  /* 最上方不需要影子 */
  .d:nth-of-type(2) {z-index: 2;}            /* 中間層 */
  .d:nth-of-type(2)::after {display: none;}  /* 中間層不需要影子 */
  .d:last-of-type {z-index: 1;}              /* 最下層 */

  .d::before {
    transform-origin: 100% 0 0;
    transform: translateY(1px) rotateY(-135deg) rotateX(90deg);   /* 最上方蓋子 */
  }
  .d::after {
    transform-origin: 100% 0 0;
    transform: translateY(1.3em) rotateY(-45deg) rotateX(-90deg); /* 影子 */
  }
  .d div:nth-child(1) {
    background: var(--c1);
    transform-origin: 100% 0 0;
    transform: rotateY(-45deg);  /* 左側 div 旋轉 */
  }
  .d div:nth-child(2) {
    background: var(--c2);
    transform-origin: 0 0 0;
    transform: rotateY(45deg);  /* 右側 div 旋轉 */
  }
  .d div::before {
    width: max-content;
    display: block;
    content: var(--text);
    line-height: 1;
  }
  .d div:nth-child(1)::before {
    color: var(--ct1);
    animation: oxxo1 var(--s) infinite linear;
  }
  .d div:nth-child(2)::before {
    color: var(--ct2);
    animation: oxxo2 var(--s) infinite linear;
  }
  @keyframes oxxo1 {
    0% {transform: translateX(calc( 2 * var(--w)));}
    100% {transform: translateX(-100%);}
  }
  @keyframes oxxo2 {
    0% {transform: translateX(var(--w));}
    100% {transform: translateX(calc(-100% - var(--w)));}
  }
</style>

CSS 教學 - CSS 雙色立體文字跑馬燈 - 使用 transform 製作雙色立體文字跑馬燈

如果修改 HTML 裡的變數,跑馬燈的大小也會跟著改變,下圖的變數為:--w:300px--w:200px--w:150px

CSS 教學 - CSS 雙色立體文字跑馬燈 - 使用 transform 製作雙色立體文字跑馬燈

小結

基本上要製作雙色文字跑馬燈並不困難,困難的地方在於要讓整體程式碼容易修改,這個範例仍然存有「超過三層就要稍微修改 CSS」的缺陷,但整體來說已經可以很順利的製作出 3D 立體跑馬燈囉。

意見回饋

如果有任何建議或問題,可傳送「意見表單」給我,謝謝~

CSS 教學

基本介紹

認識 CSS 開始使用 CSS CSS 語法規則 CSS 命名原則 CSS 常用樣式屬性

CSS 選擇器

認識 CSS 選擇器 優先順序 ( 權重 ) 樣式繼承與聯集 使用巢狀結構語法 元素選擇器 ID 和 Class 選擇器 屬性選擇器 文件結構選擇器 虛擬類別選擇器 ( 結構 ) 虛擬類別選擇器 ( 類型 ) 虛擬類別選擇器 ( 輸入 ) 虛擬類別選擇器 ( 行為 ) 虛擬類別選擇器 ( 超連結 ) 虛擬類別選擇器 ( 邏輯 ) 虛擬類別選擇器 ( 其他 ) 虛擬元素選擇器 群組與組合選擇器

數值與單位

全域關鍵字與文字數值 長度與角度單位 位置名稱與時間單位 特殊樣式屬性 ( all、appearance)

規則與定義

變數 ( Variables ) 媒體查詢 ( @media ) 容器查詢 ( @container ) 自訂屬性值 ( @property ) 匯入樣式 ( @import ) 分層優先順序 ( @layer ) 定義字型 ( @font-face ) 計數規則 ( @counter-style ) 列印網頁 ( @page )

函式類型

數學計算 文字與清單計數 形狀與線段 路徑 ( path ) 生成內容與引號

顏色與濾鏡

顏色單位 色彩模型 漸層色 影像濾鏡 ( filter ) 背景濾鏡 ( backdrop-filter ) 混合模式 ( mix-blend-mode )

文字與段落

設定字型 ( font-family ) 使用外部字型 文字尺寸 文字樣式 ( 常用 ) 文字樣式 ( 其他實用 ) 文字樣式 ( 特殊用途 ) 文字換行 文字空白與 Tab 大小 文字行高與縮排 文字水平與垂直對齊 文字書寫方向 文字自動分欄 使用 Icon Font ( 圖示文字 ) 製作自己的 Icon Font

元素容器

容器顯示類型 ( display ) 元素 display 對照表 盒子模型 ( Box Model ) 寬高尺寸 內邊距 ( padding ) 外邊界 ( margin ) 邊框 ( border ) 邊框圓角 ( border-radius ) 影像邊框 ( border-image ) 輪廓 ( outline ) 內容溢出與裁切 ( overflow ) 內容範圍 ( contain ) 可見性與透明度

背景與陰影

背景 ( 背景色、背景裁切 ) 背景圖 ( 定位、尺寸 ) 背景圖 ( 固定、重複 ) 背景圖 ( 多重背景、混合 ) 背景縮寫 ( background ) 容器陰影 ( box-shadow )

清單與表格

清單樣式 清單計數器 表格基本樣式 表格邊框樣式 表格內容寬度與對齊

基本排版與定位

元素排版方式 浮動 ( float ) 浮動形狀 ( shape-* ) 定位 ( position ) 邏輯屬性 ( logical properties ) 重置 CSS ( Reset CSS ) 水平置中技巧 垂直置中技巧

Flex 彈性排版

Flexbox 彈性盒子 Flex 對齊方式 Flex 彈性伸縮

Grid 網格排版

Grid 網格容器與格線 Grid 網格空間與命名 Grid 網格流向與間距 Grid 排列網格項目 Grid 項目對齊與順序

轉場與動畫

轉場 ( transition ) 轉場觸發事件 動畫 ( animation ) 自訂動畫路徑 ( offset ) 動畫觸發事件 多重動畫的權重與順序 動畫進度控制 ( timeline )

變形、裁切與遮罩

裁切路徑 ( clip-path ) 影像遮罩 ( mask ) 物件填滿方式與定位 轉換函式 ( transform ) 平移、旋轉與縮放 3D 轉換與透視

視窗與使用者行為

捲軸樣式 ( scrollbar ) 拉霸、滑桿樣式 ( slider ) 滑鼠游標圖示 ( cursor ) 滑鼠事件 ( pointer-events ) 使用者選取 ( user-select ) 捲動行為 ( scroll、overscroll ) 列印換頁 ( break-* )

CSS 預處理器

認識 CSS 預處理器 Less ( 安裝、開始使用 ) Less ( 巢狀結構、選擇器 ) Less ( 變數、import ) Less ( Extend、Mixin ) Less ( 邏輯、迴圈、函式 )

範例效果

CSS 圓餅圖 CSS 跑馬燈 Google 載入動畫 漸層色的轉場與動畫 電子時鐘數字 不規則形狀動畫 彈跳的正方形動畫 3D 正多面體 超連結底線動畫效果 噁心黏黏球效果 漸層色製作星空背景 CSS 視差滾動效果 捲軸控制放射形選單 捲軸改變文字背景色 CSS 頁面捲動進度條 CSS 水波效果 圓點載入動畫 ( 陰影動畫 ) 字母翻牌效果 探照燈動畫 立體雙色跑馬燈 樓梯文字動態效果 漸層色文字、雙色文字 空心文字、文字水波背景