学一点前端很有必要,简单总结下。
在我们网页上的每一个元素,一个按钮,一段文本,一张图片等等,浏览器都将它们当做一个“盒子”看待,并把这样的盒子称为盒模型(box model)。既然是模型,必定有矩可循,如果各不相同就不能叫模型了。
使用Chrome(当然FireFox也行)的右键->审查元素对某个网页上的元素看下,就可得到类似这样一张图,这就是盒模型的缩影了。
组成盒模型主要是这几个要素:外边的外边距margin、中间的边框border、里边的内边距padding(个人喜欢叫内填充)(再往里就是包围元素实体的宽、高了)。在padding这个块里面,包括实体元素的宽高,就是背景background横行的地方,一般我们所添加的背景图片、背景颜色会充满padding这里面的一块区域,所以padding变大,背景会跟着扩张,当然前提是没有精确控制背景的位置、平铺方式等参数。
CSS的盒子是包括margin的,但是按照人的看图思考方式,至少我觉得将border到里边看做成生活中的盒子更符合常理嘛。我情愿把CSS的盒子转换成生活中的盒子,当然这个盒子可以随时改尺寸,border是盒子边框厚度,width跟height规定盒子中放的物体的宽高,至于是不是恰好等于实际物体的宽高自己定,小于的话就以实际物体为准了,padding规定盒子的边框到盒子里面堆放物体的范围(宽x高,上图中蓝色区域)的距离,设置一个padding值,避免内容被生硬的装在盒子中,与边框保持一点距离,可以显得不那么拥挤,所以border和padding是不能为负值的,硬给一个负数浏览器也归为零。margin是规定其他的标签与本标签的距离,即其他的盒子与本盒子之间的边距,仿佛是在宣誓主权:方圆xx距离的地方是爷的地盘,别过来!当然有时并非如此,因为margin可以为负值。
从图中看出,CSS的盒模型是四四方方的,所以对盒子的修饰的margin、border等是有四个方向的。比如margin样式的添加,通常是这样:
margin: 5px; margin: 5px 10px; margin: 5px 10px 15px 20px;
第一种是上下左右均为5像素,第二种是上下5像素,左右10像素,第三种最具体的,顺序上(margin-top)、右(margin-right)、下(margin-bottom)、左(margin-left)的设置外边距,顺指针转,上在前,所以记不清第二种的是上下5像素还是左右5像素就很好办了,反正顺时针转,上最先开始,所以第二种写法前面自然就是指上下外边距了。当然也可针对各个具体的方向具体设置。
如果设置为auto就是让浏览器自动给值了,比如当要使某段居中时可以这样(倔强的不考虑-IE6+,不想碰这个魔鬼)
.txt{ width:760px; margin:0 auto; }
上下外边距是0,左右边距是auto,意在让浏览器自己计算,浏览器根据当前父元素宽度,假定就是body,来把760像素宽的元素放在上面,并计算保证它的左右边距的差值始终为0,所以类名为txt的元素就在网页上居中了。
还是先说盒子,浏览器将每一个元素都当盒子来处理,但不是所有的盒子都一样,主要分两种类型:行内盒子(inline box)和块级盒子(block box)。它们对应着两种标签:行内标签和块级标签。块级标签的前后会产生一些空格,如div、h1、p、table等,前后会直接换行,如果不做处理,它们总是单独霸占一行,而行内标签前后不会产生空格,不做处理时标签后边有多少内容就接多少,比如strong、em、a、input等。
大多数情况,浏览器对这两种盒子的处理是一致的,均可添加左右外边距、左右边框、左右内填充,且真正做到与其他元素隔开一定的距离,margin-top为10像素时,真的就离上边的对象10像素远。但是有一种情况例外,可以试试下面代码:
<!DOCTYPE html><html> <head> <title>inline test</title> <style type="text/css"> .segment{ width:400px; margin:0 auto; padding:5px; border:2px solid #509ddd; } .txt{ margin:10px; padding:10px; border:1px solid #e61f44; } </style> </head> <body> <p class="segment"> The human species' use of technology began with the conversion of natural resources into simple tools. The prehistorical discovery of the ability to control <strong class="txt">fire increased</strong> the available sources of food and the invention of the wheel helped humans in travelling in and controlling their environment. Recent technological developments, including the printing press, the telephone, and the Internet, have lessened physical barriers to communication and allowed humans to interact freely on a global scale. </p> </body></html>
选择一段文本中间的几个单词用strong标签修饰,给了一个类txt,整段文字居中,strong包围的单词在样式分别给了margin、padding、border,是不是这两个单词的上下左右都会有一定的间距?效果
可以看出fire increased的左右确实增加了margin和padding,因为红色边框左右都有一些空白,margin和padding是以border为边界,上下的border边框则直接与上下的文本重合了,padding给了却没有产生间距,这就是因为span是行内标签(inline),对待行内标签,上下边距给了也是白给,不会产生效果,这是行内标签的特性(我还曾傻傻的使劲增大margin=_=),当然这个地方可以用line-height来增大行间距。
而块级标签就不同,浏览器把它当成一个整体,一个块,所以它的前后有换行,它的margin、padding无论哪个方向都起作用,都会产生距离。天生就是行内标签怎么办,难道注定一生上下受欺压?当然不是,css有个属性display,展示方式,比如当它为none时可以将元素整体隐藏起来,它还有另外的值,如block、inline、inline-block...如果给上边的txt类添加display:block;属性值,它会单独占一行,也许给它加个背景更醒目,效果
还有一种inline-block,字面意思是行内块,不妨将上面的txt类选择器中的display值改为inline-block看看
改为inline-block属性值后,它的前后没有换行,但是在这一行内它的margin、padding都产生了效果,所以它是介于inline和block之间的一种,既能维持在一行之内,前后不换行,还能在这一行内被当做是一个块,看上去就像是这一行跟其他的行的行间距相比变大了,因为他的间距,行内其他的单词也跟上下隔开了。
这就是三种主要的display状态,对于平常简单的应用够了,当然它还有其他值,都去看不整死个人-_-
元素背景,很有意思,上面说过,background是跟着padding的大小走的,如果你没有精确控制背景的位置,比如简单设置一个background-color
<html> <head> <title>background</title> <style type="text/css"> * { margin:0; padding:0; border:0; } #d1 { width:100px; height:100px; padding: 10px; background-color:red; } </style> </head> <body> <div id="d1"></div> </body></html>
用Chrome的审查元素查看(或者Firefox的查看元素),padding为10px,双击它逐渐增大或减小,就可以看到,background-color是跟着padding走的,padding变大颜色块跟着变大,padding值不能为负,强制给padding一个负数的话,是不合法的,border也是如此。
background的简写是类似这样的
background:url(images/bg.png) no-repeat 1px 1px #deddd6;
挂一个背景图片,图片路径在url参数的括号里,不重复显示,位置在距左内边距(padding)1像素,距上内边距1像素,如果这个图片不存在,则使用最后一个十六进制颜色填充。这里对背景图片做了精确控制,距上边1px,左边1px,这个值可以是百分比,如0%距顶部0像素,50%则是把图片的中间放在元素上,奇妙的是这里的距离值可以给负数,所以可以使得背景图片只在元素中显示一部分,甚至将图片移出元素,可以试试。这点很重要,比如在有的网站的导航时,进入网站是一个图标,鼠标滑过(hover)时换成另一个图标,就可以这样弄
<html> <head> <title>background</title> <style type="text/css"> * { margin:0; padding:0; border:0; } .link{ width:32px; height:34px; display:block; padding-left: 28px; text-decoration: none; background:url(./CSS2e_MM/09/nav_bar/images/nav.png) no-repeat 0% 0%;/*中间时以背景图中心点为准*/ } a.link:hover{ background:url(./CSS2e_MM/09/nav_bar/images/nav.png) no-repeat 0% 50%; } </style> </head> <body> <a class="link" href="#">link</a> </body></html>
进入页面是这样,鼠标滑过时是这样,真正的背景图(nav.png)其实是这样。
核心就在于,鼠标滑过链接时(a.link:hover选择器),比如这里,将背景图的位置,距离顶部设置成50%,即将图片的中间,css会保证背景图片的中心点位于元素的中间(这里背景图片的高度是大于当前a标签的高度的),因此只是可视位置移了一下而已,就可达到一个动态效果,图片整体还是一张,这就是因为背景图片的可视范围是padding所指定的区域,出了这个范围我们就看不到了,其实很多网站都用到了。背景处在它所在的标签下方,会遭到元素内容的覆盖。
元素的宽高,不设置时,默认为自适应元素的所占的实际宽高值,比如直接p标签贴上一段文本,但是网页上经常分块放置,每一块都是宽高是计算好的,特别是有时真实图片可能太大,用img标签装载一张图,设置一个小的width和height,网页上显示的就是一张缩小后的图片,当然也能放大。所以我们看到的图片大小可能不是真实的图片尺寸。关于宽高的一个常见的现象,就是溢出,比如
<!DOCTYPE html><html> <head> <title>inline test</title> <style type="text/css"> .segment{ width:200px; height:100px; margin:0 auto; padding:5px; border:2px solid #509ddd; } </style> </head> <body> <p class="segment"> The human species' use of technology began with the conversion of natural resources into simple tools. The prehistorical discovery of the ability to control fire increased the available sources of food and the invention of the wheel helped humans in travelling in and controlling their environment. Recent technological developments, including the printing press, the telephone, and the Internet, have lessened physical barriers to communication and allowed humans to interact freely on a global scale. </p> </body></html>
效果:
对于这种溢出,因为宽高可能设置太小,可以使用overflow属性,它有几个常用值:hidden(隐藏)、scroll(滚动条)、auto(自动,超过宽高范围自动出现滚动条),比如scroll
也可以设置hidden,将超过范围的内容隐藏掉,这就完全看情况了。
对于边框,它是分隔margin和padding的一道墙,也可以说背景是以它为界的。border的设置跟其他的类似。border属性值的设置有个特点就是,如果没有设置边框线的风格,边框线便不会出现,风格没有默认值,所以可以是border:1px solid;,黑色为默认边框颜色,但不能是border:1px #f00;,border:1px;就更不行了。当然你也可以单独设置样式border-style、宽度border-width、颜色border-corlor,更具体的是针对某一边的设置,如border-top-style,设置顶边框的样式等等。
对于margin,也是个有意思的东西,有意思的地方在于,它可以是负值。一般的,我们会设置一个正的margin值来进行“主权宣誓”,让别的元素离它远点,比如下边
<!DOCTYPE html><html> <head> <title>margin test</title> <style type="text/css"> .spanA{ margin:5px; padding:5px; background-color:#accedd; } .spanB{ margin:5px; padding:5px; background-color:#66cdaa; } </style> </head> <body> <span class="spanA">Hello</span> <span class="spanB">World</span> </body></html>
效果:
如果让World所在的区域的margin为负值会怎样?修改spanB选择器里边的margin值
.spanB{ margin:-35px; padding:5px; background-color:#66cdaa; }
效果:
第二个单词与第一个重叠,甚至覆盖了它,所以对于第二个元素来说,形象点就是,“即便你骄傲的拒绝,我也要穿越人海找到你”(电视剧中经常发生),第一个元素是本能的拒绝的,因为它的margin为正,已经告知别的元素请离我5像素的距离,但第二个元素的margin为负,压根不听。如果再变化一下,比如像两个选择器的属性值调整成下面的
.spanA{ margin:5px; margin-left:40px; background-color:#accedd; } .spanB{ margin:-95px; background-color:#66cdaa; }
效果:
第一个和第二个元素的位置完全对调过来了,但是原来html代码没有变,实际上World是在Hello的前面。所以很有可能我们看到的一些网站,比如左边一个侧边栏,中间一块主要内容,右边可能还有一个侧边栏,看起来展示是这样的顺序,实际摆放的html源码却不是这样,可能主要内容那一块是在最前面。这么做当然有优化的考虑,有的网页内容太多,搜索引擎一次收录的内容是有限的,可能到网页中某个部分就停止了,搜索引擎读取的就是html源码,除了一般的meta标签设置keywords、description提高网站识别度,主要内容也可能更能体现出这个网站的内容相关性,所以将主要内容这一块源码放在靠前的位置更能起到优化(seo)的作用,这是非常有意义的,当然了,也挺折腾=_=
既然margin为负,可以将元素提到其他元素前面,那继续给它大一点的负值呢,元素很可能就偏离出视区了,给隐藏掉了,就像背景图片的精确定位一样,也可以隐藏。比如给spanB的margin给一个-200px,就会发现World不见了,它就是偏到浏览器“外边”去了,让它暂时“消失不见”,但是它仍在代码中,这点就很有意思,比如下边这个
现在有三个按钮:综合、公告、活动,每个栏目下边新闻条目几乎沾满这个宽度,是固定的,点击公告时,当前新闻列表往左一拉,公告列表从右往左出现在视区中,原来的综合列表新闻向左一拉消失不见了,css中有个left属性,表示元素距离父元素左边距的值,也可以给负值,负值也会让本元素偏离视区,想象一下,原本综合、公告、活动三项对应下面的新闻列表已经存在于网页之上,只是我们看不到而已,现在点击下公告(js更改left属性),就将left的值设为这一个块的宽度值,只不过是负数,那么原来的综合列表向左一拉就“消失”了,出现在眼前的是公告下的列表,但实际上,它们早已存在,这就是一个负值有趣的应用了,跟margin给负值很像吧,感觉被戏弄了-_-#