CSS 高级

1、CSS 盒模型(Box Model)

  所有 HTML 元素都可以看作是盒子,在 CSS 中,“Box Model”这一术语主要是在布局时使用。

  CSS 盒模型(Box Model)规定了处理元素内容、边框、内边距 和 外边距 的方式。

  CSS 盒模型本质上是一个盒子,封装周围的 HTML 元素,它包括:外填充也叫外边距(margin),边框(border),内填充也叫内边距(padding)和实际内容(content)。盒模型允许我们在其它元素和周围元素边框之间的空间放置元素。

  如下 CSS 盒子模型图:

CSS 盒子模型

  盒子模型的最内层是盒子的实际内容(content),显示文本和图像。直接包围内容的是内边距(padding),清楚内容周围的区域,内边距呈现了元素的背景,会受到框中填充的背景颜色影响。内边距的边缘是边框(border),边框以外是外边距(margin),外边距没有背景颜色,默认是透明的,因此不会遮挡其后的任何元素。背景应用于由内容和内边距、边框组成的区域。盒模型就好比一套茶杯,为了避免损坏,每个茶杯的周围都会被填充一些东西,这些填充就是内边距,再用盒子把茶杯装起来,装茶杯的盒子就是边框,一套茶杯不可能只有一个,所有的茶杯会用一个精美包装的大盒子再装起来,那么每个装茶杯的小盒子之间的距离就是外边距。

  内边距、边框和外边距都是可选的,默认值是零。但是,许多元素将由浏览器样式表(浏览器缺省值)设置外边距和内边距。因此可以将元素的 margin 和 padding 设置为零来覆盖这些浏览器样式。

  在 CSS 中,width 和 height 指的是内容区域的宽度和高度。增加内边距、边框和外边距不会影响内容区域的尺寸,但是会增加元素盒子的总尺寸。为了确保在所有浏览器中元素的宽度和高度设置正确,有必要了解盒模型是如何工作的。

  当指定一个 CSS 元素的宽度和高度属性时,只是设置了内容区域的宽度和高度,完全大小的元素,还必须添加内边距,边框和外边距。如下设置盒子的样式:

1 #box{
2     width:200px;
3     height:100px;
4     padding:20px;
5     border:10px solid blue;
6     margin:30px;
7 }

  上面例子中,ID 为 box 的宽为 200 像素,高为 100 像素,内边距为 20 像素,边框为 10 像素,外边距是 30 像素,下图是在 Firefox 中计算出的布局样式:

  那么该元素的总宽度实际为30+10+20+200+20+10+30= 320px

  实际高度为:30+10+20+100+20+10+30= 220px

  最终元素的总宽度计算公式是:总元素的宽度=内容宽度+左外边距+右外边距+左边框+右边框+左内边距+右内边距。

  元素的总高度最终计算公式是:总元素的高度=内容高度+顶外边距+底外边距+顶边框+底边框+顶内边距+底内边距。

  根据 W3C 的规范,元素内容占据的空间是由 width 属性设置的,而内容周围的 padding 和 border 值是另外计算的。内边距、边框和外边距可以应用于一个元素的所有边,也可以应用于单独的边。外边距可以是负值,而且在很多情况下都要使用负值的外边距,内边距不可以是负值。

  margin 属性的值设为负值即负边距,在 CSS 布局中是一个很有用的技巧。当 margin-top 、 margin-left 为负值的时候,会把元素上移、左移,同时文档流中的位置也发生相应变化,这点与 position:relative 的元素设置 top、left 后元素还占据原来位置不同。当 margin-bottom 、 margin-right 设为负值的时候,元素本身没有位置变化,后面的元素会下移、右移。

  当元素被设置为绝对定位时,其 top、right、bottom、left 值是指元素自身的边界到最近的已定位祖先元素的距离,这个元素自身的边界指的就是 margin 定义的边界,所以,如果 margin 为正的时候,那它的边界是向外扩的,即下移/右移,如果 margin 为负的时候,则它的边界是向内收的,即上移/左移,利用这点,就有了经典的利用绝对定位来居中的方法:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>垂直居中</title>
 6 <style>
 7 *{padding;margin:0;}
 8 #box{
 9     width:200px;
10     height:200px;
11     margin:10px auto;
12     border:1px solid blue;
13     position:relative;
14 }
15 #box .content{
16     width:100px;
17     height:100px;
18     background:green;
19     position:absolute;
20     top:50%;
21     left:50%;
22     margin-top:-50px;
23     margin-left:-50px;
24 }
25 </style>
26 </head>
27 <body>
28 <div id="box">盒子
29   <div class="content">内容</div>
30 </div>
31 </body>
32 </html>

  把元素设置为绝对定位,然后设置 top 和 left 为 50%,这时候元素的上边界、左边界就到了父元素的 50% 处,再对元素设置其自身宽度和高度一半的负边距,使元素中心移动到父元素中心,实现居中对齐。

  负边距对于浮动元素的影响和上面的情况一样,不过有其特殊性,如下:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>负边距对浮动元素的影响</title>
 6 <style>
 7 *{padding;margin:0;}
 8 #box{
 9     width:280px;
10     border:1px solid black;
11     overflow:hidden;
12 }
13 #box .float{
14     width:100px;
15     height:100px;
16     float:left;
17 }
18 #box .float:nth-child(1){
19     background:red;
20 }
21 #box .float:nth-child(2){
22     background:yellow;
23 }
24 #box .float:nth-child(3){
25     background:blue;
26 }
27 </style>
28 </head>
29 <body>
30 <div id="box">
31   <div class="float">1</div>
32   <div class="float">2</div>
33   <div class="float">3</div>
34 </div>
35 </body>
36 </html>

  上面代码中,在一个宽度为 280px 的 div 的容器中向左浮动3个子 div 元素,宽度都为 100px ,由于一行放不下,最后一个会被移动到下一行显示,如果给第三个元素添加 -20px 的外边距,这时候第三个元素就移上去了,并且覆盖了第二个元素 20px ,经典的多列布局正是利用此原理

1 #box .float:nth-child(3){
2     background:blue;
3     margin-left:-20px;
4 }

  实例:两列布局

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>两列布局</title>
 6 <style>
 7 *{padding;margin:0;font:bold 18px "微软雅黑";}
 8 #box{
 9     width:500px;
10     border:1px solid black;
11     margin:10px auto;
12     overflow:hidden;
13 }
14 #box .wrap{
15     width:100%;
16     float:left;
17 }
18 #box .wrap .content{
19     height:200px;
20     margin-right:100px;
21     background:pink;
22 }
23 #box .right{
24     width:100px;
25     height:200px;
26     background:lightgreen;
27     float:left;
28     margin-left:-100px;
29 }
30 </style>
31 </head>
32 <body>
33 <div id="box">
34     <div class="wrap">
35         <div class="content">
36             1左列内容 2左列内容 3左列内容 4左列内容 5左列内容 6左列内容 7左列内容 8左列内容 9左列内容
37         </div>
38     </div>
39     <div class="right">右列内容</div>
40 </div>
41 </body>
42 </html>

  上面的代码很好理解,为 content 元素定义父元素,设置左浮动,宽度为 100%,再为 content 元素设置右边距,值等于 right 元素的宽度,最后给 right 元素设置左浮动,再设置其宽度的负边距为 content 元素设置右边距,即自身宽度。

  本来 right 元素应该在第二行显示,但是左浮动使它到了第一行的最右边,覆盖了 wrap 元素的一部分,但是 content 元素有 right 元素宽度的右边距,所以覆盖区域没有内容,这样就实现了两列布局。注意:如果不给 content 元素设置 right 元素宽度的右边距,那么 content 元素的内容则会被覆盖掉。其它此类更复杂的布局原理与其类似。

2、CSS 边框

  CSS border 属性可以为元素指定边框的宽度、样式和颜色。元素的边框是围绕元素内容和内边距的一条或多条线。

  在 CSS 规范中指出,边框是绘制在“元素的背景之上”。这很重要,因为有些边框是“间断的“,如:点线边框或虚线框,元素的背景应当出现在边框的可见部分之间。CSS2 指出背景只延伸到内边距,而不是边框。在 CSS2.1 中定义:元素的背景是内容、内边距和边框区的背景。

  (1)、边框样式(border-style)

  border-style 属性用来定义边框的样式。边框样式属性指定要显示什么样的边界,样式是边框最重要的一个属性,如果没有样式,将根本没有边框。

  CSS 的 border-style 属性定义了 10 个不同的非 inherit(继承) 样式,包括 none 和 hidden,该属性无继承。如下:

    ①、默认值为 none:无边框。border-color 将被忽略,border-width 计算值为0,除非边框轮廓为图像,即 border-image。

    ②、hidden:隐藏边框。

    ③、dotted:点状框。

    ④、dashed: 虚线框。

    ⑤、solid: 实线框。

    ⑥、double: 双线框。 两条单线的宽度和 border-width 值相同。

    ⑦、groove: 3D 凹槽框。效果取决于边界的颜色值。

    ⑧、ridge: 3D 凸槽框。效果取决于边界的颜色值。

    ⑨、inset:3D 嵌入(凹)边框。效果取决于边界的颜色值。

    ⑩、outset:3D 突出(凸)边框。效果取决于边界的颜色值。

  border-style 属性可以定义多种样式,即为一个边框定义多个样式,如下:

 1 <head>
 2 <style>
 3 #box{
 4     width:500px;
 5     height:300px;
 6     color:blue;
 7     background:lightgreen;
 8     border-style:solid dotted dashed double;
 9 }
10 </style>
11 </head>
12 <body>
13 <div id="box">
14 内容
15 </div>
16 </body>

  上面例子中,为 div 元素的边框样式分别为:顶边框为实线框,右边框为点状框,底边框为虚线框,左边框为双线框。

  border-style 属性可以设置一个元素四个边框的样式,可以有 1-4 个值:

    ①、如果提供全部四个参数值,将按上、右、下、左的顺序作用于四边。

    ②、如果只提供一个,将用于全部的四边。

    ③、如果提供两个,第一个用于上、下,第二个用于左、右。

    ④、如果提供三个,第一个用于上,第二个用于左、右,第三个用于下。

  该属性属于复合属性,也叫简写属性,如果只为元素框的某一个边框设置样式,而不是设置所有 4 个边的边框样式,可以使用下面的单边边框样式属性:

    ①、border-top-style 设置或检索对象顶边框样式。

    ②、border-right-style 设置或检索对象右边框样式。

    ③、border-bottom-style 设置或检索对象底边框样式。

    ④、border-left-style 设置或检索对象左边框样式。

  因此,这两种方法是等同的:

1 #box1{
2     border-style:none solid solid solid;
3 }
4 #box2{
5     border-style:solid;
6     border-top-style:none;
7 }

  需要注意:如果使用第二种方法,必须把单边属性放在简写属性之后。因为如果把单边属性放在 border-style 之前,简写属性的值就会覆盖单边值 none。

  (2)、边框宽度(border-width)

  通过 border-width 属性可以为边框指定宽度。

  为边框指定宽度有两种方法:

  ①、可以指定长度值,比如 2px 或 0.1em。

  ②、使用关键字设置,默认值为 medium 定义中等的边框, thin 定义细边框,thick 定义粗边框。

  需要注意:CSS 没有定义 3 个关键字的具体宽度,所以一个浏览器可能把 thin 、medium 和 thick 分别设置为等于 2px、3px 和 5px,而另一个浏览器则分别设置为 1px、2px 和 3px。通常建议为元素指定长度值的边框。

  border-width 属性可以设置一个元素四个边框的宽度,可以有 1-4 个值,和 border-style 属性相同。

    ①、该属性有 1个 值时,对应元素的四个边框。

    ②、该属性有 2个 值时,对应元素的顶、底边框,右、左边框。

    ③、该属性有 3个 值时,对应元素的顶边框,右、左边框,底边框。

    ④、该元素有 4个 值时,对于元素的顶边框,右边框,底边框,左边框。

  该属性属于复合属性,可以使用单独的属性为每个边框指定宽度:

    ①、border-top-width 设置或检索对象顶边框的宽度。

    ②、border-right-width 设置或检索对象右边框的宽度。

    ③、border-bottom-width 设置或检索对象底边框的宽度。

    ④、border-left-width 设置或检索对象左边框的宽度。

  在前面的例子中,如果要显示某种边框,就必须设置边框样式,比如 solid 或 dashed。如果把 border-style 设置为 none,如下:

 1 <head>
 2 <style>
 3 #box1{
 4     border-style:none;
 5     border-width:10px;
 6 }
 7 #box2{
 8     border-style:solid;
 9     border-width:10px;
