tad-slide 使用說明

一套輕量、無依賴的響應式輪播套件,靈感來自 ResponsiveSlides.js,並全面升級為符合 WCAG 2.3 AAA 無障礙標準。支援三種導覽模式、五種過場特效、鍵盤與觸控操作,以及單張圖片自動靜態模式。

🚫 無依賴套件 ⚡ Vanilla JS ✅ WCAG 2.3 AAA 📱 RWD 響應式 ⌨️ 鍵盤可操作 👆 觸控支援 1️⃣ 單張自動靜態
LIVE DEMO — navMode: 'bottom' / effect: 'slide'
  • 🎠 tad-slide
    輕量 · 無依賴 · WCAG 2.3 AAA
  • ⌨️ 鍵盤友善
    完整鍵盤操作支援,符合無障礙標準
  • 🎬 五種特效
    fade · slide · zoom · flip · cube
  • 📐 三種導覽模式
    bottom · sides · none,彈性配置

🚀 快速開始

  1. 引入 CSS 與 JS 檔案
    <!-- 放在 <head> -->
    <link rel="stylesheet" href="tad-slide.css">
    
    <!-- 放在 </body> 前 -->
    <script src="tad-slide.js"></script>
  2. 撰寫 HTML 結構
    <div class="tad-slide" aria-label="圖片輪播">
      <ul class="tad-slide__list">
        <li class="tad-slide__item">
          <img src="1.jpg" alt="圖片描述">
          <div class="tad-slide__caption">說明文字(選填)</div>
        </li>
        <li class="tad-slide__item">
          <img src="2.jpg" alt="圖片描述">
        </li>
      </ul>
    </div>
  3. 初始化 JavaScript
    <script>
      tadSlide('.tad-slide', {
        navMode : 'bottom',
        effect  : 'slide',
        timeout : 4000,
        speed   : 600,
      });
    </script>
💡
tadSlide() 支援 CSS 選擇器字串或直接傳入 DOM 元素。若選擇器匹配多個元素,會自動批次初始化並回傳實例陣列。

🏗️ HTML 結構說明

tad-slide 使用語意化的 <ul> / <li> 結構,每個 .tad-slide__item 內可放置任意 HTML 內容。

完整結構說明

<!--
  .tad-slide     → 外層容器(必填)
  aria-label     → 輪播名稱,供螢幕閱讀器識別(強烈建議填寫)
-->
<div class="tad-slide" aria-label="產品圖片輪播">

  <!-- .tad-slide__list → 投影片清單(必填) -->
  <ul class="tad-slide__list">

    <!-- .tad-slide__item → 單張投影片(建議 2 張以上) -->
    <li class="tad-slide__item">

      <!-- 圖片:alt 屬性必填(WCAG 1.1.1) -->
      <img src="photo.jpg" alt="圖片的具體描述">

      <!-- .tad-slide__caption → 說明文字(選填) -->
      <div class="tad-slide__caption">說明文字</div>

    </li>
  </ul>
</div>

投影片內容不限圖片

每個 .tad-slide__item 內可放置任意 HTML,例如文字卡片、混合排版等:

<li class="tad-slide__item">
  <div style="padding:3rem;background:#1a1a2e;">
    <h2>任意 HTML 內容</h2>
    <p>文字、按鈕、圖示都可以放在這裡。</p>
    <a href="#">了解更多</a>
  </div>
</li>
⚠️
所有投影片的高度建議一致,否則切換時容器高度會跳動。使用 aspect-ratio 或固定 height 可確保穩定。

🧭 導覽模式(navMode)

透過 navMode 選項控制導覽介面的呈現方式,共三種模式。

'bottom' — 下方控制列(預設)

分頁點、上下張按鈕、暫停按鈕全部集中在輪播下方,適合一般內容頁面。

navMode: 'bottom'
  • Slide 1
    下方控制列:分頁點 + 上下張 + 暫停
  • Slide 2
    適合一般內容頁面
  • Slide 3
    所有控制集中在底部列
tadSlide('#my-slider', {
  navMode : 'bottom',  // 預設值
  pager   : true,    // 顯示分頁點(bottom 模式專屬)
  nav     : true,    // 顯示上下張按鈕(bottom 模式專屬)
});

'sides' — 左右浮動箭頭

箭頭浮動於輪播圖左右兩側,暫停按鈕浮動於右上角。滑鼠移入或鍵盤聚焦時才顯示,適合 Hero Banner。

