参考自《精通CSS 高级Web标准解决方案(第2版)》第6章
基础知识总结:
伪类和伪元素选择器:https://www.cnblogs.com/ihardcoder/p/5294927.html、https://www.cnblogs.com/zcynine/p/5008985.html
实战技术要点:
写CSS的一些体会(个人理解,待完善)
- 先整体后局部:先对宽泛的标签添加样式,再对特殊的标签进行覆盖。
- 注意及时对CSS进行合并,如果有公共部分可以提取出来,让CSS结构更清晰。
如何创建斜面边框,以及斜面边框颜色的选择
- 为了斜面边框效果,一般将元素上、左边框颜色相同(相近),下、右边框颜色相同(相近),且后者颜色更深。
- 通常对列表项的父元素列表边框设置为上述较深的颜色实现第一个列表项的斜面效果。
- 通常最后一个列表项的边框需要进行清理(水平列表项清理border-right,垂直列表项清理border-bottom)。
1. 创建基本的垂直导航条
【说明1 】通过对a标签的上边框设置浅色,下边框设置深色,来实现菜单项的斜面效果。具体实现中,ul.nav的四个方向边框的颜色(#486B02)与ul.nav a的下边框颜色一致,而ul.nav a的上边框颜色为#E4FFD3,ul.nav中最后一个li中的a标签的下边框如果不清理的话,那么会形成颜色为#486B02的双边框,影响美观,因此对其清理。
【说明2】:last-child和:first-child伪类选择器的兼容性,对于不支持其的浏览器,可以为相应元素添加class,进而设置样式。
效果

<ul class="nav">
<li class="selected">
<a href="home.htm">Home</a>
</li>
<li>
<a href="about.htm">About</a>
</li>
<li>
<a href="services.htm">Our services</a>
</li>
<li>
<a href="work.htm">Our work</a>
</li>
<li>
<a href="news.htm">News</a>
</li>
<li class="last">
<a href="contact.htm">Contact</a>
</li>
</ul>ul.nav {
margin:0;
padding:0;
list-style-type: none;
width:8em;
background-color: #8BD400;
border:1px solid #486B02;
}
ul.nav a {
display: block;
color:#2B3F00;
text-decoration: none;
border-top: 1px solid #E4FFD3;
border-bottom: 1px solid #486B02;
padding: 0.3em 1em;
}
ul.nav li.last a {
border-bottom: 0;
}
ul.nav a:hover,ul.nav a:focus,ul.nav li.selected a {
color:#E4FFD3;
background-color: #6DA203;
}
ul.nav li {
display: inline;
}2. 创建简单的水平导航条
效果
![]()
<ol class="pagination">
<li><a href="search.html?page=1" rel="prev">Prev</a></li>
<li><a href="search.htm?page=1">1</a></li>
<li class="selected">2</li>
<li><a href="search.htm?page=3">3</a></li>
<li><a href="search.htm?page=4">4</a></li>
<li><a href="search.htm?page=5">5</a></li>
<li><a href="search.html?page=3" rel="next">Next</a></li>
</ol>
ol.pagination {
margin:0;padding:0;list-style-type: none;
overflow:hidden;
}
ol.pagination li {
float:left;
margin-right: 0.6em;
}
ol.pagination a,ol.pagination li.selected {
display: block;
padding:0.2em 0.5em;
border: 1px solid #ccc;
text-decoration: none;
}
ol.pagination a:hover,ol.pagination a:focus,ol.pagination li.selected {
background-color: blue;
color:white;
}
ol.pagination a[rel="prev"],ol.pagination a[rel="next"] {
border:none;
}
ol.pagination a[rel="prev"]:before {
content: "\00AB";
padding-right: 0.5em;
}
ol.pagination a[rel="next"]:after {
content: "\00BB";
padding-left: 0.5em;
}3. Scuckerfish下拉菜单
如何利用元素隐藏+动态伪类选择器来实现下拉菜单(纯CSS的工具提示也是类似的)
- 把需要隐藏的内容嵌套在对应的标签中,再利用隐藏技术,如无依赖绝对定位+大的负值(left)偏移量;display:none;大的负值text-indent等等。
- 使用动态伪类选择器,如:hover,:focus,:active,当发生上述情况时,将隐藏内容显示,如left设置为auto或者其他正常值,display:block,text-indent设置为正常值等等。
水平菜单项的斜面边框效果:这里给ul.nav和ul.nav ul都设置了颜色为#486B02的边框,水平的列表项li中的a标签只设置水平方向的边框,左边框颜色为#E4FFD3,右边框颜色为#486B02,这样水平列表项就呈现了斜面边框的效果(第一个列表项由ul.nav的左边框以及第一个列表项中a标签的左边框合成)。水平方向最后一个列表项此时将有颜色为#486B02的双边框(分别来自ul.nav的右边框和自身的右边框),因此需要对其border-right进行清理。
垂直菜单的斜面边框效果:ul.nav ul中的a标签不设置水平方向边框,而是由ul.nav ul的水平边框代替(颜色为#486B02),对其设置颜色为#E4FFD3的上边框,颜色为#486B02的下边框,此时垂直方向最后一个列表项将有颜色为#486B02的双边框(分别来自ul.nav ul的下边框和自身的下边框),因此需要对其border-bottom进行清理。
垂直菜单的第一个列表项:这里对ul.nav ul采用无依赖的绝对定位,绝对定位元素会对普通元素进行覆盖,这里ul.nav ul的上边框(颜色为#486B02)将会覆盖原始ul.nav的下边框在具有隐藏垂直菜单的列表项的部分(颜色为#486B02),所以显示/隐藏菜单的效果实现了统一。垂直菜单的第一个列表项的的上边缘也就具有了斜面边框(分别来自ul.nav ul的颜色为#486B02的上边框,以及自身的颜色为#E4FFD3的上边框。)
3.1 书上实现的
效果(书上原本的颜色,所有边都是双边框形成的斜面效果)
效果中下拉菜单右侧有些“溢出”的感觉,不好看,不知是复现错了还是原始代码有问题。此外,关于边框折叠、、双边框、斜面边框等现象还需要进一步学习。

对代码中的颜色做了一定的替换便于分析,#486B02替换为red,#E4FFD3替换为blue。效果为
<ul class="nav">
<li class="first">
<a href="home.htm">Home</a>
</li>
<li>
<a href="products.htm">Products</a>
<ul>
<li><a href="products.htm">Silverback</a></li>
<li><a href="products.htm">Font Deck</a></li>
</ul>
</li>
<li>
<a href="services.htm">Services</a>
</li>
<li>
<a href="work.htm">Work</a>
</li>
<li>
<a href="news.htm">News</a>
<ul>
<li><a href="products.htm">Design</a></li>
<li><a href="products.htm">Development</a></li>
<li><a href="products.htm">Consultancy</a></li>
</ul>
</li>
<li class="last">
<a href="contact.htm">Contact</a>
</li>
</ul> ul.nav,ul.nav li ul {
margin:0;
padding:0;
list-style-type: none;
background-color: #8BD400;
border:1px solid #486B02;/*与a标签的右边框、下边框颜色一致,形成斜面边框*/
float: left;/*清除浮动子元素,同时对内部的内容产生包裹性,无需显式设置宽度*/
}
ul.nav li ul {
width:8em;
position: absolute;
left:-999px;/*隐藏下拉菜单*/
}
ul.nav li{
float: left;
width: 8em;
}
ul.nav a {
display: block;
color:#2B3F00;
text-decoration: none;
line-height: 2.1;
border-left:1px solid #E4FFD3;
border-right:1px solid #486B02;
padding:0.3em 1em;
}
ul.nav li li a {
border-top:1px solid #E4FFD3;/*与上一条规则中的左边框颜色一致,形成斜面边框*/
border-bottom:1px solid #486B02;/*与上一条规则中的右边框颜色一致,形成斜面边框*/
border-left:0;/*清除上一条规则中的左边框*/
border-right:0;/*清除上一条规则中的右边框*/
}
ul.nav a:hover,ul.nav a:focus{
color:#E4FFD3;
background-color: #6DA203;
}
ul.nav li:last-child a {
border-right:0;/*清除ul.nav>li:last-child a中的右边框*/
border-bottom:0;/*清除ul.nav ul li:last-child a中的下边框*/
}
ul.nav li:hover ul {
left:auto;/*鼠标悬停时显示下拉菜单*/
}3.2 自己实现的
大致思路与上面的相同,区别主要在于边框的处理采用的是单边框,以及垂直导航条的ul.nav ul以及其中的li标签不加浮动。
效果(所有边都是单边框无重叠)

<ul class="nav">
<li class="first">
<a href="home.htm">Home</a>
</li>
<li>
<a href="products.htm">Products</a>
<ul>
<li><a href="products.htm">Silverback</a></li>
<li><a href="products.htm">Font Deck</a></li>
</ul>
</li>
<li>
<a href="services.htm">Services</a>
</li>
<li>
<a href="work.htm">Work</a>
</li>
<li>
<a href="news.htm">News</a>
<ul>
<li><a href="products.htm">Design</a></li>
<li><a href="products.htm">Development</a></li>
<li><a href="products.htm">Consultancy</a></li>
</ul>
</li>
<li class="last">
<a href="contact.htm">Contact</a>
</li>
</ul> ul.nav,ul.nav li ul {
margin:0;
padding:0;
list-style-type: none;
overflow: hidden;/*为ul.nav清除浮动子元素,此时ul.nav ul中无浮动子元素*/
background-color: #8BD400;
}
ul.nav {
width:48em;
border:1px solid black;
}
ul.nav li ul {
width:8em;
position: absolute;
left:-999px;
}
ul.nav >li{
float: left;
width: 8em;
text-align: center;/*具有继承性*//*不设置a的padding,这里采用li的水平对齐*/
}
ul.nav a {
display: block;
color:#2B3F00;
text-decoration: none;
line-height: 2.1;
border-left:1px solid orangered;/*只设置左边框阻止水平边框折叠*/
}
ul.nav li li a {
border-bottom: 1px solid yellow;/*垂直下拉菜单补充下边框阻止垂直边框折叠*/
}
ul.nav a:hover,ul.nav a:focus{
color:#E4FFD3;
background-color: #6DA203;
}
ul.nav >li:first-child a {
border-left:0;/*清除ul.nav中第一个li中a标签的边框,阻止与ul.nav左边框的折叠*/
}
ul.nav ul li:first-child a {
border-top:1px solid yellow;/*补充垂直下拉菜单中第一个li中a标签的上边框*/
}
ul.nav >li:hover ul {
left:auto;
}4. CSS图像映射
利用图像映射可以将图像的一些区域指定为热点(hot spot)。
图像映射的实现技巧
- 对<a>标签进行扩展,将其中的内容替换为一个或者多个子标签。
- 利用有依赖的绝对定位来实现上述子标签的定位,尽管多个子标签位于同一个父元素中,但是可以利用定位使得它们处于页面上的不同位置。
- 充分发挥动态伪类选择器的作用,同一个父元素下的多个子元素,只要有一个被触发,如hover,那么整个父元素也被触发了,进而可以影响其他子元素的显示效果。
- 水平对齐的实现,包括两种具体情况:块级元素中行内内容的水平对齐、块级元素整体相对于包含块的水平对齐,前者使用text-align(可继承),后者采用对块级元素设置width,再利用绝对定位(有依赖)+left:50%+margin-left:-width/2来实现。
- 对于通过动态伪类选择器动态显示的元素,在开发时可以先将其显示出来,定位好,设置好样式,最后再实现动态效果。
4.1 简单的图像映射
效果:当鼠标悬停在下面图像的每个人身上时,显示矩形框(热点区域),单击这个框就会进入这个人的网站

4.2 flickr风格的图像映射
效果:当鼠标悬停在图像上,在每个人周围都会显示一个双边框,点击这个框所在区域(热点区域),能够进入这个人的网站。进一步将鼠标悬停在图像上的某个人身上时,上述边框周围又会显示一个新的边框用于突出显示,同时边框下方会显示说明。


鼠标悬停在图像上 鼠标悬停在图像的某个人身上
4.3 远距离翻转
远距离翻转是一种鼠标悬停事件,它在页面的其他地方触发显示方式的改变。
效果:图像上的每个人都有一个对应的矩形框(热点区域)和姓名,当鼠标悬停在这个人的姓名上时,图像上对应的矩形框也显示出来。同样,当鼠标悬停在图像上这个人的矩形框区域时,相应的姓名也将突出显示。

4.4 代码实现
(1)4.1 简单的图像映射
<div class="imagemap">
<img src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2096432854,4113309096&fm=26&gp=0.jpg"
width="200" height="200" alt="Some of a team">
<ul>
<li class="one">
<a href="http://baidu.com/" title="one">One</a>
</li>
<li class="two">
<a href="http://baidu.com/" title="two">Two</a>
</li>
<li class="three">
<a href="http://baidu.com/" title="three">Three</a>
</li>
<li class="four">
<a href="http://baidu.com/" title="four">Four</a>
</li>
</ul>
</div> .imagemap {
width:200px;height:200px;
position: relative;
}
.imagemap ul {
margin:0;padding:0;list-style-type: none;
}
.imagemap a {
display: block;
width:45px;height:45px;
position: absolute;
text-decoration: none;
text-indent:-1000em;
}
.imagemap li.one a {
left: 20px;
top: 15px;
}
.imagemap li.two a {
left: 60px;
top: 35px;
}
.imagemap li.three a {
left:110px;
top:40px;
}
.imagemap li.four a {
left:142px;
top:75px;
}
.imagemap a:hover,.imagemap a:focus {
border:1px solid #fff;
}(2)4.2 flickr风格的图像映射
<div class="imagemap">
<img src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2096432854,4113309096&fm=26&gp=0.jpg"
width="200" height="200" alt="Some of a team">
<ul>
<li class="one">
<a href="http://baidu.com/" title="one">
<span class="outer">
<span class="inner">
<span class="note">One</span>
</span>
</span>
</a>
</li>
<li class="two">
<a href="http://baidu.com/" title="two">
<span class="outer">
<span class="inner">
<span class="note">Two</span>
</span>
</span>
</a>
</li>
<li class="three">
<a href="http://baidu.com/" title="three">
<span class="outer">
<span class="inner">
<span class="note">Three</span>
</span>
</span>
</a>
</li>
<li class="four">
<a href="http://baidu.com/" title="four">
<span class="outer">
<span class="inner">
<span class="note">Four</span>
</span>
</span>
</a>
</li>
</ul>
</div> .imagemap {
width:200px;height:200px;
position: relative;
}
.imagemap ul {
margin:0;padding:0;list-style-type: none;
}
.imagemap a {
display: block;
position: absolute;
text-decoration: none;
border:1px solid transparent;
}
.imagemap a .outer {
display: block;
border: 1px solid transparent;
}
.imagemap a .inner {
display: block;
width:45px;height:45px;
border: 1px solid transparent;
}
.imagemap li.one a {
left: 20px;
top: 15px;
}
.imagemap li.two a {
left: 60px;
top: 35px;
}
.imagemap li.three a {
left:110px;
top:40px;
}
.imagemap li.four a {
left:142px;
top:75px;
}
.imagemap a:hover,
.imagemap a:focus {
border-color:#d4d82d;
}
.imagemap span.note {
font-size:10px;
position: absolute;
bottom: -1.5em;
text-align: center;
width: 3em;
left: -1000px;
margin-left: -1.5em;
background-color: #ffc;
}
.imagemap a:hover span.note,
.image a:focus span.note {
left:50%;
}
.imagemap:hover a .outer,
.imagemap a:hover .outer,
.imagemap:focus a .outer,
.imagemap a:focus .outer {
border-color:#000;
}
.imagemap:hover a .inner,
.imagemap a:hover .inner,
.imagemap:focus a .inner,
.imagemap a:focus .inner {
border-color:#fff;
}(3)4.3 远距离翻转
<div class="imagemap">
<img src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2096432854,4113309096&fm=26&gp=0.jpg"
width="200" height="200" alt="Some of a team">
<ul>
<li class="one">
<a href="http://baidu.com/" title="one">
<span class="hotspot"></span>
<span class="note">» One</span>
</a>
</li>
<li class="two">
<a href="http://baidu.com/" title="two">
<span class="hotspot"></span>
<span class="note">» Two</span>
</a>
</li>
<li class="three">
<a href="http://baidu.com/" title="three">
<span class="hotspot"></span>
<span class="note">» Three</span>
</a>
</li>
<li class="four">
<a href="http://baidu.com/" title="four">
<span class="hotspot"></span>
<span class="note">» Four</span>
</a>
</li>
</ul>
</div> .imagemap {
width:200px;height:200px;
position: relative;
}
.imagemap ul {
margin:0;padding:0;list-style-type: none;
}
.imagemap a {
display: block;
width:45px;height:45px;
text-decoration: none;
}
.imagemap a .hotspot {
position: absolute;
width:45px;height:45px;
}
.imagemap a .note {
position: absolute;
display: block;
width:5em;
right:-5em;
cursor: pointer;
}
.imagemap li.one a .note {
top: 0;
}
.imagemap li.two a .note {
top: 1.2em;
}
.imagemap li.three a .note {
top:2.4em;
}
.imagemap li.four a .note {
top:3.6em;
}
.imagemap .one a .hotspot {
left: 20px;
top: 15px;
}
.imagemap .two a .hotspot {
left: 60px;
top: 35px;
}
.imagemap .three a .hotspot {
left:110px;
top:40px;
}
.imagemap .four a .hotspot {
left:142px;
top:75px;
}
.imagemap a:hover .hotspot,
.imagemap a:focus .hotspot {
border:1px solid #fff;
}
.imagemap a:hover .note,
.imagemap a:focus .note {
color:#0066FF;
}