10 }
11 </style>
12 </head>
13 <body>
14 <div id="box1">
15 内容 内容
16 </div>
17 <div id="box2">
18 内容
19 </div>
20 </body>

  通过上面的例子,可以看到,尽管 box1 的边框的宽度是 10px,但是边框样式设置为 none。在这种情况下,不仅边框的样式没有了,其宽度也会变成 0。边框消失了,这是因为如果边框样式为 none,即边框根本不存在,那么边框就不可能有宽度,因此边框宽度自动设置为 0,而不论宽度定义的是多少。这一点非常重要,根据下面规则,所有 h1 元素都不会有任何边框,更不用说 50 像素宽了:

1 h1{
2     border-width:50px;
3 }

  border-style 属性的默认值是 none,如果没有声明样式,就相当于 border-style:none。所以,如果要想显示边框,就必须声明一个边框样式。

  (3)、边框颜色(border-color)

  border-color 属性用于设置边框的颜色。可以使用任何颜色类型的值,如指定颜色的名称,”red”。如指定 RGB 值,”rgb(255,0,0)”。如指定16进制值, “#FF0000″。该属性的默认值为 “transparent” 指定边框的颜色为透明。注意: border-color 单独使用是不起作用的,必须得先使用 border-style 来设置边框样式。

  border-color 属性可以设置一个元素四个边框的颜色,可以有 1-4 个值,和 border-width 属性相同,即按照 top-right-bottom-left 的顺序设置元素的各边边框。

  该属性属于复合属性,可以使用单独的属性为每个边框指定颜色:

    ①、border-top-color 设置或检索对象顶边框的颜色。

    ②、border-right-color 设置或检索对象右边框的颜色。

    ③、border-bottom-color 设置或检索对象底边框的颜色。

    ④、border-left-color 设置或检索对象左边框的颜色。

  默认边框颜色是元素本身的前景色。如果没有为边框设置颜色,它将与元素的文本颜色相同。另一方面,如果元素没有任何文本,假设它是一个表格,其中只包含图像,那么该表格的边框颜色就是其父元素的文本颜色,因为 color 属性可以继承,这个父元素很可能是 body、div 或另一个 table。

  我们可以为网页上的文字赋予颜色,这就使用到了 CSS 的前景色,前景色使用 color 属性,且通常使用在文字上。与前景色相对应的就是 CSS 背景色,背景色不同于前景色,文字颜色可以使用 color 属性,但是包含文字的 p、div、body 等元素的背景颜色则使用 background-color 属性,前景色具有继承性,而背景色则没有继承。

  综上所述,前景色影响边框颜色,如下面的实例,不设置 div 元素的边框颜色:

 1 <head>
 2 <style>
 3 #box{
 4     width:200px;
 5     height:100px;
 6     border-style:solid;
 7     border-width:5px;
 8     background:lightgreen;
 9 }
10 </style>
11 </head>
12 <body>
13 <div id="box">
14 内容
15 </div>
16 </body>

  上面的例子,给 div 元素设置了背景色为浅绿色,可以看到,元素的背景区包含前景之下直到边框外边界的所有空间,包含内容、内边距,且延伸到边框。而前景色则影响到了边框颜色,例子中没有设置边框颜色,但是前景色默认是黑色,因此边框也显示为黑色,如果给文本定义前景色,那么边框就显示为元素的前景色:

1 #box{
2     width:200px;
3     height:100px;
4     color:red;
5     border-style:solid;
6     border-width:5px;
7     background:lightgreen;
8 }

  上面的例子,给 div 元素设置了前景色为红色,可以看到,边框也显示为红色。‘

  透明边框:

  如果边框没有样式,就没有宽度,不过可以创建一个不可见的边框。即使用 border-color 属性的默认值 transparent 指定边框的颜色为透明,从而可以创建有宽度的不可见边框,如下:

 1 <head>
 2 <style>
 3 a:link, a:visited{
 4     border-style:solid;
 5     border-width:5px;
 6     border-color:transparent;
 7 }
 8 a:hover{
 9     border-color:gray;
10 }
11 </style>
12 </head>
13 <body>
14 <a href="#">AAA</a>
15 <a href="#">BBB</a>
16 <a href="#">CCC</a>
17 </body>

  从某种意义上来说,利用 transparent,使用边框就像是额外的内边距一样,此外还有一个好处,就是能在需要的时候使其可见。这种透明边框相当于内边距,因为元素的背景会延伸到边框区域,如果给 a 元素再添加一个背景属性,就能更形象的展示这种效果。

  (4)、边框属性简写属性

  border 属性属于复合属性,使用该属性可以把边框属性设置在一个声明中。比如 border:1px solid red;

  当使用简写属性时,属性值的顺序依次为:

    border-width –> border-style –> border-color

  如果上述值缺少一个也没有关系,例如 border:solid red,也是允许的。

  还可以使用单独的复合属性为每个边框设置特性:

    ①、border-top 设置对象顶边框的特性。

    ②、border-right 设置对象右边框的特性。

    ③、border-bottom 设置对象底边框的特性。

    ④、border-left 设置对象左边框的特性。

3、CSS 轮廓

  轮廓(outline)是绘制于元素周围的一条线,位于边框边缘的外围,可起到突出元素的作用。

  CSS outline 属性规定元素轮廓的样式,颜色和宽度。该属性和 border 属性一样,同为复合属性,不同的是 border 属性作用于内容和内边距外围,而 outline 属性作用于 border 属性外围。轮廓也可以叫做外边框。

  下面的实例,在 div 元素的外围绘制一条边框,再给边框绘制一条轮廓:

 1 <head>
 2 <style>
 3 #box{
 4     border:2px solid red;
 5     outline:4px dotted green;
 6 }
 7 </style>
 8 </head>
 9 <body>
10 <div id="box">
11 内容
12 </div>
13 </body>

  也可以使用单独的属性为边框设置特性:

    ①、outline-width 设置或检索对象外的线条轮廓的宽度。

    ②、outline-style 设置或检索对象外的线条轮廓的样式。

    ③、outline-color 设置或检索对象外的线条轮廓的颜色。

4、CSS 内边距

  元素的内边距在边框和内容区之间,控制该区域最简单的属性是 padding 属性。

  CSS padding 属性定义元素边框与元素内容之间的空间,即内边距,该属性接受任何类型的长度单位或百分比值,但不允许使用负值。百分数值是相对于其父元素的 width 计算的,这一点与外边距一样。所以,如果父元素的 width 改变,它们也会改变。如果上下内边距与左右内边距一致,即上下内边距的百分数会相对于父元素宽度设置,而不是相对于高度。

  内边距也叫做填充,当元素的 padding 被清除时,所“释放”的区域将会受到元素背景颜色的填充。

  (1)、单边内边距

  padding 属性属于复合属性,可以使用单独的属性设置元素的内边距:

    ①、padding-top 设置元素的顶内边距。

    ②、padding-right 设置元素的右内边距。

    ③、padding-bottom 设置元素的底内边距。

    ④、padding-left 设置元素的左内边距。

  (2)、内边距属性简写

  padding 属性允许在一个声明中设置元素所有的内边距属性,可以有 1-4 个值。

    ①、如果提供全部四个参数值,将按上、右、下、左的顺序作用于四边。

    ②、如果只提供一个,将用于全部的四边。

    ③、如果提供两个,第一个用于上、下,第二个用于左、右。

    ④、如果提供三个,第一个用于上,第二个用于左、右,第三个用于下。

  这个简写属性设置元素所有内边距的宽度,或者设置各边上内边距的宽度。内非替换元素上设置的内边距不会影响行高计算,因此,如果一个元素既有内边距又有背景,元素的背景会延伸穿过内边距,从视觉上看可能会延伸到其他行,有可能还会与其他内容重叠。

5、CSS 外边距

  围绕在元素边框的空白区域是外边距,设置外边距会在元素外创建额外的“空白”。

  CSS margin 属性设置元素周围的空间,即外边距,该属性属性接受任何类型的长度单位、百分比值,甚至是负值。百分数是相对于父元素的 width 计算的,负值则重叠内容。

  外边距清除周围的元素边框外的区域,margin 没有背景颜色,是完全透明的。

  margin 属性的值可以是 auto 浏览器计算外边距,这样做的结果会依赖于浏览器,更常见的做法是为外边距设置长度值。但是设置为 auto 也有一个好处,那就是可以在页面上居中一个元素。下面的例子,将 div 元素的上下外边距设置为 0,左右外边距设置为 auto,就可以实现该元素在页面上居中显示。

 1 <head>
 2 <style>
 3 *{padding:0;margin:0;}
 4 #box{
 5     width:400px;
 6     height:200px;
 7     background:green;
 8     margin:0 auto;
 9 }
10 </style>
11 </head>
12 <body>
13 <div id="box">
14 内容
15 </div>
16 </body>

  margin 属性的默认值是 0,所以如果没有为 margin 声明一个值,就不会出现外边距。但是,在实际中,浏览器对许多元素提供了预定的样式,外边距也不例外。例如,在浏览器中,外边距会在每个段落元素的前边和后边生成一个“空行”。因此,如果没有为 p 元素声明外边距,浏览器会自己应用一个外边距。当然,如果特别作了声明,就会覆盖默认样式。

  (1)、单边外边距

  margin 属性属于复合属性,可以使用单独的属性设置元素的外边距:

    ①、margin-top 设置元素的顶外边距。

    ②、margin-right 设置元素的右外边距。

    ③、margin-bottom 设置元素的底外边距。

    ④、margin-left 设置元素的左外边距。

  (2)、外边距属性简写

  margin 属性允许在一个声明中设置元素所有的外边距属性,可以有 1-4 个值。

    ①、如果提供全部四个参数值,将按上、右、下、左的顺序作用于四边。

    ②、如果只提供一个,将用于全部的四边。

    ③、如果提供两个,第一个用于上、下,第二个用于左、右。

    ④、如果提供三个,第一个用于上,第二个用于左、右,第三个用于下。

  这个简写属性设置一个元素所有外边距的宽度,或者设置各边上外边距的宽度。块级元素的垂直相邻外边距会重叠,而行内元素实际上不占上下外边距,行内元素的的左右外边距不会重叠。同样地,浮动元素的外边距也不会重叠。允许指定负的外边距值,不过需要小心使用。

  (3)、外边距重叠

  外边距重叠,也叫外边距合并,指的是当两个或多个垂直外边距相遇时,它们将形成一个外边距,重叠后的外边距的高度等于两个发生重叠的外边距的高度中的较大者。如果出现负边距,则都取绝对值,然后用正值减去最大值。如果都为负边距,则都取绝对值,然后用零减去最大值。

  外边距合并叠加是不难理解,但是,在实践中对网页进行布局时,它会造成许多混淆。

  当一个元素出现在另一个元素上面时,第一个元素的下外边距与第二个元素的上外边距会发生重叠。如下:

 1 <head>
 2 <style>
 3 *{padding:0;margin:0;}
 4 #box1{
 5     width:100px;
 6     height:100px;
 7     background:red;
 8     margin-top:20px;
 9     margin-bottom:20px;
