前端開發入門到實戰:善用CSS僞類,不用JS也能做出選項卡功能

善用CSS僞類,不用JS也能做出選項卡功能

先看看Demo:

講到選項卡(Tabs)功能時,大多會想到用JavaScript去做,像知名的前端框架:Bootstrap所提供的Tab元件,就是用jQuery實現的(其實網絡上有很多用jQuery開發的Tab);但其實不用jQuery或JavaScript技術,就能實現高效能且易維護的Tabs元件,讓我們來看看是怎麼辦到的:

規劃HTML結構

通常我們會用列表元素來製作選項卡的界面,每個<li>代表用來包含一組選項卡與其對應的內容塊。接下來加入選項卡,選項卡必須使用<label>元素才能實作我們要的功能,原因待會會講,是這篇文章的核心技巧之一。

內容塊則是<div>元素。再來我們爲每個<label>前面加上表單元素Radio button,結果如下:

<ul class="tabs">
  <li>
    <input type="radio" name="tabs">
    <label class="tab">頁面A</label>
    <div class="section">內容A</div>
  </li>
  <li>
    <input type="radio" name="tabs">
    <label class="tab">頁面B</label>
    <div class="section">內容B</div>
  </li>
  <li>
    <input type="radio" name="tabs">
    <label class="tab">頁面C</label>
    <div class="section">內容C</div>
  </li>
</ul>

爲什麼使用Label與Radio button?

這篇文章的主要技巧也就是要靠這兩種元素的特性,因爲我們要“借用”Radio button的單選特性,決定哪個Tab是Active,同時確保其他Tab是未選中的狀態。

Radio button默認的樣式是非常醜陋的,而且我們能改動的樣式也是有限的,所以不建議直接把它設計成Tab,所以我們使用<label>來擔任觸發的角色,也比較容易改變樣式,再藉由Label的For屬性去觸發對應id的Radio button。

所以我們爲Radio button加上id,然後將Label的for屬性指向對應的id:

<ul class="tabs">
  <li>
    <input type="radio" name="tabs" id="tabA">
    <label class="tab" for="tabA">頁面A</label>
    <div class="section">內容A</div>
  </li>
  <li>
    <input type="radio" name="tabs" id="tabB">
    <label class="tab" for="tabB">頁面B</label>
    <div class="section">內容B</div>
  </li>
  <li>
    <input type="radio" name="tabs" id="tabC">
    <label class="tab" for="tabC">頁面C</label>
    <div class="section">內容C</div>
  </li>
</ul>

這樣就完成我們的HTML結構了,再來要寫點CSS,讓功能得以運作起來。

寫點CSS

我們先讓<li>並排(display:inline-block)。再來爲<label>和內容塊<div class=“section”>設計外觀。

特別注意內容塊用絕對定位讓每次顯示的內容都在同樣的位置,之後我們再控制層疊等級(z-index)和透明度(opacity)來實現顯示/隱藏。

li { display: inline-block; }

input[type="radio"] {
  position: absolute;
  outline: none;
    ...
}

.tab {
    ...
}

.section {
  position: absolute;
  top: 50px; // 取決於你的Label高度
  left: 0;
    ...
}

咦?還是不能動?因爲我們還需要運用CSS的兩個重要技巧:僞類(Pseudo-class)和通用兄弟元素選擇器(Sibling Combinator),才能讓選項卡與內容塊做切換。

加入CSS僞類與通用兄弟元素選擇器

我們爲Radio button加上僞類:checked,表示當這個Radio button被選中時(等於對應的標籤被選中使)纔會呈現的樣式。

input[type="radio"]:checked {
    ...
}

然後要做切換動作的是選項卡和內容塊,由於它們與Radio button屬同一層父元素,所以我們這裏要用到通用兄弟元素選擇器~來做,通用兄弟元素選擇器有兩種:

  1. 相鄰兄弟選擇器(Adjacent Sibling Combinator)是用來選擇互爲兄弟元素的相鄰的元素。
  2. 通用兄弟元素選擇器(General Sibling Combinator)則是用來選擇互爲兄弟元素的所有匹配的元素。

我們使用通用兄弟元素選擇器即可:

input[type="radio"]:checked ~ .tab {        // 這裏也可以使用相鄰兄弟選擇器來做
    ...
}

input[type="radio"]:checked ~ .section {
    ...
  z-index: 2;
}

注意內容內存塊(.section)要加上z-index屬性才能覆蓋其它選項卡的內容塊,最後我們再將Radio button設爲透明或使用定位的技巧讓它消失在頁面上,前面沒有先提這點的原因,是因爲可以讓你在點選選項卡時,觀察Radio button的選中狀態變化,同時也方便測試,確認選項卡對應的Radio button有正確被觸發。

這樣就大功告成啦!

自己是一個6年的前端工程師,希望本文對你有幫助!

這裏推薦一下我的前端學習交流扣qun:731771211 ,裏面都是學習前端的,如果你想製作酷炫的網頁,想學習編程。自己整理了一份2019最全面前端學習資料,從最基礎的HTML+CSS+JS【炫酷特效,遊戲,插件封裝,設計模式】到移動端HTML5的項目實戰的學習資料都有整理,送給每一位前端小夥伴,每天分享技術

點擊:加入

整理

大略整理一下重點與需要注意的地方:

  1. Radio button的單選特性是基於同樣的name屬性,所以name一定要設,而且要一樣;反之,你可以設置多組name去實現多組的選項卡組件,而且各自是獨立運作,不會互相影響。
  2. Radio button的id和Label的for是必要的屬性。
  3. 內容塊的定位要避免覆蓋到選項卡。
  4. 注意HTML的結構是否正確,CSS選擇器的使用是否正確(選項卡和內容塊有沒有在同一層)。
  5. 注意z-index的設置是否正確。

本篇文章的技術給予選項卡UI另一種開發的選擇,Radio button的特性還有很多應用可以做(如Switcher),只要善用HTML表單元素與CSS的一些技巧,也能玩出很多有趣的功能,甚至替代JavaScript的部份工作

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章