navMode: 'sides'
  • Slide A
    滑鼠移入後,左右箭頭與暫停按鈕才會顯示
  • Slide B
    適合 Hero Banner 全幅輪播
  • Slide C
    鍵盤聚焦時按鈕同樣會顯示
tadSlide('#my-slider', {
  navMode : 'sides',  // 左右浮動箭頭 + 右上角暫停
});

'none' — 僅暫停按鈕

不顯示任何導覽控制,僅右上角保留浮動暫停按鈕。仍支援鍵盤 ← → 與觸控滑動,適合背景輪播。

navMode: 'none'
  • 純自動播放
    無導覽按鈕,滑鼠移入後暫停按鈕才顯示
  • 鍵盤仍可操作
    ← → 鍵切換,Space 鍵暫停
  • 觸控滑動
    支援左右滑動手勢
tadSlide('#my-slider', {
  navMode : 'none',  // 僅右上角浮動暫停按鈕
});
ℹ️
sides 與 none 模式的浮動按鈕在 prefers-reduced-motion 環境下會直接常駐顯示,確保使用者隨時可見控制元件。

🎬 過場特效(effect)

透過 effect 選項選擇切換動畫,共五種。以下為各效果的即時展示:

effect: 'fade'(預設)
  • 淡入淡出
  • Fade
  • 柔和過渡
effect: 'slide'
  • 左右滑動
  • Slide
  • 水平位移
effect: 'zoom'
  • 縮放淡入
  • Zoom
  • Scale 過渡
effect: 'flip'
  • 水平翻轉
  • Flip
  • Y 軸旋轉
effect: 'cube'
  • 立方體旋轉
  • Cube
  • X 軸翻轉
ℹ️
當使用者系統開啟「減少動態效果」(prefers-reduced-motion: reduce)時, 所有特效會自動降級為簡單的 0.1s 淡入淡出,不會有位移或旋轉動畫。

五種特效對照表

effect 值 動畫類型 CSS 屬性 適合場景
'fade'(預設) 淡入淡出 opacity 通用,最穩定,效能最佳
'slide' 水平滑動 translateX 新聞輪播、橫向內容
'zoom' 縮放淡入 scale + opacity 圖片展示、視覺強調
'flip' Y 軸翻轉 rotateY + perspective 卡片翻面、互動感強
'cube' X 軸立方體 rotateX + perspective 視覺衝擊、展示型頁面

設定方式

tadSlide('#my-slider', {
  effect : 'slide',  // 'fade' | 'slide' | 'zoom' | 'flip' | 'cube'
  speed  : 600,    // 動畫持續時間(毫秒),預設 600
});
⚠️
'flip' 與 'cube' 使用 3D transform,在低階裝置上可能有效能問題。 若需要廣泛相容性,建議使用 'fade' 或 'slide'。

1️⃣ 單張靜態模式

當 .tad-slide__list 內只有一個 .tad-slide__item 時,tad-slide 會自動偵測並切換為靜態模式:不啟動計時器、不建立任何控制元件、不執行動畫。

  • 自動套用 .tad-slide--single class
  • CSS 隱藏所有控制列、箭頭、進度條、暫停按鈕
  • 投影片直接顯示,無任何過場效果
  • 即使選項設定了 auto: true 或 navMode,單張時一律忽略
單張投影片 — 自動靜態模式
  • 只有一張,不需要輪播
    單張模式:無進度條、無按鈕、無計時器,即使設定 navMode 也不顯示
// 即使傳入任何選項,單張時一律靜態顯示
tadSlide('#demo-single', {
  navMode : 'bottom',  // 單張時忽略
  auto    : true,     // 單張時忽略
  effect  : 'slide',  // 單張時忽略
});
💡
這個設計讓你可以在後端動態輸出投影片數量,不需要在模板層額外判斷「只有一張時要隱藏導覽」,tad-slide 會自動處理。

⚙️ 所有選項

初始化時傳入選項物件,以下為完整參數說明:

tadSlide('.tad-slide', {

  // ── 播放控制 ──────────────────────────────────
  auto          : true,        // 是否自動播放
  speed         : 600,         // 過場動畫時間(毫秒)
  timeout       : 4000,        // 自動切換間隔(毫秒)
  random        : false,       // 隨機播放順序
  pauseOnHover  : true,        // 滑鼠移入時暫停

  // ── 視覺效果 ──────────────────────────────────
  effect        : 'fade',      // 'fade' | 'slide' | 'zoom' | 'flip' | 'cube'

  // ── 導覽模式 ──────────────────────────────────
  navMode       : 'bottom',    // 'bottom' | 'sides' | 'none'
  pager         : true,        // 顯示分頁點(僅 bottom 模式有效)
  nav           : true,        // 顯示上下張按鈕(僅 bottom 模式有效)

  // ── 文字標籤 ──────────────────────────────────
  prevText      : '‹',         // 上一張按鈕顯示文字(可含 HTML)
  nextText      : '›',         // 下一張按鈕顯示文字(可含 HTML)
  pauseText     : '⏸',         // 播放中時暫停按鈕顯示內容
  playText      : '▶',          // 已暫停時播放按鈕顯示內容
  pauseLabel    : '暫停輪播',   // 暫停按鈕 aria-label(播放中)
  playLabel     : '播放輪播',   // 暫停按鈕 aria-label(已暫停)
  prevLabel     : '上一張投影片', // 上一張按鈕 aria-label
  nextLabel     : '下一張投影片', // 下一張按鈕 aria-label

  // ── 無障礙 ────────────────────────────────────
  announceSlide : true,        // 切換時透過 Live Region 通知螢幕閱讀器

  // ── 回呼函式 ──────────────────────────────────
  before        : null,        // 切換前觸發 function(fromIndex, toIndex)
  after         : null,        // 切換後觸發 function(fromIndex, toIndex)

});

選項速查表

選項名稱 型別 預設值 說明
auto Boolean true 是否自動播放;單張時自動忽略
speed Number 600 過場動畫時間(毫秒)
timeout Number 4000 自動切換間隔(毫秒)
effect String 'fade' fade / slide / zoom / flip / cube
navMode String 'bottom' bottom / sides / none;單張時自動忽略
pager Boolean true 顯示分頁點(僅 bottom 模式有效)
nav Boolean true 顯示上下張按鈕(僅 bottom 模式有效)
random Boolean false 初始化時隨機排序投影片
pauseOnHover Boolean true 滑鼠移入時自動暫停
announceSlide Boolean true 切換時透過 Live Region 通知螢幕閱讀器
prevText String '‹' 上一張按鈕 innerHTML(可含 HTML 標籤)
nextText String '›' 下一張按鈕 innerHTML(可含 HTML 標籤)
pauseText String '⏸' 播放中時暫停按鈕顯示內容
playText String '▶' 已暫停時播放按鈕顯示內容
pauseLabel String '暫停輪播' 暫停按鈕的 aria-label(播放中狀態)
playLabel String '播放輪播' 暫停按鈕的 aria-label(已暫停狀態)
prevLabel String '上一張投影片' 上一張按鈕的 aria-label
nextLabel String '下一張投影片' 下一張按鈕的 aria-label
before Function null 切換前觸發,參數為 (fromIndex, toIndex)
after Function null 切換後觸發,參數為 (fromIndex, toIndex)

🔧 實例方法

tadSlide() 回傳實例物件,可呼叫以下方法進行程式化控制:

// 取得實例
const slider = tadSlide('#my-slider', { ... });

// 呼叫方法
slider.next();       // 下一張
slider.prev();       // 上一張
slider.goTo(2);     // 跳至第 3 張(索引從 0 開始)
slider.play();       // 開始自動播放
slider.pause();      // 暫停自動播放
slider.destroy();    // 銷毀實例,還原 DOM
next()

切換至下一張投影片。若目前為最後一張,循環回第一張。

prev()

切換至上一張投影片。若目前為第一張,循環至最後一張。

goTo( index: Number )

跳至指定索引的投影片(索引從 0 開始)。若傳入超出範圍的值,會自動取餘數循環。動畫進行中呼叫會被忽略,避免競態問題。

play()

啟動自動播放計時器,並重設進度條動畫。若已在播放中,會先清除舊計時器再重新啟動。

pause()

暫停自動播放計時器,並凍結進度條在目前位置。暫停狀態會同步更新暫停按鈕的 aria-pressed 與視覺樣式。

destroy()

完整銷毀實例:清除計時器、移除所有由 JS 建立的 DOM 元素(控制列、進度條、Live Region)、還原投影片的 ARIA 屬性與 class,並移除容器上的模式 class。

多個實例的批次操作

// 選擇器匹配多個元素時,回傳陣列
const sliders = tadSlide('.tad-slide', { navMode: 'bottom' });

// 批次暫停所有輪播
sliders.forEach(s => s.pause());

// 單獨操作第二個實例
sliders[1].goTo(0);