10 }
11 #box2{
12     width:100px;
13     height:100px;
14     background:blue;
15     margin-top:30px;
16 }
17 </style>
18 </head>
19 <body>
20 <div id="box1">
21 1
22 </div>
23 <div id="box2">
24 2
25 </div>
26 </body>

  上面的例子,box1 设置了底外边距为 20px,box2 设置了顶外边距为 30px,在 Firefox 中打开上面的文档,鼠标分别移动到 box1 和 box2 元素上,可以看到,这两个元素的外边距是 30px,而不是 50px(20px+30px)。

  发生重叠的条件是子元素的上外边距或下外边距与父元素的上边界或下边界之间不能出现 padding 或 border。当一个元素包含在另一个元素中时,假设没有内边距或边框把外边距分隔开,它们的上 和/或 下外边距也会发生重叠。如下:

 1 <head>
 2 <style>
 3 *{padding:0;margin:0;}
 4 #box1{
 5     width:200px;
 6     height:200px;
 7     background:red;
 8     margin-top:20px;
 9 }
10 #box2{
11     width:50px;
12     height:50px;
13     background:blue;
14     margin-top:30px;
15 }
16 </style>
17 </head>
18 <body>
19 <div id="box1">
20     <div id="box2">
21     </div>
22 </div>
23 </body>

   如果不设置 div 的内边距和边框,那么内部 div 的上外边距将与外部 div 的上外边距叠加,此时2个 div 距离页面顶部的距离为 30px。

  甚至外边距可以与自身发生重叠,假设有一个空元素,它有外边距,但是没有边框或填充。在这种情况下,上外边距与下外边距就碰到了一起,它们就会发生重叠。如果这个外边距遇到另一个元素的外边距,它还会发生重叠。这就是一系列的段落元素占用空间非常小的原因,因为它们的所有外边距都重叠在一起,形成了一个小的外边距。

  外边距的重叠只产生在普通流文档的上下外边距之间,这个看起来有点奇怪的规则,但是实际上,它是有意义的。假设上下排列一系列规则的块级元素时,比如段落,第一个段落上面的空间等于段落的上外边距。如果没有外边距重叠,后续所有段落之间的外边距都将是相邻上外边距和下外边距的和。这意味着段落之间的空间是页面顶部的两倍,因为块元素之间存在外边距重叠,段落之间就不会产生双倍的距离,段落之间的上外边距和下外边距就合并在一起,这样各处的距离就一致了。

  注意:只有两个或多个普通文档流中块元素的垂直外边距才会发生外边距重叠。行内元素、浮动元素或绝对定位之间的外边距不会合并,且水平边距永远不会重叠,根元素的垂直边距也不会被重叠。

  合并操作是以 margin、padding、border 的值为基础的,即在浏览器解析所有这些值之后,合并后的 margin 计算将覆盖已使用的不同 margin 的值。因此,简单为元素添加 padding 或者 border 就可以不使边距重叠。给内层元素可以设置透明边框 border:1px solid transprent,或者给内层元素设置内边距 padding:1px。

6、CSS 尺寸和长度单位

  (1)、尺寸

  CSS 尺寸属性可以控制元素的高度和宽度。同样,它也可以增加行间距。CSS 尺寸属性如下:

属性 说明
width 设置元素的宽度
height 设置元素的高度
line-height 设置行高
max-width 设置元素的最大宽度
max-height 设置元素的最大高度
min-width 设置元素的最小宽度
max-height 设置元素的最小高度

  (2)、长度单位

  在写 CSS 时最常用到的单位长度就是 px(像素),也会使用 em 、%(相对父元素的大小) 单位等等,其实 CSS 中的长度单位有8个:px,em,ex,pt,pc,in,mm,cm

  ①、相对长度单位

  相对长度单位是网页中的基本单位,既然是相对,那就表明了其长度单位会随着他的参考值的变化而变化,不是固定的。因为相对单位没有一个可观的测量,相反,他们的实际大小是通过父元素的尺寸来确定的,这以为着他们的大小可以通过相关元素的大小来改变。属于相对长度单位的有3个:px,em,ex

  px:像素(Pixel),相对于设备的长度单位,像素是相对于显示器屏幕分辨率而言的,是屏幕上显示数据的最基本的点。px 是一个点,它不是自然界的长度单位,因为并不能精确描述一个“点”到底有多长多大,所以点可以很小,也可以很大,相对于设备来说,如果点很小,那画面就清晰,就可以称它为“分辨率高”,反之,就是“分辨率低”。因此,“点”的大小是会“变”的,被称为“相对长度”。

  在 Web 上,网页布局时常用像素为单位,像素是典型的度量单位,很多其他长度单位直接映射成像素,最终,他们被按照像素处理。

  em:相对于当前对象内文本的字体尺寸,如果当前行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸。

  在没有任何 CSS 规则的前提下,1em 的长度是:

100% = 1em = 1rem = 16px = 12pt = 1pc = 0.17in = 4.2mm = 0.42cm

  如果有任何 CSS 规则改变了字体大小,不管在文档的什么位置,1em 的长度会变成相对于新的 font-size 的大小。

  任意浏览器的默认字体大小都是 16px,因此 1em = 16px,那么 10px = 0.625em = 62.5%,12px = 0.75em = 75%,显然这样的话,如 1.2em则=19.2px,像素的最小单位是点,平时在设置时也不可能用 19.2px 表示,使用 px 时数值不带小数位。为了简化 font-size 的换算,可以在 CSS 中的 body 选择器中声明 font-size:62.5%,这就使 em 值变为 16px * 62.5%=10px, 即 1em = 10px,那么 12px = 1.2em, 也就是说只需要将原来的 px 数值除以 10,再换上 em 作为单位就好了。也可以自定义设置字体大小,不过这样设置更简单,也准确多了,具体需要根据实际的开发去定义。还可以设置为 100%,需要注意在写 CSS 时如果采用 em 作单位,要避免字体大小的重复声明,即重复运算。如下:

  em 并不是一个固定的值,它会继承父级元素的字体大小,当设置了 font-size 属性后,它会逐级向上相乘,所以如果一个设置了 font-size:1.2em 的元素在另一个设置了 font-size:1.2em 的元素里,则结果是 1.2 * 1.2= 1.44,而这个元素又在另一个设置了 font-size:1.2em 的元素里,那么最后计算的结果是 1.2 * 1.2 * 1.2。这意味着即使一个元素设置为 10em,这个元素也不会在他出现的每个地方都是 10em。如果 font-size 变化了,它可能会宽点,也可能会窄点。 比如说在 #content 中声明了字体大小为 1.2em,那么在声明 p 的字体大小时就只能是 1em,而不是 1.2em, 因为此 em 非彼 em,它因继承 #content 的字体大小而变为了 1em=12px。

  ex:相对于字符“x”的高度。为小写字母“x”的高度,通常为字体尺寸的一半。如果当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸。和 em 不同,当改变 font-family 时 em 不会改变,而 ex 单位会变化,因为一个单位的值和该字体是特殊的约束关系。

  ②、绝对长度单位

  绝对单位是固定的,是自然界标准的长度单位,也称为“绝对长度”。他们一旦被声明,将不能通过改变其他元素的字体大小来改变他的大小。属于绝对长度单位的有5个:pt,pc,in,mm,cm

  pt:Point,翻译为点,但其实应该叫磅,pt 是一个物理度量单位,1pt = 1/72英寸,在 CSS 之外 pt 是最常用的尺寸类型,常被用在印刷排版中,他在语言中也很常见,比如在电脑上 word 字体的字号就使用这个单位,默认为宋体五号字,即10.5pt,10.5pt = 14px = 0.875em = 87.5%,而小五号字为 9pt,9pt = 12px = 0.75em = 75%,在浏览器中默认字体为16px,字号则为笑四,1em = 16px = 12pt = 100%。

  pc派卡(Pica),相当于我国新四号铅字的尺寸。pc 和 pt 一样,只不过 1pc = 12pt。

  in:英寸(Inch),英寸是一个物理度量单位,但是在 CSS 领域,英寸只不过被直接映射成像素罢了。

1in = 96px = 72pt = 6pc = 2.54cm = 25.4mm

  mm:毫米(Millimeter),毫米是个小数量级的物理度量单位,1mm = 0.1cm = 3.78px。

  cm:厘米(Centimeter),常用的物理度量单位,也会被映射成像素,1cm = 37.8px。

  (3)、CSS3 长度单位

  在 CSS3 中引入了一些新的相对长度单位:ch、rem、vw、vh、vmin、vmax

  ch:相对长度单位,ch 的含义和 ex 的 x-height 相似,只不过 ch 是基于字符“0”的宽度而不是基于字符“x”高度的,当font-family 改变的时候 ch 也会随着改变。

  rem:(root element,html),rem 和 em 一样也是一个相对单位,但是和 em 不同的是 rem 总是相对于根元素(html)的 font-size,而不像 em 的计算是基于父级的,且 font-size 具有继承性,因此嵌套层数越深字体越大。所以使用 rem 这种相对单位更简单,再也不用担心父级元素的 font-size 了,因为它始终是基于根元素的。rem 单位不仅可以应用在字体上,还可以实现到 CSS 网格系统中。使用 rem 也可以简化 font-size 的换算,如下:

 1 html{
 2     font-size:62.5%;    /* 10÷16=62.5% */
 3 } 
 4 body{
 5     font-size:14px;
 6     font-size:1.4rem;    /* 14÷10=1.4 */
 7 } 
 8 p{
 9     font-size:12px;
10     font-size:1.2rem;
11 }

  其实不用太纠结到底是默认的 font-size:100%,还是设置为 font-size:62.5%,如果引入了 CSS 预处理工具那么自然可以使用默认值,但是由于其他原因使用 font-size:62.5% 也无可厚非,完全可以在 body 中重置为需要的 font-size。

  在网站建设中,一般中文的字体大小是 12px 和 14px,这基本已经成了大多数网站字体的标准大小,而 16px 为中等字体,18px 为较大字体,12px 则为偏小字体。随着显示器分辨率不断提高,12px 的文字在大于 1440*900 的显示器中看起来会显得比较小,不宜阅读,所以现在网页设计里面用 12px 的已经比较少了,特别是文章正文部分,普遍都会用 14px。一般来说设置为宋体,也可以设置为微软雅黑。但是对于大于 14px 的文字,特别是大于 16px 的文字,宋体就显得比较难看了,所以设置为黑体或者微软雅黑,看起来会舒服一些。

  vw:(viewpointWidth),可视区宽度单位,1vw等于视口宽度的1%。vw 单位跟百分比很相似,不同的是 vw 的值对所有的元素都一样,与父元素的宽度无关。有点像 rem 单位那样总是相对于根元素。

  vh:(viewpointHeight),可视区高度单位,1vh等于视口高度的1%。与 vw 单位一样,不同的是 vh 是相对于可视区的高度。

  vmin:1%的视口的小尺寸,值是当前 vw 和 vh 中较小的值,在标准尺寸类型的使用实例中,和由自己确定屏幕大小的vw、vh单位相比,vmin是一个更有用的度量标准。

  vmax:1%的视口的大尺寸,值是 vw 和 vh 中的较大的值。

  显然 vw、vh、vmin、vmax 是针对移动设备的单位,如果视口大小变化了,这三个值也会跟着相应的变化。在进行响应式布局时,常常会使用百分比来布局,然而 CSS 的百分比不总是解决每个问题的最佳方案,CSS 的宽度相对于离它最近的父元素的宽度。 那么使用 vw 和 vh 单位,是基于视口的宽高而不是父元素的宽高, 使用 vh 和 vw 就可以保证元素的宽高适应不同设备。vw 和 vh 对应于 viewport 的 width 和 height,而 vmin 和 vmax 分别对应于 width、height 中的最小值和最大值,假如浏览器的宽/高被设置为1000px/600px,那么:

1vmin = 600 * 1/%;
1vmax = 1000 * 1/%;

  (4)、%

  以百分比为单位的长度值是基于具有相同属性的父元素的长度值。假如一个元素呈现的宽度是 600px,子元素的宽度设置为 50%,那么子元素呈现的宽度为 300px。百分比不是一个专门的长度单位,但是百分比和长度关系很大,可以相互换算。

7、CSS Display(显示) 和 Visibility(可见性)

  display 属性设置一个元素应如何显示,visibility 属性规定一个元素是否可见。

  (1)、隐藏元素:display:none 或 visibility:hidden

  隐藏一个元素可以通过把 display 属性设置为 “none”,或把 visibility 属性设置为 “hidden”。但是请注意,这两种方法会产生不同的结果。

  visibility:hidden 可以隐藏某个元素,但隐藏的元素仍需占用与未隐藏之前一样的空间。也就是说,该元素虽然被隐藏了,但仍然会影响布局。

  该属性的默认值是 visible 元素是可见的。值为 hidden 则元素是不可见的。即使不可见的元素也会占据页面上的空间。建议使用 display 属性来创建不占据页面空间的不可见元素。值为 collapse 时,当在表格元素中使用时,此值可删除一行或一列,但是它不会影响表格的布局。被行或列占据的空间会留给其他内容使用。如果此值被用在其他的元素上,会呈现为 “hidden”。

  display:none 可以隐藏某个元素,且隐藏的元素不会占用任何空间。也就是说,该元素不但被隐藏了,而且该元素原本占用的空间也会从页面布局中消失

  该属性的默认值为 inline 此元素会被显示为内联元素,元素前后没有换行符。值为 none 此元素不会被显示。值为 block 此元素将显示为块级元素,此元素前后会带有换行符。值为 inline-block 表示行内块元素。该属性也有多个值可用于表格设置。

  (2)、CSS Display – 块和内联元素

  大多数 HTML 元素被定义为块级元素或内联元素:

  块级元素在浏览器显示时,通常会以新行来开始(和结束),块状元素排斥其他元素与其位于同一行,可以设定元素的宽和高以及内外边距,块级元素一般是其他元素的容器,可以容纳内联元素和其他块元素。常见的块级元素有: <h1> – <h6>, <div>,<p>, <pre>,<hr>,<ul>, <ol>,<dl>,<from>,<table>,<menu>。

  内联元素在显示时通常不会以新行开始,不可以设置宽和高,但可以设置与其他内联元素位于同一行,高度由元素内部的文字大小决定,宽度由内容的长度决定,内联元素一般不能包含块级元素,内联元素只能容纳文本或者其他内联元素。常见的内联元素有:<a>, <span>,<img>,<br>,<input>,<textarea>,<strong>,<em>,<mark>,<i>,<small>。

  块元素是一个元素,占用了全部宽度,在前后都是换行符。而内联元素只需要必要的宽度,不强制换行。内联元素的例子:<span>、<a>、<img>。

  可以更改内联元素和块元素,反之亦然,可以使页面看起来是以一种特定的方式组合,并仍然遵循 Web 标准。

  下面的例子把列表项显示为内联元素:

 1 <head>
 2 <style>
 3 li{
 4     display:inline;
 5 }
 6 </style>
 7 </head>
 8 <body>
 9 <ul>
10     <li><a href="#" target="_blank">HTML</a></li>
11     <li><a href="#" target="_blank">CSS</a></li>
12     <li><a href="#" target="_blank">JavaScript</a></li>
13     <li><a href="#" target="_blank">jQuery</a></li>
14 </ul>
15 </body>

  下面的例子把 span 元素作为块元素:

 1 <head>
 2 <style>
 3 span{
 4     display:block;
 5     color:red;
 6 }
 7 </style>
 8 </head>
 9 <body>
10 <p>display 属性<span>可把一个块元素转换为内联元素,</span>反之亦然,<span>也可以把一个内联元素转换为块元素。</span></p>
11 </body>

  注意:一个内联元素设置为 display:block 是不允许有它内部的嵌套块元素。

8、CSS Position(定位)

  CSS position 属性可以对元素进行定位。

  CSS 的定位和浮动属性,可用于建立列式布局,将布局的一部分与另一部分重叠,即可以将一个元素放在另一个元素后面,并指定一个元素的内容太大时,应该发生什么。元素可以使用顶部,底部,左侧和右侧属性进行定位。但是,这些属性无法单独工作,除非是先设定 position 属性。

  定位的基本思想很简单,它允许你定义元素框(盒子模型)相对于其正常位置应该出现的位置,或者相对于父元素、另一个元素甚至浏览器窗口本身的位置。这个功能非常强大,而浮动不完全是定位,不过,它当然也不是正常流布局。

  CSS 有三种基本的定位机制:普通流、浮动和绝对定位。

  除非专门指定,否则所有框都在普通流中定位,也就是说,普通流中的元素的位置由元素在 HTML 中的位置决定。块级框从上到下一个接一个地排列,框之间的垂直距离是由框的垂直外边距计算出来。行内框在一行中水平布置,可以使用水平内边距、边框和外边距调整它们的间距。但是,垂直内边距、边框和外边距不影响行内框的高度。由一行形成的水平框称为行框(Line Box),行框的高度总是足以容纳它包含的所有行内框。不过,设置行高可以增加这个框的高度。

  定位有四种不同的方法:静态定位、固定定位、相对定位和绝对定位。

  (1)、静态定位(static)

  HTML 元素的默认值,即没有定位,元素出现在正常的流中,块级元素生成一个矩形框,作为文档流的一部分,行内元素则会创建一个或多个行框,置于其父元素中。静态定位的元素不会受到 top, bottom, left, right 影响。

  (2)、固定定位(fixed)

  元素的位置相对于浏览器窗口是固定位置。类似于将 position 设置为 absolute,不过其包含块是视窗本身。固定定位使元素的位置与文档流无关,因此不占据空间,固定定位的元素和其他元素重叠。

  下面的例子,将 div 固定在浏览器右下角:

 1 <head>
 2 <style>
 3 #box{
 4     width:150px;
 5     height:200px;
 6     background:green;
 7     position:fixed;
 8     right:0;
 9     bottom:0;
10 }
11 </style>
12 </head>
13 <body style="height:2000px">
14 <div id="box">固定在右下角。
15 </div>
16 </body>

  (3)、相对定位(relative)

  相对定位元素的定位是相对其正常位置,仍处在文档流中,元素的位置相对于它在普通流中的位置偏移某个距离,元素仍保持其未定位前的形状,它原本所占的空间仍保留。相对定位元素经常被用来作为绝对定位元素的容器块。

  如果对一个元素设置相对定位,它将出现在它所在的位置上。然后,可以通过设置垂直或水平位置,让这个元素“相对于”它的起点进行移动。如下:

 1 <head>
 2 <style>
 3 #pos1{
 4     color:blue;
 5 }
 6 #pos2{
 7     color:red;
 8     position:relative;
 9     top:-50px;
10     left:60px;
11 }
12 </style>
13 </head>
14 <body>
15 <h1 id="pos1">我是普通流中的大标题。</h1>
16 <h1 id="pos2">我是设置了相对定位的大标题。</h1>
17 <h1>我也是普通流中的大标题。</h1>
18 </body>

  注意,在使用相对定位时,无论是否进行移动,元素仍然占据原来的空间。因此,移动元素会导致它和其他元素重叠。

  (4)、绝对定位(absolute)

  绝对定位的元素的位置相对于最近的已定位父元素,如果元素没有已定位的父元素,那么它的位置相对于 <html>,绝对定位使元素的位置与文档流无关,因此不占据空间。这一点与相对定位不同,相对定位实际上被看作普通流定位模型的一部分,因为元素的位置相对于它在普通流中的位置。绝对定位的元素和其他元素也会重叠。

  设置为绝对定位的元素框从文档流完全删除,并相对于其包含块定位,包含块可能是文档中的另一个元素或者是初始包含块(<html>)。元素原先在正常文档流中所占的空间会关闭,就好像该元素原来不存在一样。元素定位后生成一个块级框,而不论原来它在正常流中生成何种类型的框。

  可以使用上面的例子,观察绝对定位和相对定位的不同,可以将其顶部属性设置为0,如果使用负值,会超出浏览器窗口:

 1 <head>
 2 <style>
 3 #pos1{
 4     color:blue;
 5 }
 6 #pos2{
 7     color:red;
 8     position:absolute;
 9     top:0;
10     left:60px;
11 }
12 </style>
13 </head>
14 <body>
15 <h1 id="pos1">我是普通流中的大标题。</h1>
16 <h1 id="pos2">我是设置了绝对定位的大标题。</h1>
17 <h1>我也是普通流中的大标题。</h1>
18 </body>

  (5)、堆叠顺序(z-index)

  因为元素的定位与文档流无关,所以它们可以覆盖页面上的其它元素。可以通过 z-index 属性控制这些元素的堆放次序。

  z-index 属性用于指定一个元素的堆叠顺序,即哪个元素应该放在前面,或后面。一个元素可以有正数或负数的堆叠顺序,默认值为 auto 堆叠顺序与父元素相等。拥有更高堆叠顺序的元素总是会处于堆叠顺序较低的元素前面。 注意: 如果两个定位元素重叠,没有指定z-index,最后定位在 HTML 代码中的元素将被显示在最前面。该属性只能用于定位元素,且无继承。该属性设置一个定位元素沿 z 轴的位置,z 轴定义为垂直延伸到显示区的轴。如果为正数,则离用户更近,为负数则表示离用户更远。

 1 <head>
 2 <style>
 3 *{padding:0;margin:0;}
 4 #box1{
 5     width:500px;
 6     height:100px;
 7     background:blue;
 8     position:relative;
 9     z-index:100;
