##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>
![页面初步效果](http://upload-images.jianshu.io/upload_images/1875545-65af9e0b5520a0c2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
为了更好的理清这些div的层次关系,可以先将示例中的body部分画一个DOM树形草图,如下所示:
![body 的树形结构](http://upload-images.jianshu.io/upload_images/1875545-37da6be401389835.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
###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;} /* 后代选择器 */
![使用后代选择器的效果](http://upload-images.jianshu.io/upload_images/1875545-fcb59bc9234ea49b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
###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;} /* 子选择器 */
![使用子选择器的效果](http://upload-images.jianshu.io/upload_images/1875545-15be73c96c4c1c81.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
###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>
![使用相邻兄弟选择器效果](http://upload-images.jianshu.io/upload_images/1875545-1a6c23f1d91b0edf.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
###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;}
![使用通用兄弟选择器效果](http://upload-images.jianshu.io/upload_images/1875545-2cbbbbe59f70a1fc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
> 通用兄弟选择器中的是与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>
![美化按钮效果](http://upload-images.jianshu.io/upload_images/1875545-f79b6bd6e60dcee4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
##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>
![手风琴初始效果](http://upload-images.jianshu.io/upload_images/1875545-b45eba25bf8f232a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![手风琴效果](http://upload-images.jianshu.io/upload_images/1875545-c7701fff1b25d7e7.gif?imageMogr2/auto-orient/strip)