CSS實現導航條Tab切換的三種方法

前面的話

  導航條Tab在頁面中很是常見,本文說詳細介紹CSS實現導航條Tab的三種方法javascript

 

佈局

buju

  根據上圖所示,先規定幾個定義,上圖的模塊總體叫作導航,由導航標題和導航內容組成。要實現上圖所示的佈局效果,有兩種佈局方法:語義佈局和視覺佈局css

【語義佈局】html

  從語義佈局的角度來看,每個導航標題和其對應的導航內容應該是一個總體java

<style>
body,p{margin: 0;}
h2{margin: 0;font-size:100%;}
ul{margin: 0;padding: 0;list-style: none;}   
a{text-decoration: none;color:inherit;}
.box{width: 572px;border: 1px solid #999;overflow: hidden;}
.nav{margin-left: -1px;font: 14px "微軟雅黑";overflow: hidden;background-color: #f1f1f1;}
.navI{float: left;width: 33.333%;box-sizing: border-box;}
.navI-tit{line-height: 40px;text-align: center;cursor: pointer;border-left: 1px solid #cecece;border-bottom: 1px solid #cecece;}
.navI-txt{width: 572px;height:200px;text-indent:2em;line-height: 2;background:#fff;}
.ml1{margin-left: -100%;}
.ml2{margin-left: -200%;}
.navI_active{position:relative;z-index:1;}
</style>

<div class="box">
    <ul class="nav">
        <li class="navI navI_active">
            <h2 class="navI-tit">課程</h2>
            <p class="navI-txt">課程內容</p>
        </li>
        <li class="navI">
            <h2 class="navI-tit">學習計劃</h2>
            <p class="navI-txt ml1">學習計劃內容</p>
        </li>
        <li class="navI">
            <h2 class="navI-tit">技能圖譜</h2>
            <p class="navI-txt ml2">技能圖譜內容</p>
        </li>
    </ul>   
</div>

【視覺佈局】瀏覽器

  從視覺佈局的角度來看,全部導航標題爲一組,全部導航內容爲一組佈局

<style>
body,p{margin: 0;}
ul{margin: 0;padding: 0;list-style: none;}
a{text-decoration: none;color: inherit;}
.box{width:572px;border:1px solid #999;font:14px "微軟雅黑";overflow:hidden;}
.nav-tit{margin-left: -1px;height: 40px;line-height: 40px;text-align: center;background-color: #f1f1f1;overflow: hidden;}
.nav-titI{box-sizing: border-box;float: left;width: 33.333%;border-left: 1px solid #cecece;border-bottom: 1px solid #cecece;cursor: pointer;}
.nav-txt{height: 200px;text-indent: 2em; line-height: 2;}
.nav-txtI{height: 200px;}
</style>

<div class="box">
    <nav class="nav-tit">
        <a class="nav-titI">課程</a>
        <a class="nav-titI">學習計劃</a>
        <a class="nav-titI">技能圖譜</a>
    </nav>
    <ul class="nav-txt">
        <li class="nav-txtI nav-txtI_active">課程內容</li>
        <li class="nav-txtI">學習計劃內容</li>
        <li class="nav-txtI">技能圖譜內容</li>
    </ul>
</div>

 

hover

  導航條的功能就是點擊導航標題時,顯示對應的導航內容。若是使用僞類hover實現相似效果,使用第一種佈局方式語義佈局比較合適學習

  因爲在語義佈局中,三個導航內容是處於重疊的狀態。移入其父元素.navI時,觸發鼠標的hover態,給父元素添加樣式爲position:relative;z-index:1;。從而提高了層級z-index。在其子元素導航內容的層級比拼中,「子憑父貴」,父元素層級高的,其導航內容在重疊狀態中顯示在最上面code

<style>
body,p{margin: 0;}
h2{margin: 0;font-size:100%;}
ul{margin: 0;padding: 0;list-style: none;}   
a{text-decoration: none;color:inherit;}
.box{width: 572px;border: 1px solid #999;overflow: hidden;}
.nav{margin-left: -1px;font: 14px "微軟雅黑";overflow: hidden;background-color: #f1f1f1;}
.navI{float: left;width: 33.333%;box-sizing: border-box;}
.navI-tit{line-height: 40px;text-align: center;cursor: pointer;border-left: 1px solid #cecece;border-bottom: 1px solid #cecece;}
.navI-txt{width: 572px;height:200px;text-indent:2em;line-height: 2;background:#fff;}
.ml1{margin-left: -100%;}
.ml2{margin-left: -200%;}
.navI_active{position:relative;z-index:1;}
/*重點代碼*/
.navI:hover{position:relative;z-index:1;}
.navI:hover .navI-tit{background:#fff;border-bottom:none;}
</style>

<div class="box">
    <ul class="nav">
        <li class="navI navI_active">
            <h2 class="navI-tit">課程</h2>
            <p class="navI-txt">課程內容</p>
        </li>
        <li class="navI">
            <h2 class="navI-tit">學習計劃</h2>
            <p class="navI-txt ml1">學習計劃內容</p>
        </li>
        <li class="navI">
            <h2 class="navI-tit">技能圖譜</h2>
            <p class="navI-txt ml2">技能圖譜內容</p>
        </li>
    </ul>   
</div>

  [缺點]:初始狀態時,第一個導航標題沒法實現默認被選中的狀態(背景白色,無下劃線);鼠標移出導航模塊時,導航內容部分沒法固定,顯示第一個導航內容;鼠標移出導航模塊時,導航標題的樣式沒法固定,恢復到默認狀態htm

 

錨點

  實現導航條的關鍵就在於如何創建導航標題與導航內容之間的聯繫,而錨點就能夠實現相似效果。經過點擊錨點,頁面生成一個哈希值,而後跳轉到相應內容的位置blog

  使用錨點技術時,使用語義佈局和視覺佈局均可以實現

【1】使用語義佈局

  使用語義佈局時,可使用僞類target,經過target選擇器來改變點擊導航標題時,當前標題的樣式。不只如此,由於要使用兄弟選擇器,因此須要改變HTML結構,將導航標題的HTML結構移到導航內容的下面

  點擊導航標題時,觸發target僞類,改變對應的導航內容的層級z-index,從而使當前導航內容在三個導航內容中勝出,在最上層顯示;與此同時,改變當前導航標題的樣式

<style>
body,p{margin: 0;}
h2{margin: 0;font-size:100%;}
ul{margin: 0;padding: 0;list-style: none;}   
a{text-decoration: none;color:inherit;}
.box{width: 572px;border: 1px solid #999;overflow: hidden;}
.nav{margin-left: -1px;font: 14px "微軟雅黑";overflow: hidden;background-color: #f1f1f1;}
.navI{float: left;width: 33.333%;box-sizing: border-box;position:relative;}
.navI-tit{position:absolute;top:0;left:0;right:0;box-sizing: border-box;line-height: 40px;height: 40px;text-align: center;cursor: pointer;border-left: 1px solid #cecece;border-bottom: 1px solid #cecece;}
.navI-txt{width: 572px;height:200px;margin-top: 40px;text-indent:2em;line-height: 2;background:#fff;}
.ml1{margin-left: -100%;}
.ml2{margin-left: -200%;}
.navI_active{z-index:1;}
/*重點代碼*/
.navI-txt:target{position:relative;z-index:1;}
.navI-txt:target ~ .navI-tit{background:#fff;border-bottom:none;}
</style>

<div class="box">
    <ul class="nav">
        <li class="navI navI_active">
            <p class="navI-txt" id="kc">課程內容</p>
            <a class="navI-tit" href="#kc">課程</a>
        </li>
        <li class="navI">
            <p class="navI-txt ml1" id="xx">學習計劃內容</p>
            <a class="navI-tit" href="#xx">學習計劃</a>
        </li>
        <li class="navI">
            <p class="navI-txt ml2" id="jn">技能圖譜內容</p>
            <a class="navI-tit" href="#jn">技能圖譜</a>
        </li>
    </ul>   
</div>

  [缺點]:初始態默認選中的導航標題樣式沒法設置;改變了HTML結構;錨點技術自己的侷限是錨點目標會盡量的到達可視區域上方,從而可能會生成頁面跳動

【2】使用視覺佈局

  在視覺佈局中,三個導航內容屬於同一個父元素,與父元素的高度相同,並按照塊級元素的排列方式進行排布,父元素設置溢出隱藏時,默認只顯示第一個導航內容

  點擊導航標題時,對應的導航內容到達導航標題行下面,達到了導航切換的效果

  使用僞類hover來實現改變當前導航標題樣式的效果

<style>
body,p{margin: 0;}
ul{margin: 0;padding: 0;list-style: none;}
a{text-decoration: none;color: inherit;}
.box{width:572px;border:1px solid #999;font:14px "微軟雅黑";overflow:hidden;}
.nav-tit{margin-left: -1px;height: 40px;line-height: 40px;text-align: center;background-color: #f1f1f1;overflow: hidden;}
.nav-titI{box-sizing: border-box;float: left;width: 33.333%;border-left: 1px solid #cecece;border-bottom: 1px solid #cecece;cursor: pointer;}
.nav-txt{height: 200px;text-indent: 2em; line-height: 2;}
.nav-txtI{height: 200px;}
/*重點內容*/
.nav-txt{overflow: hidden;}
.nav-titI:hover{background-color: white;border-bottom: none;}
</style>

<div class="box">
    <nav class="nav-tit">
        <a class="nav-titI" href="#kc">課程</a>
        <a class="nav-titI" href="#xx">學習計劃</a>
        <a class="nav-titI" href="#jn">技能圖譜</a>
    </nav>
    <ul class="nav-txt">
        <li class="nav-txtI nav-txtI_active" id="kc">課程內容</li>
        <li class="nav-txtI" id="xx">學習計劃內容</li>
        <li class="nav-txtI" id="jn">技能圖譜內容</li>
    </ul>
</div>

  [缺點]:初始態默認選中的導航標題樣式沒法設置;錨點技術自己的侷限是錨點目標會盡量的到達可視區域上方,從而可能會生成頁面跳動;hover態與點擊態分開,可能會讓人犯暈;鼠標移出導航模塊時,導航標題的樣式沒法固定,恢復到默認狀態

 

label

  上面使用錨點技術來聯繫導航標題和導航內容,而label也能夠實現相似的效果。label元素爲input元素定義標註,創建文字標籤與表單控件的關聯。在label元素內點擊文本會觸發此控件,選擇該文本時瀏覽器會自動把焦點轉到和標籤相關的表單控件上

  使用label時,使用語義佈局和視覺佈局均可以實現

【1】使用語義佈局

  使用語義佈局時,使用label標籤來顯示導航標題,且須要配合使用單選按鈕<input type="radio">。使用僞類checked,經過checked選擇器來改變點擊導航標題時,當前標題的樣式。不只如此,由於要使用兄弟選擇器,因此須要改變HTML結構,將單選按鈕放在每一個.navI元素裏的最上層,而後設置display:none,接下來是<label>表示導航標題,最後是<p>表示導航內容

  點擊導航標題時,觸發checked僞類,改變對應的導航內容的層級z-index,從而使當前導航內容在三個導航內容中勝出,在最上層顯示;與此同時,改變當前導航標題的樣式

<style>
body,p{margin: 0;}
h2{margin: 0;font-size:100%;}
ul{margin: 0;padding: 0;list-style: none;}  
input{margin: 0;width: 0;} 
a{text-decoration: none;color:inherit;}
.box{width: 572px;border: 1px solid #999;overflow: hidden;}
.nav{margin-left: -1px;font: 14px "微軟雅黑";overflow: hidden;background-color: #f1f1f1;}
.navI{float: left;width: 33.333%;box-sizing: border-box;}
.navI-tit{display:block;line-height: 40px;text-align: center;cursor: pointer;border-left: 1px solid #cecece;border-bottom: 1px solid #cecece;}
.navI-txt{position:relative;width: 572px;height:200px;text-indent:2em;line-height: 2;background:#fff;}
.ml1{margin-left: -100%;}
.ml2{margin-left: -200%;}
/*重點代碼*/
.navI-radio{display:none;}
.navI-radio:checked + .navI-tit{background:#fff;border-bottom:none;}
.navI-radio:checked ~ .navI-txt{z-index:1;}
</style>

<div class="box">
    <ul class="nav">
        <li class="navI">
            <input class="navI-radio" name="nav" type="radio" id="kc" checked>
            <label class="navI-tit" for="kc">課程</label>            
            <p class="navI-txt">課程內容</p>
        </li>
        <li class="navI">
            <input class="navI-radio" name="nav" type="radio" id="xx">
            <label class="navI-tit" for="xx">學習計劃</label>            
            <p class="navI-txt ml1">學習計劃內容</p>
        </li>
        <li class="navI">
            <input class="navI-radio" name="nav" type="radio" id="jn">
            <label class="navI-tit" for="jn">技能圖譜</label>            
            <p class="navI-txt ml2">技能圖譜內容</p>
        </li>
    </ul>   
</div>

  [缺點]:HTML結構較複雜

【2】使用視覺佈局

  在視覺佈局中,三個導航內容屬於同一個父元素,與父元素的高度相同,並按照塊級元素的排列方式進行排布,父元素設置溢出隱藏時,默認只顯示第一個導航內容

  點擊導航標題時,對應的導航內容到達導航標題行下面,達到了導航切換的效果

  使用僞類hover來實現改變當前導航標題樣式的效果

<style>
body,p{margin: 0;}
ul{margin: 0;padding: 0;list-style: none;}
a{text-decoration: none;color: inherit;}
input{margin: 0;padding: 0;border:none;}
.box{width:572px;border:1px solid #999;font:14px "微軟雅黑";overflow:hidden;}
.nav-tit{margin-left: -1px;height: 40px;line-height: 40px;text-align: center;background-color: #f1f1f1;overflow: hidden;}
.nav-titI{box-sizing: border-box;float: left;width: 33.333%;border-left: 1px solid #cecece;border-bottom: 1px solid #cecece;cursor: pointer;}
.nav-txt{height: 200px;}
.nav-txtI{height: 200px;display:block;width: 100%;text-indent: 2em; line-height: 2;}
/*重點內容*/
.nav-txt{overflow: hidden;}
.nav-titI:hover{background-color: #fff;border-bottom:none;}
</style>

<div class="box">
    <nav class="nav-tit">
        <label class="nav-titI" for="kc">課程</label>
        <label class="nav-titI" for="xx">學習計劃</label>
        <label class="nav-titI" for="jn">技能圖譜</label>
    </nav>
    <nav class="nav-txt">
        <input class="nav-txtI nav-txtI_active" id="kc" value="課程內容" readonly>
        <input class="nav-txtI" id="xx" value="學習計劃內容" readonly>
        <input class="nav-txtI" id="jn" value="技能圖譜內容" readonly>
    </nav>
</div>

  [缺點]:初始態默認選中的導航標題樣式沒法設置;有時會出現頁面跳動的效果;hover態與點擊態分開,可能會讓人犯暈;鼠標移出導航模塊時,導航標題的樣式沒法固定,恢復到默認狀態

 

最後

  上面的三種方法中,實現效果最好的是使用label標籤配合radio類型的input標籤,經過:checked選擇器來實現

  在實際應用中,使用javascript的方式來控制導航條Tab的狀況更爲廣泛

  歡迎交流

相關文章
相關標籤/搜索