10 }
11 #box2{
12     width:800px;
13     height:200px;
14     background:red;
15     position:absolute;
16     top:20px;
17     left:50px;
18 }
19 #box3{
20     width:1000px;
21     height:300px;
22     background:green;
23     position:absolute;
24     top:40px;
25     left:100px;
26     z-index:-1;
27 }
28 </style>
29 </head>
30 <body>
31 <div id="box1">1
32 </div>
33 <div id="box2">2
34 </div>
35 <div id="box3">3
36 </div>
37 </body>

  上面的例子,默认的堆叠顺序是 box1 在最底层,下来是 box2,box3 显示在最上层。给 box3 设置为 z-index:-1;,那么 box3 会显示在最底层,下来是 box1,box2 会显示在最上层。再给 box1 设置 z-index:100;,最终 box1 显示在最上层,下来是 box2,box3 被显示在最底层。

  (6)、固定层效果

  固定层效果是固定定位的应用,这种效果在网站中也很常见,比如在页面顶部固定导航栏菜单,当页面滚动时,内容从导航栏菜单下面穿过,或者侧边栏固定在页面右底部。如下:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>固定层效果</title>
 6 <style>
 7 *{padding:0;margin:0;}
 8 body{
 9     background:#EEEEE0;
10 }
11 #header{
12     width:100%;
13     height:50px;
14     background:#99CC33;
15     position:fixed;
16     top:0;
17     left:0;
18 }
19 #conten{
20     width:80%;
21     height:1000px;
22     border:1px solid black;
23     margin:0 auto;
24     margin-top:70px;
25 }
26 #conten .main{
27     width:200px;
28     height:400px;
29     background:yellow;
30 }
31 #sidebar{
32     width:80px;
33     height:80px;
34     background:green;
35     position:fixed;
36     right:0;
37     bottom:0;
38 }
39 #footer{
40     width:100%;
41     background:#cdcdc1;
42     text-align:center;
43     margin-top:20px;
44     padding:20px 0;
45 }
46 </style>
47 </head>
48 <body>
49 <div id="header">
50     <h2>网站头部</h2>
51 </div>
52 <div id="conten">
53     <div class="main">
54         <h2>内容</h2>
55     </div>
56 </div>
57 <div id="sidebar">
58     <h2>侧边栏</h2>
59 </div>
60 <div id="footer">
61     <h2>页脚</h2>
62 </div>
63 </body>
64 </html>

  为了提高用户体验,增强交互效果,可以配合 JS 对页面进行控制,就像电商网站的页面效果,当页面从商品简介滚动到商品详情、用户评论时,将导航栏菜单固定在页面顶部,这样评论数就会从导航栏菜单下穿过,方便用户使用。

  position 三种形式定位的影响因素:属性的取值、元素的偏移量和元素偏移的参考基准。

  absolute 与 fixed 相同点都是完全脱离文档流,未设置偏移量时都定位在父元素的左上角。元素设置定位后就具备偏移属性和堆叠属性,只有元素在设置相对定位,或者绝对定位后,堆叠属性才有效,它的作用是设置元素所在的 z 轴层级。z-index值越大,元素层级越大。

  他们的不同点是设置偏移时,偏移的参考基准,absolute 无已定位祖先元素时,以 <html> 为基准偏移;有已经定位的祖先元素时,以距其最近的已定位元素为基准偏移,通常设置了 relative 的元素常被用来做 absolute 元素的容器块。fixed 有、无已定位祖先元素,都已浏览器可视窗口为基准偏移。

  他们还存在表现形式的差异,即滚动条,absolute 的位置会随滚动条变化,而 fixed 的位置是固定不变的,不会随滚动条变化,兄弟元素可以从其下穿过。

  fixed 的定位形式也属于绝对对位,但不同于 absolute,fixed 的位置固定不变,未设置偏移量时,有已定位的祖先元素,以祖先元素为基准定位;无已定位祖先元素时,以浏览器窗口为基准定位。设置偏移量后,有无已定位祖先元素,均以浏览器窗口定位。

9、CSS Float(浮动)

  在 CSS 中,通过 float 属性来实现元素的浮动。浮动会使元素向左或向右移动,直到他的外边缘碰到包含框或另一个浮动框的边框为止,其周围的元素也会重新排列。浮动元素之后的元素将围绕它,浮动元素之前的元素不会受到影响。由于浮动框不在文档的普通流中,所以文档的普通流中的块框表现得就像浮动框不存在一样。浮动往往是用于图像,但它在布局时一样非常有用。浮动也可以理解为向一边看齐,即就是向左看齐或者向右看齐,元素是在水平方向浮动,那么意味着元素只能左右移动而不能上下移动。

  (1)、浮动

  ①、创建浮动,可以使文本围绕图像。

  如果图像是左浮动,下面的文本流将环绕在它右边,如果图像是右浮动,下面的文本流将环绕在它左边。如下:

 1 <head>
 2 <style>
 3 img{
 4     /* float:left; */
 5     float:right;
 6 }
 7 </style>
 8 </head>
 9 <body>
10 <p>浮动元素之后的元素将围绕它,浮动元素之前的元素不会受到影响。</p>
11 <p>浮动会使元素向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止,其周围的元素也会重新排列。浮动元素之后的元素将围绕它,浮动元素之前的元素不会受到影响。浮动往往是用于图像,但它在布局时一样非常有用。浮动也可以理解为向一边看齐,即就是向左看齐或者向右看齐,元素是在水平方向浮动,那么意味着元素只能左右移动而不能上下移动。
12 
13 <img src="images/1.jpg" width="90px" height="90px" alt="">
14 
15 浮动会使元素向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止,其周围的元素也会重新排列。浮动元素之后的元素将围绕它,浮动元素之前的元素不会受到影响。浮动往往是用于图像,但它在布局时一样非常有用。浮动也可以理解为向一边看齐,即就是向左看齐或者向右看齐,元素是在水平方向浮动,那么意味着元素只能左右移动而不能上下移动。
16 
17 浮动会使元素向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止,其周围的元素也会重新排列。浮动元素之后的元素将围绕它,浮动元素之前的元素不会受到影响。浮动往往是用于图像,但它在布局时一样非常有用。浮动也可以理解为向一边看齐,即就是向左看齐或者向右看齐,元素是在水平方向浮动,那么意味着元素只能左右移动而不能上下移动。
18 
19 浮动会使元素向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止,其周围的元素也会重新排列。浮动元素之后的元素将围绕它,浮动元素之前的元素不会受到影响。浮动往往是用于图像,但它在布局时一样非常有用。浮动也可以理解为向一边看齐,即就是向左看齐或者向右看齐,元素是在水平方向浮动,那么意味着元素只能左右移动而不能上下移动。
20 </p>
21 </body>

  彼此相邻的浮动元素,如果有空间的话,它们将彼此相邻,即在一行显示,如下:

 1 <head>
 2 <style>
 3 #box{
 4     width:400px;
 5     height:350px;
 6     border:1px solid black;
 7     margin:10px auto;
 8     overflow:hidden;
 9 }
10 img{
11     float:left;
12     margin:0 10px 10px 0;
13 }
14 </style>
15 </head>
16 <body>
17 <p>浮动元素之后的元素将围绕它,浮动元素之前的元素不会受到影响。</p>
18 <div id="box">
19     <img src="images/1.jpg" width="90px" height="90px" alt="">
20     <img src="images/1.jpg" width="90px" height="90px" alt="">
21     <img src="images/1.jpg" width="90px" height="90px" alt="">
22     <img src="images/1.jpg" width="90px" height="90px" alt="">
23     <img src="images/1.jpg" width="90px" height="90px" alt="">
24     <img src="images/1.jpg" width="90px" height="90px" alt="">
25     <img src="images/1.jpg" width="90px" height="90px" alt="">
26     <img src="images/1.jpg" width="90px" height="90px" alt="">
27     <img src="images/1.jpg" width="90px" height="90px" alt="">
28     <img src="images/1.jpg" width="90px" height="90px" alt="">
29     <img src="images/1.jpg" width="90px" height="90px" alt="">
30     <img src="images/1.jpg" width="90px" height="90px" alt="">
31     <img src="images/1.jpg" width="90px" height="90px" alt="">
32     <img src="images/1.jpg" width="90px" height="90px" alt="">
33     <img src="images/1.jpg" width="90px" height="90px" alt="">
34     <img src="images/1.jpg" width="90px" height="90px" alt="">
35 </div>
36 </body>

  上面的例子,如果不给浮动的图像设置外边距,所有的图像会紧挨在一起显示,犹如一张图像。

  ②、浮动不在文档普通流中

  下面的例子,3个 div 元素在普通流中垂直显示,当把 box1 向右浮动时,他会脱离文档流并且向右移动,知道他的右边缘碰到包含框(<html>)的右边缘:

 1 <head>
 2 <style>
 3 #box1{
 4     width:200px;
 5     height:100px;
 6     background:blue;
 7     float:right;
 8 }
 9 #box2{
10     width:200px;
11     height:100px;
12     background:red;
13 }
14 #box3{
15     width:200px;
16     height:100px;
17     background:green;
18 }
19 </style>
20 </head>
21 <body>
22 <p>由于浮动框不在文档的普通流中,所以文档的普通流中的块框表现得就像浮动框不存在一样。</p>
23 <div id="box1">1
24 </div>
25 <div id="box2">2
26 </div>
27 <div id="box3">3
28 </div>
29 </body>

  如果把 box1 向左浮动,他会脱离文档流并且向左移动,直到他的左边缘碰到包含框的左边缘。因为它不再处于文档流中,所以它不占据空间,实际上会覆盖掉 box2,使 box2 从视图中消失。为了达到演示效果,可以稍微修改下3个 div 元素的的样式:

 1 #box1{
 2     width:200px;
 3     height:100px;
 4     background:blue;
 5     float:left;
 6 }
 7 #box2{
 8     width:300px;
 9     height:100px;
10     background:red;
11 }
12 #box3{
13     width:400px;
14     height:100px;
15     background:green;
16 }

  如果把所有3个 box 都向左浮动,那么 box1 向左浮动直到碰到包含框,另外两个 box 向左浮动直到碰到前一个浮动框:

 1 #box1{
 2     width:200px;
 3     height:100px;
 4     background:blue;
 5     float:left;
 6 }
 7 #box2{
 8     width:200px;
 9     height:100px;
10     background:red;
11     float:left;
12 }
13 #box3{
14     width:200px;
15     height:100px;
16     background:green;
17     float:left;
18 }

  如果包含框太窄,无法容纳水平排列的三个浮动元素,那么其它浮动块向下移动,直到有足够的空间。如果浮动元素的高度不同,那么当它们向下移动时可能被其它浮动元素“卡住”,如下:

 1 <head>
 2 <style>
 3 #box{
 4     width:450px;
 5     height:300px;
 6     border:1px solid black;
 7     margin:10px auto;
 8 }
 9 #box1{
10     width:200px;
11     height:150px;
12     background:blue;
13     float:left;
14 }
15 #box2{
16     width:200px;
17     height:100px;
18     background:red;
19     float:left;
20 }
21 #box3{
22     width:200px;
23     height:100px;
24     background:green;
25     float:left;
26 }
27 </style>
28 </head>
29 <body>
30 <p>如果包含框太窄,无法容纳水平排列的三个浮动元素,那么其它浮动块向下移动,直到有足够的空间。如果浮动元素的高度不同,那么当它们向下移动时可能被其它浮动元素“卡住”。</p>
31 <div id="box">
32     <div id="box1">1
33     </div>
34     <div id="box2">2
35     </div>
36     <div id="box3">3
37     </div>
38     <p>浮动会影响处于其后的元素,需要清除浮动的影响。</p>
39 </div>
40 </body>

  (2)、清除浮动

  元素浮动之后,周围的元素将重新排列,浮动元素之后的元素会围绕它,为了避免这种情况,可以使用 clear 属性。

  clear 属性指定元素两侧不能出现浮动元素。该属性的默认值是 none 允许浮动元素出现在两侧,还可以是 left、right、both,它表示框的哪些边不应该挨着浮动框。

  大多情况下都会使用 clear:both; 左右两端均不出现浮动元素。

  对于上面例子中的情况,就可以用 clear 属性给 p 元素设置清除浮动影响:

1 p{
2     clear:both;
3 }

  (3)、overflow

  overflow 属性指定如果内容溢出一个元素的框,会发生什么。在上面彼此相邻元素的浮动中,给父容器设置了宽高,因为图像很多,超出了父容器,在代码中使用了 overflow:hidden; 对溢出的内容进行了隐藏。下面再通过一个例子来看下:

 1 <head>
 2 <style>
 3 #box{
 4     width:200px;
 5     height:200px;
 6     border:5px solid black;
 7 }
 8 #box .content{
 9     width:300px;