🔔 回呼函式

before 與 after 兩個回呼讓你可以在投影片切換的前後執行自訂邏輯,兩者都接收相同的參數:

  • fromIndex:離開的投影片索引(Number,從 0 開始)
  • toIndex:進入的投影片索引(Number,從 0 開始)
tadSlide('#my-slider', {

  // 切換動畫開始前觸發
  before: function(fromIndex, toIndex) {
    console.log(`準備從第 ${fromIndex + 1} 張切換至第 ${toIndex + 1} 張`);
  },

  // 切換動畫結束後觸發
  after: function(fromIndex, toIndex) {
    console.log(`已切換至第 ${toIndex + 1} 張`);

    // 範例:同步更新頁面上的文字說明
    const captions = ['第一章', '第二章', '第三章'];
    document.querySelector('#chapter-title').textContent = captions[toIndex];
  },

});
⚠️
before 在動畫開始前觸發,此時新投影片尚未完全顯示。若需要操作已完全顯示的投影片 DOM,請使用 after。

⌨️ 鍵盤操作

當焦點位於輪播容器內部時,以下鍵盤快捷鍵均可使用,無論 navMode 為何種模式:

← 或 ↑ 切換至上一張投影片
→ 或 ↓ 切換至下一張投影片
Space 切換暫停/播放狀態(焦點不在暫停按鈕上時有效)
Home 跳至第一張投影片
End 跳至最後一張投影片
Tab 依序聚焦至控制按鈕(瀏覽器預設行為)
Enter / Space 在按鈕上觸發點擊(瀏覽器預設行為)
💡
sides 與 none 模式下,鍵盤使用者可透過 Tab 將焦點移入輪播容器,此時浮動按鈕會自動顯示(CSS :focus-within 觸發),確保完整的鍵盤可操作性。

♿ 無障礙(WCAG)說明

tad-slide 在設計時即以 WCAG 2.3 AAA 為目標,以下列出各項對應的實作方式:

  • 1.1.1 A
    圖片替代文字 — 要求每個 <img> 填寫有意義的 alt 屬性。tad-slide 不自動產生 alt,需由開發者提供。
  • 1.3.1 A
    資訊與關係 — 使用 role="region"、role="group"、aria-roledescription="carousel / slide" 提供語意結構。
  • 1.4.3 AA
    對比度(最低) — 說明文字背景 rgba(0,0,0,0.65) 搭配白色文字,對比度 ≥ 4.5:1。按鈕焦點色 #ffdd00 對比度 ≥ 7:1。
  • 2.1.1 A
    鍵盤可操作 — 所有功能均可透過鍵盤完成:←→ 切換、Space 暫停、HomeEnd 跳轉。
  • 2.2.2 A
    暫停、停止、隱藏 — 所有自動播放模式均提供暫停按鈕,使用者可隨時停止輪播。
  • 2.2.3 AAA
    無時間限制 — 暫停後輪播完全停止,不會自動恢復,直到使用者主動按下播放。
  • 2.3.3 AAA
    互動中的動畫 — 偵測 prefers-reduced-motion: reduce,自動將所有過場特效降級為簡單淡入淡出(0.1s),消除位移與旋轉動畫。
  • 2.4.3 A
    焦點順序 — 分頁點點擊後,焦點移至對應投影片元素,維持合理的焦點流向。
  • 2.4.7 AA
    焦點可見 — 所有可聚焦元素均有 3px solid #ffdd00 的高對比焦點框。
  • 2.4.12 AAA
    焦點外觀(增強) — 焦點框面積 ≥ 元素周長 × 2px,對比度 ≥ 3:1,符合 AAA 增強標準。
  • 2.5.8 AA
    最小觸控目標 — 所有按鈕最小尺寸為 44×44px,分頁點使用透明擴充點擊區域達到此標準。
  • 4.1.2 A
    名稱、角色、值 — 暫停按鈕使用 aria-pressed 表達狀態;分頁點使用 aria-current;隱藏投影片設定 aria-hidden="true"。
  • 4.1.3 AA
    狀態訊息 — 每次切換透過 aria-live="polite" Live Region 向螢幕閱讀器播報「第 N 張,共 M 張:說明文字」。
🚨
開發者責任:tad-slide 提供無障礙的互動框架,但 圖片的 alt 屬性與容器的 aria-label 必須由開發者提供有意義的內容。空白或缺少這兩個屬性,將導致螢幕閱讀器使用者無法理解輪播內容。