1、CSS 盒模型(Box Model)
所有 HTML 元素都可以看作是盒子,在 CSS 中,“Box Model”这一术语主要是在布局时使用。
CSS 盒模型(Box Model)规定了处理元素内容、边框、内边距 和 外边距 的方式。
CSS 盒模型本质上是一个盒子,封装周围的 HTML 元素,它包括:外填充也叫外边距(margin),边框(border),内填充也叫内边距(padding)和实际内容(content)。盒模型允许我们在其它元素和周围元素边框之间的空间放置元素。
如下 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 122 </div>23 <div id="box2">24 225 </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 元素被定义为块级元素或内联元素:
块级元素在浏览器显示时,通常会以新行来开始(和结束),块状元素排斥其他元素与其位于同一行,可以设定元素的宽和高以及内外边距,块级元素一般是其他元素的容器,可以容纳内联元素和其他块元素。常见的块级元素有: , -
,
,<hr>,
,
,
,
,