10     height:400px;
11     background:red;
12 }
13 </style>
14 </head>
15 <body>
16 <div id="box">
17     <div class="content">
18     </div>
19 </div>
20 <p>子元素高度超出了父容器的高度,超出的部分就属于溢出的内容。</p>
21 </body>

  为了防止布局被撑开,只需要给父容器设置 overflow:hidden 就可以强制隐藏溢出的内容。在网站开发中,常常会使用到该方法。overflow 属性的默认值是 visible 内容不会被修剪,会呈现在元素框之外。值为 hidden 时内容会被修剪,并且其余内容是不可见的。值为 scroll 时内容会被修剪,但是浏览器会显示滚动条以便查看其余的内容。值为 auto 时,如果内容被修剪,则浏览器会显示滚动条以便查看其余的内容。

  使用了溢出隐藏之后,如果把父容器的高度注释掉,设置子元素左浮动,会发现父容器的高度自动被子元素的高度撑开了,如果不设置溢出隐藏,则父容器不会被撑开,将上面例子中的代码稍微改动下:

 1 <head>
 2 <style>
 3 #box{
 4     width:450px;
 5     /* height:200px; */
 6     border:5px solid black;
 7     overflow:hidden;
 8 }
 9 #box .content{
10     float:left;
11     width:200px;
12     height:400px;
13     background:red;
14     margin-right:20px;
15 }
16 </style>
17 </head>
18 <body>
19 <div id="box">
20     <div class="content">
21     </div>
22     <div class="content">
23     </div>
24 </div>
25 <p>子元素高度超出了父容器的高度,超出的部分就属于溢出的内容。</p>
26 </body>

  按照之前的解释,由于浮动框不在文档的普通流中,所以文档普通流中的块框表现得就像浮动框不存在一样。浮动也可以理解为向一边看齐,元素是在水平方向浮动,这就意味着元素只能左右移动而不能上下移动,即就是在一个平面上的浮动,但是上面的例子,浮动并不仅仅是一个平面上的浮动,而是一个立体的浮动,当子元素设置了浮动之后,在显示器侧面,他已经脱离了父容器,也就是说此时的子元素的宽高是多少,对于已经脱离了的父容器来说,是不起作用的。所以使用 overflow:hidden 还可以清除浮动,也就是说,当给父容器设置这个属性时,其内的子元素等带浮动属性的元素在这个立体的浮动已经被清除了。

  如果给父容器设置高度,或者释放之前的高度注释,那么无论子元素的高度是多少,父容器的高度都是指定的值,并不会被撑开,而当子元素的高度超出父容器的高度时,超出的部分就会被隐藏,该属性可以保证 div 的高度或宽度不变。该属性主要用于规定,当一个块元素容器的内容溢出元素的盒模型边界时是否对其进行修剪,也就是隐藏,他影响被应用元素的所有内容的修剪,即作为所有子元素的包含块,但如果后代元素的包含块是整个视区(通常指浏览器内容可视区域,可以理解为 body 元素)或者是该容器(定义了 overflow 的元素)的父级元素时,则不受影响。

10、CSS 对齐(align)

  (1)、块元素水平对齐

  在 CSS 中,可以使用多种属来实现元素水平对齐。

  块元素指的是占据全部可用宽度的元素,并且在其前后都会换行,排斥其他元素与其位于同一行。

  ①、使用 margin 属性

  块元素可以把左,右外边距设置为“auto”,实现水平对齐,也可以叫做中心对齐。

  margin 属性把左和右设置为自动,规定均等的分配可用的外边距,结果就是元素居中显示。

 1 <head>
 2 <style>
 3 #box{
 4     width:300px;
 5     height:200px;
 6     background:blue;
 7     margin:auto;
 8 }
 9 </style>
10 </head>
11 <body>
12 <div id="box">
13 </div>
14 </body>

  注意:如果宽度是 100%,对齐是没有效果的。

  ②、使用 position 属性

  使用绝对定位是元素对齐方法之一,可以设置左和右对齐。绝对定位与文档流无关,所以它们可以覆盖页面上的其它元素。

 1 <head>
 2 <style>
 3 #box{
 4     width:300px;
 5     height:200px;
 6     background:blue;
 7     position:absolute;
 8     right:0px;
 9 }
10 </style>
11 </head>
12 <body>
13 <div id="box">
14 </div>
15 </body>

  ③、使用 float 属性

  对齐元素的另一个方法就是使用 float 属性,可以实现左和右对齐。

 1 <head>
 2 <style>
 3 #box{
 4     width:300px;
 5     height:200px;
 6     background:blue;
 7     float:right;
 8 }
 9 </style>
10 </head>
11 <body>
12 <div id="box">
13 </div>
14 </body>

  (2)、文本水平对齐

  text-align 属性用于指定元素文本的水平对齐方式。该属性通过指定行框与哪个点对齐,从而设置块级元素内文本的水平对齐方式。默认值为 left 把文本排列到左边,right 把文本排列到右边,center 把文本排列到中间。

 1 <head>
 2 <style>
 3 h1{
 4     text-align:center;
 5 }
 6 h2{
 7     text-align:left;
 8 }
 9 h3{
10     text-align:right;
11 }
12 </style>
13 </head>
14 <body>
15 <h1>我是大标题。</h1>
16 <h2>我是中标题。</h2>
17 <h3>我是小标题。</h3>
18 </body>

  (3)、垂直对齐

  vertical-align 属性可以设置一个元素的垂直对齐方式。该属性定义行内元素的基线相对于该元素所在行的基线的垂直对齐。允许指定负长度值和百分比值,这会使元素降低而不是升高。在表单元格中,这个属性会设置单元格框中的单元格内容的对齐方式。

  默认值为 baseline 元素放置在父元素的基线上,top 元素的顶端与行中最高元素的顶端对齐,middle 把此元素放置在父元素的中部。bottom 元素的顶端与行中最低的元素的顶端对齐。text-top 元素的顶端与父元素字体的顶端对齐,text-bottom 元素的底端与父元素字体的底端对齐。sup/sub 垂直对齐文本的上标/下标。也可以使用 “line-height” 属性的百分比值来排列此元素,允许使用负值。

 1 <head>
 2 <style>
 3 img.top{
 4     vertical-align:text-top;
 5 }
 6 img.mid{
 7     vertical-align:middle;
 8 }
 9 img.bot{
10     vertical-align:text-bottom;
11 }
12 </style>
13 </head>
14 <body>
15 <p>元素的顶端<img class="top" src="images/1.jpg" width="90px" height="90px">与父元素字体的顶端对齐。</p>
16 <p>元素与父元素的中间对齐。<img class="mid" src="images/1.jpg" width="90px" height="90px"></p>
17 <p>元素的底端<img class="bot" src="images/1.jpg" width="90px" height="90px">与父元素字体的底端对齐。</p>
18 </body>

11、CSS 图像透明度

  通过 CSS 创建透明图像是很容易的,CSS3 的 opacity 属性可以为一个元素设置透明度。

  该属性的值为数值,从 0.0 – 1,值越小,使元素更加透明,0.0 为完全透明,1 则完全不透明。

  IE8 及更早版本的浏览器则使用 filter 属性来设置元素的透明,filter:alpha(opacity=value);

  filter 属性的值也为数值,不过是从 0 – 100,较低的值,使得元素更加透明,0 为完全透明,100 则完全透明。

  (1)、创建一个透明图像

  创建透明图像,只需要给图像标签设置 opacity 属性就好了,根据不同的需求,可以设置不同的透明度级别。

1 img{
2     opacity:0.5;
3 }

  (2)、透明图像悬停效果

  悬停效果即鼠标悬停在图像上时,图像是完全不透明的,当鼠标移出后,图像变为透明。该效果可以使用 hover 实现。

1 img{
2     opacity:0.5;
3 }
4 img:hover{
5     opacity:1;
6 }

  透明图像的悬停效果在网站中应用还是十分普遍的,尤其是在一些电商网站中,特卖商品或其他商品的展示就可以使用这种效果,京东做过这种效果,淘宝也在使用这种效果展示商品。该效果也可以用 JS 来更改元素的透明度,给图像绑定鼠标移入移出事件,当鼠标悬停在图像上时会发生什么。

   (3)、图片画廊

  图片画廊也可以叫图片库,非常适合作为图片展示、个人作品展示和相册使用,可以在页面上显示系列图片,因此图片画廊也是网站重要的组成部分,实现图片画廊有很多种方法,这里就简单的用 CSS 创建一个图片画廊,如果使用 CSS3 可以让图片画廊拥有更加炫酷的效果。

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="UTF-8">
 5     <base target='_blank'>
 6     <title>CSS 图片画廊</title>
 7 <style>
 8 .gallery{
 9     width:auto;
10     height:auto;
11     margin:2px;
12     border:1px solid #0000FF;
13     text-align:center;
14     float:left;
15 }
16 .gallery img{
17     margin:5px;
18     border:1px solid #FFFFFF;
19 }
20 a:hover img{
21     border:1px solid #4169E1;
22 }
23 .desc{
24     width:120px;
25     margin:2px;
26 }
27 </style>
28 </head>
29 <body>
30 <div class="gallery">
31     <a href="#" target="_blank"><img src="images/1.jpg" alt="anime" width="90" height="90"></a>
32     <div class="desc">在这里可以为图片添加相关描述。</div>
33 </div>
34 <div class="gallery">
35     <a href="#" target="_blank"><img src="images/2.jpg" alt="anime" width="90" height="90"></a>
36     <div class="desc">在这里可以为图片添加相关描述。</div>
37 </div>
38 <div class="gallery">
39     <a href="#" target="_blank"><img src="images/3.jpg" alt="anime" width="90" height="90"></a>
40     <div class="desc">在这里可以为图片添加相关描述。</div>
41 </div>
42 <div class="gallery">
43     <a href="#" target="_blank"><img src="images/4.jpg" alt="anime" width="90" height="90"></a>
44     <div class="desc">在这里可以为图片添加相关描述。</div>
45 </div>
46 </body>
47 </html>

  下图是浏览器显示结果:

12、CSS 图像拼合技术

  图像拼合就是 CSS 雪碧 即 CSS Sprite,也被称为 CSS 精灵,是一种 CSS 图像合并技术,该方法是将小图标和背景图片合并到一张图片上,然后利用 CSS 的背景定位来显示需要显示的图片部分。简单说图像拼合就是单个图像的集合,他能合并的只能是用于背景的图片。

  有许多图像的网页可能需要很长的时间来加载和生成多个服务器的请求,那么使用图像拼合就会减少网站的 HTTP 请求数量,提高页面加载速度,并节省带宽。

  图像拼合的原理就是把页面涉及到的所有零星图片整合在一张大图中,图片在 CSS 中定义,而不是使用 <img> 标签。利用 CSS 的 background-image、background- repeat、background-position 属性的组合进行背景定位,background-position 使用数字可以精确的定位出背景图片需要显示的位置。合图的一般顺序为从上到下、从左到右,通常保存为 PNG 格式的文件。使用 CSS Sprite 时一定要预先确定每个小图标的大小,并且要注意每个图标之间的间距。

  (1)、简单实例

   在网站中应用 CSS Sprite,那么首先就得把需要的图片合并成一张图片,可以使用 PS 手动合成,也可以下载用于生成 CSS Sprite 的本地应用,比如 CssGaga 等,还可以使用一些简单的在线 CSS Sprite 生成工具,比如 CSS Sprites Generator 或 GoPng  ,前者是一个小清新风格的网站,简单的界面和绿色背景,使用非常方便,易操作,但是图片只能横向或纵向排列,不支持图片拖拽排列,支持自定义图片间距,点击生成按钮之后,页面下方会自动生成每张图片的样式信息方便调用,点击 PNG 图标下载图片,另外点击 HTML 图标可以跳转新页面预览生产的图标。后者是企鹅的前端使用 HTML5 实现的合成图片的在线工具,支持自定义画布大小,带有磁力吸附对齐功能,可以拖动图片进行排序,不仅能生成 PNG 图片,还可以生成 CSS 文件,并且还能定制 CSS 模板,支持工作状态导出,包括图片数据(图片、图片位置排序)和参数设置(主页的参数设置和 CSS 模板设置)全部导出成一个文件,下次利用该文件就可以恢复到上次的工作状态。企鹅的工具明显相当强大了,一般情况是足够用了,界面也比较清爽,就是个人感觉不太好操作。

  下图是在百度图片中找的几个小图标,使用企鹅的在线工具生成的 CSS Sprite 图,在下面例子中使用。

  使用图像拼合技术是小图片加载优化的惯用手段,上面的雪碧图是把7个小图标合并在一个图片中,使用这种单个的图片,再利用 CSS,就可以只显示我们需要的部分:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>CSS Sprite</title>
 6 <style>
 7 i{
 8     width:64px;
 9     height:64px;
10     display:block;
11     float:left;
12     margin-right:20px;
13     background:url(images/sprite.png) no-repeat;
14 }
15 .clock{
16     background-position:0 0;
17 }
18 .right{
19     background-position:0 -64px;
20 }
21 .left{
22     background-position:0 -128px;
23 }
24 .home{
25     background-position:0 -192px;
26 }
27 
28 .favorite{
29     background-position:-64px 0;
30 }
31 .love{
32     background-position:-64px -64px;
33 }
34 .close{
35     background-position:-64px -128px;
36 }
37 </style>
38 </head>
39 <body>
40 <i class="clock"></i>
41 <i class="right"></i>
42 <i class="left"></i>
43 <i class="home"></i>
44 <i class="favorite"></i>
45 <i class="love"></i>
46 <i class="close"></i>
47 </body>
48 </html>

  上面的代码,在浏览器打开后,雪碧图每个小图标从上往下并左浮动显示,右外边距 20px。

   实例解析:

  ①、雪碧图中每个小图标都为等宽等高的图像,为所有 i 元素都设置 64px;height:64px;,定义我们使用的那部分图像。

  ②、从代码中可以看出,雪碧图应用的语法为:

background:url(images/sprite.png) no-repeat 0 0;

  background-image:url(images/sprite.png); 指定了元素的背景图像,background-repeat:no-repeat; 规定背景图像不重复,background-position:0 0; 设置背景图像的位置。 

  ③、background-position:0 0; 定义背景图像和它的位置(左0px,顶部0px)。

  整个 Sprite 图默认以左上角为坐标点(0,0),即 background-position 代表图片的起始位置,从左上角开始,x 轴向右为正,y 轴向下为正,所以一般 Sprite 值均为负值。background-position 的计算是指 0 点到图片左上角的偏移量,例如(-64px,-128px)就是整块雪碧图向左(x 轴)移动 64px ,向上(y轴)移动 128px,图片定位的原理,使用 px 为单位,这个值是一个偏移量,而不是具体的坐标值,正值向正轴方向偏移,负值则相反。

   这是使用图像拼合最简单的方法,雪碧图在网站中应用非常广泛,比如用户登录注册按钮,图标导航,电商网站的爆款、热卖、秒杀和抢购等的小图片,雪碧图可以把网站中涉及到的所有零星的小图标、背景图像合并在一张大图中使用,根据实际需要也可以合并为多张图。

  (2)、悬停效果

  :hover 选择器可用于鼠标悬停在元素上显示的效果,该选择器可以运用于所有元素。

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>CSS Sprite 悬停效果</title>
 6 <style>
 7 i{
 8     width:64px;
 9     height:64px;
10     display:block;
11     float:left;
12     margin-right:20px;
13     background:url(images/sprite.png) no-repeat;
14     opacity:1;
15 }
16 .right{
17     background-position:0 -64px;
18 }
19 .home{
20     background-position:0 -192px;
21 }
22 .love{
23     background-position:-64px -64px;
24 }
25 .left{
26     background-position:0 -128px;
27 }
28 .favorite{
29     background-position:-64px 0;
30 }
31 
32 i:hover{
33     opacity:0.3;
34     border:1px solid black;
35 }
36 .change:hover{
37     background-position:-64px -128px;
38 }
39 </style>
40 </head>
41 <body>
42 <i class="right change"></i>
43 <i class="home"></i>
44 <i class="love"></i>
45 <i class="left change"></i>
46 <i class="favorite change"></i>
47 </body>
48 </html>

  上面的代码,打乱了小图标的显示顺序,并且用1个小图标为带有 change 的类做了鼠标悬停效果,还增加了1像素的边框,也可以增加外边距,需要注意鼠标滑过图片时,为元素增加了边框会影响外边距,这样做可以变相的为静态图片增加动态效果,但是这只是一个演示效果,在实际的网站开发中有时仅1像素的问题就会影响到整体的布局结构,需要谨慎使用。

  (3)、图标导航

  可以使用雪碧图创建一个简单的图标导航:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>CSS Sprite 图标导航</title>
 6 <style>
 7 ul li{
 8     list-style:none;
 9     width:64px;
10     height:64px;
11     float:left;
12     margin-right:10px;
13     background:url(images/sprite.png) no-repeat;
14     opacity:1;
15 }
16 ul li a{
17     display:block;
18     height:64px;
19 }
20 #home{
21     background-position:0 -192px;
22 }
23 #left{
24     background-position:0 -128px;
25 }
26 #right{
27     background-position:0 -64px;
28 }
29 #favorite{
30     background-position:-64px 0;
31 }
32 #close{
33     background-position:-64px -128px;
34 }
35 ul li:hover{
36     opacity:0.5;
37 }
38 </style>
39 </head>
40 <body>
41 <ul>
42     <li id="home"><a href="#" title="主页"></a></li>
43     <li id="left"><a href="#" title="前进"></a></li>
44     <li id="right"><a href="#" title="后退"></a></li>
45     <li id="favorite"><a href="#" title="收藏"></a></li>
46     <li id="close"><a href="#" title="关闭"></a></li>
47 </ul>
48 </body>
49 </html>
50 
51 
52 
53 <br><br><br><br>
54 55 56 57 58 59 60 61 62 63

  上面代码中,每个列表项都包含一个链接,也可以使用 :hover 伪类让每个链接切换背景图:

1 #home a:hover{background:url(images/icon.png) no-repeat 0 0;}
2 #left a:hover{background:url(images/icon.png) no-repeat 0 -64px;}

  (4)、雪碧图应用

  一些电商网站的导航栏都位于页面左边,每项菜单前边都有一个小背景图,这就可以使用雪碧图完成。下面是需要用的图片:

  1 <!DOCTYPE html>
  2 <html>
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>CSS Sprite 应用</title>
  6 <style>
  7 *{margin:0;padding:0;}
  8 nav{
  9     width:150px;
 10     background:#F5F5F5;
 11     border:1px solid #A9A9A9;
 12     margin:20px;
 13 }
 14 ul{
 15     list-style:none;
 16     overflow:hidden;
 17 }
 18 li{
 19     border-bottom:1px solid #C0C0C0;
 20 }
 21 li:last-child{
 22     border-bottom:none;
 23 }
 24 a{
 25     display:block;
 26     height:35px;
 27     line-height:35px;
 28     font-size:14px;
 29     font-weight:400;
 30     color:black;
 31     text-decoration:none;
 32 }
 33 a:hover{
 34     color:red;
 35     background:#DCDCDC;
 36 }
 37 li i{
 38     float:left;
 39     width:24px;
 40     height:24px;
 41     margin:5px 10px 0 20px;
 42     background:url("images/sprite.png") no-repeat;
 43 }
 44 .icon-1 i{background-position:0 0;}
 45 .icon-2 i{background-position:0 -24px;}
 46 .icon-3 i{background-position:0 -48px;}
 47 .icon-4 i{background-position:0 -72px;}
 48 .icon-5 i{background-position:0 -96px;}
 49 .icon-6 i{background-position:0 -120px;}
 50 .icon-7 i{background-position:-24px 0;}
 51 .icon-8 i{background-position:-24px -24px;}
 52 .icon-9 i{background-position:-24px -48px;}
 53 .icon-10 i{background-position:-24px -72px;}
 54 .icon-11 i{background-position:-24px -96px;}
 55 .icon-12 i{background-position:-24px -120px;}
 56 </style>
 57 </head>
 58 <body>
 59 <nav>
 60     <ul>
 61         <li class="icon-1">
 62             <i></i>
 63             <h3><a href="#">家用电器</a></h3>
 64         </li>
 65         <li class="icon-2">
 66             <i></i>
 67             <h3><a href="#">手机数码</a></h3>
 68         </li>
 69         <li class="icon-3">
 70             <i></i>
 71             <h3><a href="#">电脑办公</a></h3>
 72         </li>
 73         <li class="icon-4">
 74             <i></i>
 75             <h3><a href="#">潮流服饰</a></h3>
 76         </li>
 77         <li class="icon-5">
 78             <i></i>
 79             <h3><a href="#">母婴玩具</a></h3>
 80         </li>
 81         <li class="icon-6">
 82             <i></i>
 83             <h3><a href="#">护肤彩妆</a></h3>
 84         </li>
 85         <li class="icon-7">
 86             <i></i>
 87             <h3><a href="#">鞋包皮具</a></h3>
 88         </li>
 89         <li class="icon-8">
 90             <i></i>
 91             <h3><a href="#">运动户外</a></h3>
 92         </li>
 93         <li class="icon-9">
 94             <i></i>
 95             <h3><a href="#">汽车用品</a></h3>
 96         </li>
 97         <li class="icon-10">
 98             <i></i>
 99             <h3><a href="#">美食旅游</a></h3>
100         </li>
101         <li class="icon-11">
102             <i></i>
103             <h3><a href="#">图书音响</a></h3>
104         </li>
105         <li class="icon-12">
106             <i></i>
107             <h3><a href="#">金融理财</a></h3>
108         </li>
109     </ul>
110 </nav>
111 </body>
112 </html>

  (5)、CSS Sprite 总结

  在网页中,没请求一次,即没加载一张图片,就会个服务器链接一次,建立链接是需要额外的时间,使用雪碧图可以加速网站的显示效果,他最根本的目的就是有效减少 HTTP 请求数量,加速内容显示。

  一些大图,比如动态图片或者用户上传的图片不能拼成雪碧图,雪碧图适用于以下几种情况:

    ①、静态图片,不随用户信息的变化而变化,在网站上以常态形式存在。

    ②、小图片,图片容量比较小,一般大小为 3-5K,或 3.5K 以下的图片。

    ③、加载量比较大的图片。

  Css Sprite 雪碧图,其实就是将小图标放在同一个 PSD 文件里,PSD 属于分层的可编辑的图片格式,通常需要使用 PS 或 FW 软件打开,就可以分离图层。透明背景的小图片都需要保存为 PNG 格式,他是图片格式的一种,常被用来作为网页的图标。

  Css Sprite 的原理,以雪碧图左上角为基准(0,0),通过 background-position 设置 x、y 偏移来显示需要的部分,x 向右为正,y 向下为负,所以一般都为负值。

13、CSS 导航栏

  拥有易用的导航栏,对于任何网站都非常重要。通过 CSS 可以把枯燥的 HTML 菜单转换成漂亮的导航栏。

  (1)、导航栏 – 链接列表

  导航栏需要标准的 HTML 作为基础,对于前端开发人员而言,一定要熟悉 Web 标准。

  导航栏基本上是一个链接列表,所以使用 <ul> 和 <li>元素非常适合,根据实际开发需求也可以使用自定义列表创建导航栏。

  下面是创建导航栏链接列表的标准 HTML 结构:

1 <ul>
2     <li><a href="URL">HTML</a></li>
3     <li><a href="URL">CSS</a></li>
4     <li><a href="URL">JavaScript</a></li>
5     <li><a href="URL">jQuery</a></li>
6 </ul>

  一个导航栏并不需要列表标记,并且需要初始化列表的样式,即清除列表的填充和外边距,这些都需要使用 CSS 定义:

1 ul{
2     list-style:none outside;
3     padding:0;
4     margin:0;
5 }

  这里仅仅只是初始化了列表的样式,在实际的网站开发中,需要对整个 HTML 文档进行初始化设置。

  (1)、垂直导航栏

  垂直导航栏通常都位于网站左侧,也可以叫左侧导航栏。如果需要构建垂直导航栏,只需要给 a 元素定义样式就可以了。因为 a 元素为内联元素,所以首先就需要把他转换为块元素,使用 CSS 定义 display:block ,即显示块元素的链接,让整体变为可点击链接区域,不只是链接文本。块元素默认情况下,是最大宽度,所以必需给导航栏指定宽度,再添加其他用于美化的样式。

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>左侧导航栏</title>
 6 <style>
 7 *{padding:0;margin:0;}
 8 ul{
 9     list-style:none outside;
10 }
11 a{
12     display:block;
13     background:#99CC33;
14     width:120px;
15     height:35px;
16     line-height:35px;
17     color:white;
18     font-weight:bold;
19     text-decoration:none;
20     text-align:center;
21 }
22 a:hover{
23     color:black;
24     background-color:#669933;
25 }
26 </style>
27 </head>
28 <body>
29 <ul>
30     <li><a href="URL">IT互联网</a></li>
31     <li><a href="URL">职业技能</a></li>
32     <li><a href="URL">语言学习</a></li>
33     <li><a href="URL">设计创作</a></li>
34     <li><a href="URL">兴趣爱好</a></li>
35     <li><a href="URL">职业规划</a></li>
36 </ul>
37 </body>
38 </html>

  现有的网站中,有一部分网站构建的左侧导航栏,并不是使用标准的 HTML 链接列表来布局的,而是使用 DIV 来完成的,比如京东商城左侧的导航栏,就使用的 DIV 嵌套标题链接布局的,也有一些网站是直接在 DIV 中嵌套链接,还有一些网站是通过一个列表项再嵌套 DIV 的方式来布局的,这样虽然都能达到目的,但严格来讲并不符合标准,大多数情况下左侧导航栏在鼠标移入时,都会在右侧显示该菜单栏的相关选项,与京东商城类似的比如苏宁、国美、小米的左侧导航栏都是使用标准的 HTML 链接列表来布局的。而淘宝网左侧的导航栏布局使用的是自定义链接列表,这也符合 HTML 标准。几乎所有网站构建的水平导航栏都是使用标准的 HTML 链接列表布局的。

  (2)、水平导航栏

  有两种创建水平导航栏的方法,使用内联或浮动的列表项。这两种方法都很好,但如果需要每个菜单项都拥用有相同的大小,就必须使用浮动的方法。

  ①、内联列表项

  创建一个水平导航栏的方法之一是就是把 li 元素转换为内联元素,默认 li 元素是块级元素,所以使用 CSS 设置 display:inline; 可以删除每个列表项之前和之后的换行符,以显示一行 。

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>内联水平导航栏</title>
 6 <style>
 7 *{padding:0;margin:0;}
 8 ul{
 9     list-style:none outside;
10     padding:10px 0;
11 }
12 li{
13     display:inline;
14 }
15 a{
16     background:#0000CD;
17     color:white;
18     font-weight:bold;
19     text-decoration:none;
20     padding:10px;
21 }
22 a:hover{
23     background-color:#191970;
24 }
25 </style>
26 </head>
27 <body>
28 <ul>
29     <li><a href="URL">首页</a></li>
30     <li><a href="URL">公司简介</a></li>
31     <li><a href="URL">经营发展</a></li>
32     <li><a href="URL">产品展示</a></li>
33     <li><a href="URL">新闻中心</a></li>
34     <li><a href="URL">在线服务</a></li>
35     <li><a href="URL">企业文化</a></li>
36 </ul>
37 </body>
38 </html>

  这里需要注意:如果只给 a 元素设置内边距,而不给列表设置,那么链接会出现在 ul 元素之外,所以必须给 ul 设置顶和底内边距。

  ②、浮动列表项

  使用内联列表项,链接的宽度是不同的,为了让所有链接拥有相等的宽度,需要给 li 元素设置浮动,并把 a 元素转换为块元素再指定宽度。

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>浮动水平导航栏</title>
 6 <style>
 7 *{padding:0;margin:0;}
 8 ul{
 9     list-style:none outside;
10     overflow:hidden;
11 }
12 li{
13     float:left;
14 }
15 a{
16     display:block;
17     background:#CCCCCC;
18     width:120px;
19     height:35px;
20     line-height:35px;
21     color:black;
22     font-weight:bold;
23     text-decoration:none;
24     text-align:center;
25     margin-right:2px;
26 }
27 a:hover{
28     color:white;
29     background-color:#000000;
30 }
31 </style>
32 </head>
33 <body>
34 <ul>
35     <li><a href="URL">首页</a></li>
36     <li><a href="URL">公司简介</a></li>
37     <li><a href="URL">经营发展</a></li>
38     <li><a href="URL">产品展示</a></li>
39     <li><a href="URL">新闻中心</a></li>
40     <li><a href="URL">在线服务</a></li>
41     <li><a href="URL">企业文化</a></li>
42 </ul>
43 </body>
44 </html>

14、CSS 媒体类型

  媒体类型(Media Type)是用于指定文件将如何在不同媒体呈现。该文件可以以不同的方式显示在屏幕上,在纸张上,或听觉浏览器等等。

  一些 CSS 属性仅仅被设计为针对某些媒体。例如 “voice-family” 属性被设计为针对听觉用户终端,其他一些属性可用于不同的媒体类型。例如,”font-size” 属性可用于屏幕和印刷媒体,但有不同的值。屏幕和纸上的文件不同,所以屏幕上显示的文档通常需要比纸媒体文档更大的字体,因此针对不同的媒体,需要使用不同的字体系列,使文本更易阅读。再比如电脑端和移动终端,因为屏幕尺寸的不同,所以更需要针对不同的设备定义不同的样式,即响应式布局。

  (1)、@media 规则

  @media 规则使你有能力在相同的样式表中,使用不同的样式规则来针对不同的媒体,简单说就是:可以在相同样式表为不同媒体设置不同的样式。

  下面的样式,使用 @media 规则指定在浏览器中段落显示为”14px“的”微软雅黑“字体,如果页面被打印,则段落显示为”10px“的”宋体“,不管是在浏览器页面上还是在纸上段落都被显示为加粗:

 1 @media screen{
 2     p{
 3         font-family:"Microsoft YaHei",Arial,Tahoma,sans-serif;
 4         font-size:14px;
 5     }
 6 }
 7 
 8 @media print{
 9     p{
10         font-family:'宋体';
11         font-size:10px;
12     }
13 }
14 
15 @media screen,print{
16     p{font-weight:bold;}
17 }

  (2)、不同的媒体类型

媒体类型 说明
all 用于所有设备。
screen 用于电脑屏幕,平板电脑,智能手机等。
speech 应用于屏幕阅读器等发声设备。
print 用于打印机和打印预览。

  

  注意:媒体类型不区分大小写。

15、CSS 重要性

  (1)、CSS 继承

  CSS 的某些属性是具有继承性的,继承是一种规则,它允许样式不仅应用于某个特定html标签元素,而且应用于其后代。

  比如下面的例子,给 p 标签设置字体颜色,这个颜色设置不仅应用 p 标签,还应用于 p 标签中的所有子元素文本。

 1 <head>
 2 <style>
 3 p{
 4     color:red;
 5     border:1px solid black;
 6 }
 7 </style>
 8 </head>
 9 <body>
10 <p>CSS 的某些属性是具有继承性的,<span>继承是一种规则,</span>它允许样式不仅应用于某个特定 HTML 标签元素,而且应用于其后代。</p>
11 </body>

  需要注意,有一些 CSS 样式是不具有继承性的,比如 border:1px solid black;。

  (2)、CSS 特殊性

  有时候我们为同一个元素设置了不同的 CSS 样式代码,浏览器会根据权值来判断使用哪种 CSS 样式,哪种样式权值高就使用该样式,所以理解选择器的特殊性很重要。

  权值就是所用选择器的特殊性,浏览器会根据这种特殊性来决定所定义的样式规则的次序,具有更特殊选择器的规则优先于具有一般选择器的规则,如果两个规则的特殊性相同,那么后定义的规则优先,这一点和 JS 相同,即后面定义的会覆盖前边定义的。

  覆盖也就是 CSS 层叠,当有相同权重的样式存在时,会根据这些 CSS 样式的前后顺序来决定,处于最后面的 CSS 样式会被应用。那么对于 CSS 样式优先级的顺序就不难理解了。

  特殊性可以分为4个等级,每个等级代表一类选择器:

    ①、代表内联样式,如 <p style=”color:red”></p>,权值为 1000。

    ②、代表 ID 选择器,如 #content,权值为 100。

    ③、代表类,类选择器以及伪类和属性选择器,如 .main,权值为 10。

    ④、代表类型选择器,标签和伪元素选择器,如 div p,权值为 1。

  通配符选择器(*),子选择器(>)和相邻同胞选择器(+)并不在这四个等级中,所以他们的权值都为 0。

  注意:继承也有权值的,但是继承的权值是最低的。

  每个等级的值为其所代表的选择器的个数乘以这一等级的权值(比如 ④ 中例子的权值为 2),最后把所有等级的值相加得出选择器的特殊值。比较同一级别的个数,数量多的优先级高,如果相同即比较下一级别的个数 。

  权值的规则:选择器的权值相加,大的优先;如果权值相同,后定义的优先 。

  权值的大小跟选择器的类型和数量有关,样式的优先级跟样式的定义顺序有关。

 1 p{ /* 权值为 1 */
 2     color:red;
 3 }
 4 p span{ /* 权值为 1+1=2 */
 5     color:green;
 6 }
 7 .main{ /* 权值为 10*/
 8     font-size:14px;
 9 }
10 div p .main{ /* 权值为 1+1+10=12 */
11     color:purple;
12 }
13 #footer{ /* 权值为 100 */
14     color:gray;
15 }
16 #footer .note p{ /* 权值为 100+10+1=111 */
17     color:white;
18 }

  (3)、CSS 重要性

  在实际的网站开发中,有些特殊的情况需要为某些样式设置具有最高权值,这时候我们可以使用 !important 来解决。

  具体实现如下:

 1 <head>
 2 <style>
 3 p{
 4     color:red!important;
 5 }
 6 .demo{
 7     color:green;
 8 }
 9 </style>
10 </head>
11 <body>
12 <p class="demo">在实际的网站开发中,有些特殊的情况需要为某些样式设置具有最高权值,这时候我们可以使用 !important 来解决。</p>
13 </body>

  上面的代码,使用标签选择器设置了段落字体为红色,再使用类选择定义了段落字体为绿色,标签选择器的权值为 1,类选择器的权值为 10,因为类选择器的权值更高,最终段落显示为绿色,但是我们使用了 important,这时段落中的文字就显示为红色。

  !important 拥有最高权值,需要注意,在使用时不能忘了前边的感叹号,并且要写样式的分号前边。

  当网页不设置 CSS 样式时,浏览器会按照自己的一套样式来显示网页。并且用户也可以在浏览器中设置自己习惯的样式,比如有的用户习惯把字号设置为大一些,使其查看网页的文本更加清楚。这时样式优先级为:浏览器默认的样式 < 网页的样式 < 用户自己设置的样式,但 !important 优先级样式是个例外,权值高于用户自己设置的样式。

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注