##2.3 層次選擇器
層次選擇器通過HTML的DOM元素間的層次關系獲取元素,其主要的層次關系包括后代、父子、相鄰兄弟和通用兄弟幾種關系,通過其中某類關系可以方便快捷地選定需要的元素。
###2.3.1 層次選擇器語法
| 選擇器 | 類型 | 功能描述 |
| -------- | -----: | :----: |
| `E F` | 后代選擇器(包含選擇器) | 選擇匹配的F元素,且匹配的F元素被包含在匹配的E元素內 |
| `E > F` | 子選擇器 | 選擇匹配的F元素,且匹配的F元素是所匹配的E元素的子元素 |
| `E + F` | 相鄰兄弟選擇器 | 選擇匹配的F元素,且匹配的F元素緊位于匹配的E元素后面 |
| `E ~ F` | 通用兄弟選擇器 | 選擇匹配的F元素,且位于匹配的E元素后的所有匹配的F元素 |
###2.3.2 瀏覽器兼容性
> 子選擇器、相鄰兄弟選擇器和通用兄弟選擇器要IE7及以上版本才支持,隨著IE6的慢慢消失,層次選擇器可以放心使用。
###2.3.3 實戰體驗:使用層次選擇器選擇元素
在層次選擇器中,后代選擇器與子選擇器是比較常用的,而對于相鄰兄弟選擇器和通用兄弟選擇器而言,平時大家并不常使用,特別是CSS3選擇器中新增的通用兄弟選擇器。
- 頁面中有10個div元素,其中第四個div包含了2個div,另外第七個div包含了第八個,而第八個div又包含了第九個div,并且第九個div包含了第十個div。
----------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>使用CSS3層次選擇器</title>
<style>
*{margin: 0;padding: 0;}
body{width: 300px;margin: 0 auto;}
div{margin: 5px;padding: 5px;border: 1px solid #ccc;}
</style>
</head>
<body>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4
<div>5</div>
<div>6</div>
</div>
<div>7
<div>8
<div>9
<div>10</div>
</div>
</div>
</div>
</body>
</html>

為了更好的理清這些div的層次關系,可以先將示例中的body部分畫一個DOM樹形草圖,如下所示:

###2.3.4 后代選擇器
后代選擇器(`E F`也稱為包含選擇器,作用就是可以選擇某元素的后代元素。)
> **后代選擇器兩選擇符之間必須以空格隔開,中間不能有任何其他符號插入。**
*{margin: 0;padding: 0;}
body{width: 300px;margin: 0 auto;}
div{margin: 5px;padding: 5px;border: 1px solid #ccc;}
div div{background: orange;} /* 后代選擇器 */

###2.3.5 子選擇器
子選擇器(`E > F`)只能選擇某元素的子元素,其中E為父元素,而F為子元素,其中E > F表示選擇了E元素下所有子元素F。與后代選擇器不一樣的是,后代選擇器中F是E的后代元素,而子選擇器中,F僅僅是E的子元素而已。
*{margin: 0;padding: 0;}
body{width: 300px;margin: 0 auto;}
div{margin: 5px;padding: 5px;border: 1px solid #ccc;}
div div{background: orange;}
body > div{background: green;} /* 子選擇器 */

###2.3.6 相鄰兄弟選擇器
相鄰兄弟選擇器(`E + F`)可以選擇緊接在另一個元素后的元素,它們具有一個相同的父元素。換句話說,E和F是同輩元素,F元素在E元素后面,并且相鄰,這樣就可以使用相鄰兄弟選擇器來選擇F元素。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>使用CSS3層次選擇器</title>
<style>
*{margin: 0;padding: 0;}
body{width: 300px;margin: 0 auto;}
div{margin: 5px;padding: 5px;border: 1px solid #ccc;}
div div{background: orange;}
body > div{background: green;}
.active + div {background: lime;} /* 相鄰兄弟選擇器 */
</style>
</head>
<body>
<!-- 為了說明相鄰兄弟選擇器,在此處添加一個類名active -->
<div class="active">1</div>
<div>2</div>
<div>3</div>
<div>4
<div>5</div>
<div>6</div>
</div>
<div>7
<div>8
<div>9
<div>10</div>
</div>
</div>
</div>
</body>
</html>

###2.3.7 通用兄弟選擇器
通用兄弟選擇器(`E ~ F`)是CSS3新增加的,用于選擇某個元素后面的所有兄弟元素,他們和相鄰兄弟選擇器類似,需要在同一個父元素中。也就是說,E和F元素都是同輩元素,并且F元素在E元素之后,E ~ F將選中E元素后面的所有F元素。
*{margin: 0;padding: 0;}
body{width: 300px;margin: 0 auto;}
div{margin: 5px;padding: 5px;border: 1px solid #ccc;}
div div{background: orange;}
body > div{background: green;}
.active + div {background: lime;}
.active ~ div {background: red;}

> 通用兄弟選擇器中的是與E元素相鄰的后面兄弟元素F,其選中的是一個或多個元素;而相鄰兄弟選擇器中的僅是與E元素相鄰并且緊挨的兄弟元素F,其選中的僅是一個元素。
##2.4 動態偽類選擇器
偽類選擇器對于大家來說最熟悉的莫過于`":link",":visited",":hover",":active"`,因為這些是大家平時常用到的偽類選擇器。而CSS3的偽類選擇器可以分為六種:動態偽類選擇器、目標偽類選擇器、語言偽類選擇器、UI狀態偽類選擇器、結構為了選擇器和否定偽類選擇器。
> 偽類選擇器語法書寫時和其他的CSS選擇器寫法有所區別,都以冒號(`:`)開頭。例如:
E:pseudo-class {property:value} /* E為HTML元素;pseudo-class是css的偽類選擇器名稱;property是CSS的屬性;value是css屬性值 */
###2.4.1 動態偽類選擇器語法
| 選擇器 | 類型 | 功能描述 |
| -------- | -----: | :----: |
| `E:link` | 鏈接偽類選擇器 | 選擇匹配的E元素,而且匹配元素被定義了超鏈接并未被訪問過。常用于鏈接錨點上 |
| `E:visited` | 鏈接偽類選擇器 | 選擇匹配的E元素,而且匹配元素被定義了超鏈接并已被訪問過。常用于鏈接錨點上 |
| `E:active` | 用戶行為偽類選擇器| 選擇器匹配的E元素,且匹配元素被激活。常用于鏈接錨點上 |
| `E:hover` | 用戶行為偽類選擇器 | 選擇器匹配的E元素,且用戶鼠標停留在元素E上。IE6及以下瀏覽器僅支持`a:hover` |
| `E:focus` | 用戶行為偽類選擇器 | 選擇匹配的E元素,且匹配的元素獲得焦點 |
> **錨點偽類的設置必須遵守一個“愛恨原則” LoVe/HAte,也就是“link-visited-hover-active”。**
###2.4.2 瀏覽器兼容性
> `E:hover` 在IE6瀏覽器中僅支持鏈接錨點 `a:hover`
###2.4.3 實戰體驗:美化按鈕
根據用戶的行為不同,按鈕效果可以分為:默認狀態、懸浮狀態、點擊時狀態、焦點狀態和點擊后狀態,可以按照CSS3的動態偽類選擇器,在不同狀態下給按鈕賦予不同的樣式風格。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>使用動態偽類選擇器美化按鈕</title>
<style>
.download-info {
text-align: center;
}
/* 默認狀態下的按鈕效果 */
.btn {
background-color: #0074cc;
*background-color: #0055cc;
/* css3漸變制作背景圖片 */
background-image: -ms-linear-gradient(top, #0088cc, #0055cc);
background-image: -webkit-linear-gradient(linear, 0 0, 0 100%, form(#0088cc), to(#0055cc));
background-image: -webkit-linear-gradient(top, #0088cc, #0055cc);
background-image: -o-linear-gradient(top, #0088cc, #0055cc);
background-image: -moz-linear-gradient(top, #0088cc, #0055cc);
background-image: linear-gradient(top, #0088cc, #0055cc);
background-repeat: repeat-x;
display: inline-block;
*display: inline;
border: 1px solid #ccc;
*border: 0;
border-color: #ccc;
/* css3的色彩模塊 */
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
border-radius: 6px;
color: #fff;
cursor: pointer;
font-size: 20px;
font-weight: normal;
filter: progid:dximagetransform.microsoft.gradient(startColorstr='#0088cc', endColorstr='#0055cc', GradientType=0);
filter: progid:dximagetransform.microsoft.gradient(enabled=false);
line-height: normal;
padding: 14px 24px;
text-align: center;
/* css3文字陰影特性 */
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
text-decoration: none;
vertical-align: middle;
*zoom: 1;
}
/* 懸浮狀態下按鈕效果 */
.btn:hover {
background-position: 0 -15px;
background-color: #0055cc;
*background-color: #004ab3;
color: #fff;
text-decoration: none;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
/* CSS3動畫效果 */
-webkit-transition: background-position 0.1s linear;
-moz-transition: background-position 0.1s linear;
-ms-transition: background-position 0.1s linear;
-o-transition: background-position 0.1s linear;
transition: background-position 0.1s linear;
}
/* 點擊時按鈕效果 */
.btn:active {
background-color: #0055cc;
*background-color: #004ab3;
background-color: #004499 \9;
background-image: none;
outline: 0;
/* CSS3盒子陰影特性 */
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
color: rgba(255, 255, 255, 0.75);
}
/* 獲得焦點按鈕效果 */
.btn:focus {
outline: thin dotted #333;
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
</style>
</head>
<body>
<div class="download-info">
<p>默認狀態</p>
<a href="#" class="btn">View project on GitHub</a>
<p>懸浮狀態</p>
<a href="#" class="btn">View project on GitHub</a>
<p>點擊狀態</p>
<a href="#" class="btn">View project on GitHub</a>
<p>焦點狀態</p>
<a href="#" class="btn">View project on GitHub</a>
</div>
</body>
</html>

##2.5 目標偽類選擇器
目標偽類選擇器“`:target`”是總舵實用的CSS3特性中的一個,用來匹配文檔的URI中某個標志符的目標元素。
###2.5.1 目標偽類選擇器語法
| 選擇器 | 功能描述 |
| -------- | :----: |
| `E:target` | 選擇匹配E的所有元素,且匹配元素被相關URL指向 |
###2.5.2 瀏覽器兼容性
> 目標偽類選擇器在IE8及之前版本不被支持,但IE用戶點擊目錄里的鏈接仍將跳轉到相應的標題,只是標題不會高亮顯示。(需要兼容IE低版本瀏覽器,就要用到JacaScript。[Suckerfish:target](http://www.htmldog.com/articles/suckerfish/target) 或者 [Improving the usability of within-page links](http://dev.opera.com/articles/view/imporoving-the-usability-of-within-page-1))
###2.5.3 實戰體驗:制作手風琴效果
頁面中有三個區塊,默認狀態只顯示三個區塊的標題,點擊其中一個標題時,其對應的內容就會顯示;點擊另一個標題時,對應區塊內容將顯示,而前一塊內容將隱藏。通過`:target`,顯示和隱藏不同欄目的內容,從而實現手風琴效果。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>垂直手風琴</title>
<style>
.accordionMenu{
background: #fff;
color: #424242;
font: 12px Arial,Verdana,sans-serif;
margin: 0 auto;
padding: 10px;
width: 500px;
}
.accordionMenu h2{
margin: 5px 0;
padding: 0;
position: relative;
}
.accordionMenu h2:before { /* 制作向下三角效果 */
border: 5px solid #fff;
border-color: #fff transparent transparent;
content: '';
height: 0;
position: absolute;
right: 10px;
top: 15px;
width: 0;
}
.accordionMenu h2 a { /* 制作手風琴標題效果 */
background: #8f8f8f;
background: -moz-linear-gradient(top, #cecece, #8f8f8f);
background: -webkit-linear-gradient(top, #cecece, #8f8f8f);
background: -o-linear-gradient(top, #cecece, #8f8f8f);
background: linear-gradient(top, #cecece, #8f8f8f);
border-radius: 5px;
color: #424242;
display: block;
font-style: 13px;
font-weight: normal;
margin: 0;
padding: 10px;
text-shadow: 2px 2px 2px #aeaeae;
text-decoration: none;
}
.accordionMenu :target h2 a, /* 目標標題的效果 */
.accordionMenu h2 a:focus,
.accordionMenu h2 a:hover,
.accordionMenu h2 a:active {
background: #2288dd;
background: -moz-linear-gradient(top, #6bb2ff, #2288dd);
background: -webkit-linear-gradient(top, #6bb2ff, #2288dd);
background: -o-linear-gradient(top, #6bb2ff, #2288dd);
background: linear-gradient(top, #6bb2ff, #2288dd);
color: #fff;
}
.accordionMenu p { /* 標題欄對應的內容 */
margin: 0;
height: 0; /* 默認欄內容高度為0,達到隱藏效果 */
overflow: hidden;
padding: 0 10px;
-webkit-transition: height 0.5s ease-in;
-moz-transition: height 0.5s ease-in;
-o-transition: height 0.5s ease-in;
transition: height 0.5s ease-in;
}
/* 這部分是顯示內容的關鍵代碼 */
.accordionMenu :target p { /* 展開對應目標內容 */
height: 100px;
overflow: auto;
}
.accordionMenu :target h2:before { /* 展開時標題三角效果 */
border-color: transparent transparent transparent #fff;
}
</style>
</head>
<body>
<div class="accordionMenu">
<div class="menuSection" id="brand">
<h2><a href="#brand">Brand</a></h2>
<p>Lorem ipsum dolor...</p>
</div>
<div class="menuSection" id="promotion">
<h2><a href="#promotion">Promotion</a></h2>
<p>Lorem ipsum dolor...</p>
</div>
<div class="menuSection" id="event">
<h2><a href="#event">Event</a></h2>
<p>Lorem ipsum dolor...</p>
</div>
</div>
</body>
</html>

