最近有個需求是製作 TAB 頁籤選單,這功能很常見,理應沒什麼難度。然而客戶希望將來能自行編修、調整選單內容,並製作大量相關頁面,這對於不是熟悉前端程式碼、架構的人來說,要無腦編修 TAB 頁籤的 HTML/CSS 內容實在不太可能(因為這案子的選單內容區塊架構很複雜),而且我也不想順便再教幾堂基礎 HTML/CSS 課程。
於是花了些時間研究,TAB 選單有沒有架構最簡單的實現方式,如果能以純 CSS 實現、不另外處理 JS 更好,研究結果請見本篇的整理。
(圖片出處: .peakpx.com)
1. 理想架構
上面是一個簡單的 TAB 頁籤效果,對於目標是建立一個可以無腦維護、容易複製編修重作的架構,我理想中的 TAB 頁籤程式碼模組希望能符合以下需求:
一、各種方案比較
第 1 個頁籤內容區塊
第 2 個頁籤內容區塊
第 3 個頁籤內容區塊
- 能只用 HTML/CSS 處理、不另外寫 JS 最好
- 維護時最好只需複製、編修 HTML 區塊,不用另外動到 CSS,也就是 CSS 寫法需要能萬用,如此可減少人為操作失誤
- 根據前一點,選單頁籤區塊與內容區塊最好位於同一處:
- 根據多年經驗,選單的架構一定是頁籤區塊一處、內容區塊一處,頁籤區塊的順序必須與內容區塊的順序一致
- 那麼日後增、減內容時,不小心兩邊不一致就會讓頁籤與內容不符合,更別說不熟悉前端的人一定會搞混
- 所以如果能有一種架構,是頁籤區塊與內容區塊可以打包在一起,日後維護絕對不會出問題
- 點擊頁籤的部分利用 A 連結的錨點功能
- CSS 處理內容區塊切換的技巧為使用偽類
:target ,很是巧妙
- 選單架構 HTML 為傳統的頁籤區塊一處、內容區塊一處,維護不便
- 使用錨點會讓應用方式受限,如果整個選單位於畫面需要捲動之處,點擊頁籤後就只能看到內容、看不到頁籤了
- 使用 Input 單選按鈕製作頁籤效果,原理可參考「如何製作無圓點單選、多選按鈕﹍純 CSS 技巧」
- HTML 使用傳統的 TAB 頁籤架構,頁籤一區、內容一區
- CSS 處理內容區塊切換的技巧為,使用 input 單選按鈕獨有的偽類
:checked ,然而有幾個頁籤就必須設定幾個控制代碼,也是這個架構下無可奈何的事
- 傳統的頁籤選單 HTML 架構維護不便
- 只要新增頁籤、內容,就必須新增對應的 CSS 控制,維護麻煩
- 同前範例,使用 Input 單選按鈕製作頁籤效果
- 這是我首次看到使用非傳統 HTML 頁籤架構,頁籤與內容區塊合而為一!
- CSS 處理內容區塊切換的技巧同上,使用 input 單選按鈕獨有的偽類
:checked - 內容區塊的版面處理則是必須使用
position: absolute 定位,否則無法出現在該有的版面位置
- 這是目前為止接近滿分的方案,頁籤與內容區塊合而為一,要複製、修改、刪除都非常方便,只要處理一處適合無腦維護。
- CSS 部分為萬用代碼,無論如何新增、刪除頁籤,都不需動到 CSS
- 唯一的缺點是使用
position: absolute 來定位,這會使應用方式受限,必須為內容區塊設定高度(否則版面會爆掉),導致內容區塊無法根據內容彈性調整高度。
二、利用 flexbox
最後找到這個方案,參考這個 CodePen 範例「Pure CSS Tabs 」,其原理為:- 同前範例,使用 Input 單選按鈕製作頁籤效果,並且使用非傳統 HTML 頁籤架構,頁籤與內容區塊合而為一!
- 唯一不同處,內容區塊的版面處理使用
display: flex ,這是 CSS 新世代的 flexbox 排版技巧
- 目前為止最接近完美的方案,幾乎符合我所有需求。
- 日後要複製、修改、刪除時,只有一點不方便,必須手動為個別 input 單選按鈕設定 id,且對應的 label 標籤也要設定 for 參數
- 不過上一點的不便之處,可以另外寫一行 JS 來自動處理,那麼給客戶使用時就能無腦維護了
三、範例程式碼
以下提供整理過,版面效果較佳的範例程式碼:<div class="tab_css">
<!-- TAB1 打包區塊 start -->
<input id="tab1" type="radio" name="tab" checked="checked"/>
<label for="tab1">頁籤 1</label>
<div class="tab_content">
第 1 個頁籤內容區塊<br/>
WFU BLOG | Blogger 調校資料庫<br/>
</div>
<!-- TAB1 打包區塊 end -->
<!-- TAB2 打包區塊 start -->
<input id="tab2" type="radio" name="tab"/>
<label for="tab2">頁籤 2</label>
<div class="tab_content">
第 2 個頁籤內容區塊<br/>
WFU BLOG | Blogger 調校資料庫<br/>
第 2 個頁籤內容區塊<br/>
WFU BLOG | Blogger 調校資料庫<br/>
</div>
<!-- TAB2 打包區塊 end -->
<!-- TAB3 打包區塊 start -->
<input id="tab3" type="radio" name="tab"/>
<label for="tab3">頁籤 3</label>
<div class="tab_content">
第 3 個頁籤內容區塊<br/>
WFU BLOG | Blogger 調校資料庫<br/>
第 3 個頁籤內容區塊<br/>
WFU BLOG | Blogger 調校資料庫<br/>
第 3 個頁籤內容區塊<br/>
WFU BLOG | Blogger 調校資料庫<br/>
</div>
<!-- TAB3 打包區塊 end -->
</div>
<style>
.tab_css{display:flex;flex-wrap:wrap;justify-content:center;}
.tab_css input{display:none}
.tab_css label{margin: 0 5px 5px 0; padding: 10px 16px; cursor: pointer; border-radius: 5px; background: #999; color: #fff; opacity: 0.5;}
.tab_content{order:1;display: none; width:100%; border-bottom: 3px solid #ddd; line-height: 1.6; font-size: .9em; padding: 15px; border: 1px solid #ddd; border-radius: 5px;}
.tab_css input:checked + label, .tab_css label:hover{opacity: 1; font-weight:bold;}
.tab_css input:checked + label + .tab_content{display: initial;}
</style>
四、展示效果
範例程式碼的 DEMO 效果如下:
第 1 個頁籤內容區塊
WFU BLOG | Blogger 調校資料庫
WFU BLOG | Blogger 調校資料庫
第 2 個頁籤內容區塊
WFU BLOG | Blogger 調校資料庫
第 2 個頁籤內容區塊
WFU BLOG | Blogger 調校資料庫
WFU BLOG | Blogger 調校資料庫
第 2 個頁籤內容區塊
WFU BLOG | Blogger 調校資料庫
第 3 個頁籤內容區塊
WFU BLOG | Blogger 調校資料庫
第 3 個頁籤內容區塊
WFU BLOG | Blogger 調校資料庫
第 3 個頁籤內容區塊
WFU BLOG | Blogger 調校資料庫
WFU BLOG | Blogger 調校資料庫
第 3 個頁籤內容區塊
WFU BLOG | Blogger 調校資料庫
第 3 個頁籤內容區塊
WFU BLOG | Blogger 調校資料庫
更多 CSS 相關技巧:
在 \ 上用 tabindex="0" (或者 ="1") ,允許只用鍵盤一直按 [Tab] 鍵的使用者 focus 在那些標籤上。
回覆刪除