開本系列,談談一些有趣的 CSS
題目,題目類型天馬行空,想到什麼說什麼,不只爲了拓寬一下解決問題的思路,更涉及一些容易忽視的 CSS 細節。css
解題不考慮兼容性,題目天馬行空,想到什麼說什麼,若是解題中有你感受到生僻的 CSS 屬性,趕忙去補習一下吧。html
不斷更新,不斷更新,不斷更新,重要的事情說三遍。git
談談一些有趣的CSS題目(一)-- 左邊豎條的實現方法github
談談一些有趣的CSS題目(二)-- 從條紋邊框的實現談盒子模型佈局
談談一些有趣的CSS題目(三)-- 層疊順序與堆棧上下文知多少post
談談一些有趣的CSS題目(四)-- 從倒影提及,談談 CSS 繼承 inherit字體
談談一些有趣的CSS題目(五)-- 單行居中,兩行居左,超過兩行省略url
談談一些有趣的CSS題目(六)-- 全兼容的多列均勻佈局問題spa
談談一些有趣的CSS題目(七)-- 消失的邊界線問題code
全部題目彙總在個人 Github 。
不用 Javascript
,使用純 CSS
方案,實現相似下圖的導航欄切換:
CSS 的強大之處有的時候超乎咱們的想象,Tab 切換,常規而言確實須要用到必定的腳本才能實現。下面看看如何使用 CSS 完成一樣的事情。
實現 Tab 切換的難點在於如何使用 CSS 接收到用戶的點擊事情並對相關的節點進行操做。便是:
如何接收點擊事件
如何操做相關DOM
下面看看如何使用兩種不一樣的方法實現需求:
:target
僞類選擇器首先,咱們要解決的問題是如何接收點擊事件
,這裏第一種方法咱們採用 :target
僞類接收。
:target
是 CSS3 新增的一個僞類,可用於選取當前活動的目標元素。當 URL 末尾帶有錨名稱 #,就能夠指向文檔內某個具體的元素。這個被連接的元素就是目標元素(target element)。它須要一個 id 去匹配文檔中的 target 。
解釋很難理解,看看實際的使用狀況,假設咱們的 HTML
代碼以下:
<ul class='nav'>
<li>列表1</li>
<li>列表2</li>
</ul>
<div>列表1內容:123456</div>
<div>列表2內容:abcdefgkijkl</div>
因爲要使用 :target
,須要 HTML 錨點,以及錨點對應的 HTML 片斷。因此上面的結構要變成:
<ul class='nav'>
<li><a href="#content1">列表1</a></li>
<li><a href="#content2">列表2</a></li>
</ul>
<div id="content1">列表1內容:123456</div>
<div id="content2">列表2內容:abcdefgkijkl</div>
這樣,上面 <a href="#content1">
中的錨點 #content1
就對應了列表1 <div id="content1">
。錨點2與之相同對應列表2。
接下來,咱們就可使用 :target
接受到點擊事件,並操做對應的 DOM 了:
#content1,
#content2{
display:none;
}
#content1:target,
#content2:target{
display:block;
}
上面的 CSS 代碼,一開始頁面中的 #content1
與 #content2
都是隱藏的,當點擊列表1觸發href="#content1"
時,頁面的 URL 會發生變化:
由 www.example.com
變成 www.example.com#content1
接下來會觸發 #content1:target{ }
這條 CSS 規則,#content1
元素由 display:none
變成display:block
,點擊列表2亦是如此。
如此即達到了 Tab 切換。固然除了 content1 content2
的切換,咱們的 li
元素樣式也要不斷變化,這個時候,就須要咱們在 DOM 結構佈局的時候多留心,在 #content1:target
觸發的時候能夠同時去修改 li
的樣式。
在上面 HTML
的基礎上,再修改一下,變成以下結構:
<div id="content1">列表1內容:123456</div>
<div id="content2">列表2內容:abcdefgkijkl</div>
<ul class='nav'>
<li><a href="#content1">列表1</a></li>
<li><a href="#content2">列表2</a></li>
</ul>
仔細對比一下與上面結構的異同,這裏我只是將 ul
從兩個 content
上面挪到了下面,爲何要這樣作呢?
由於這裏須要使用兄弟選擇符 ~ 。
E~F{ cssRules } ,CSS3 兄弟選擇符(E~F) ,選擇 E 元素後面的全部兄弟元素 F。
注意這裏,最重要的一句話是 E~F 只能選擇 E 元素 以後 的 F 元素,因此順序就顯得很重要了。
在這樣調換位置以後,經過兄弟選擇符 ~ 能夠操做整個 .nav
的樣式。
#content1:target ~ .nav li{
// 改變li元素的背景色和字體顏色
&:first-child{
background:#ff7300;
color:#fff;
}
}
#content2:target ~ .nav li{
// 改變li元素的背景色和字體顏色
&:last-child{
background:#ff7300;
color:#fff;
}
}
上面的 CSS 規則中,咱們使用 ~ 選擇符,在 #content1:target
和 #content2:target
觸發的時候分別去控制兩個導航 li
元素的樣式。
至此兩個問題,1. 如何接收點擊事件
與 2. 如何操做相關DOM
都已經解決,剩下的是一些小樣式的修補工做。
<input type="radio">
&& <label for="">
上面的方法經過添加 <a>
標籤添加頁面錨點的方式接收點擊事件。
這裏還有一種方式可以接收到點擊事件,就是擁有 checked
屬性的表單元素, <input type="radio">
或者<input type="checkbox">
。
假設有這樣的結構:
<input class="nav1" type="radio"> <ul class='nav'> <li>列表1</li> </ul>
對於上面的結構,當咱們點擊 <input class="nav1" type="radio">
單選框表單元素的時候,使用 :checked
是能夠捕獲到點擊事件的。
.nav1:checked ~ .nav li { // 進行樣式操做 }
一樣用到了兄弟選擇符 ~
這樣,當接收到表單元素的點擊事件時,能夠經過兄弟選擇符 ~ 操做它的兄弟元素的樣式。
能夠試着點擊下面 codepen 中的單選框。
可是,這裏有個問題 咱們的 Tab 切換,要點擊的是<li>
元素,而不是表單元素,因此這裏很重要的一點是,使用 <label for="">
綁定表單元素。看看以下結構:
<input class="nav1" id="li1" type="radio"> <ul class='nav'> <li><label for="li1">列表1</label></li> </ul>
上面的 <li>
中,有一層 <label for="li">
,裏面的 for="li1"
意思是綁定 id 爲li1 的表單元素。
label 標籤中的 for 定義:for 屬性規定 label 與哪一個表單元素綁定。
這樣改造以後,當咱們點擊 <li>
元素的時候,至關於點擊了 <input class="nav1" id="li1" type="radio">
這個單選框表單元素,而這個表單元素被點擊選中的時候,又能夠被 :checked
僞類捕獲到。
這個時候,咱們就能夠將頁面上的表單元素隱藏,作到點擊 <li>
至關於點擊表單:
input{ display:none; }
這樣,應用到本題目,咱們應該創建以下 DOM 結構:
<div class="container"> <input class="nav1" id="li1" type="radio" name="nav"> <input class="nav2" id="li2" type="radio" name="nav"> <ul class='nav'> <li class='active'><label for="li1">列表1</label></li> <li><label for="li2">列表2</label></li> </ul> <div class="content"> <div class="content1">列表1內容:123456</div> <div class="content1">列表2內容:abcdefgkijkl</div> </div> </div>
使用兩個單選框,分別對應兩個導航選項,運用上面介紹的 label 綁定表單,:checked
接收點擊事件,能夠獲得第二解法。
看看最後的結果:
Demo戳我:純CSS導航切換(label 綁定 input:radio && ~)
全部題目彙總在個人 Github ,發到博客但願獲得更多的交流。
到此本文結束,若是還有什麼疑問或者建議,能夠多多交流,原創文章,文筆有限,才疏學淺,文中如有不正之處,萬望告知。