理解盒模型
每一个元素都会在页面上生成一个盒子。因此,HTML页面实际上就是由一堆盒子组成的。
先从每个元素盒子的属性开始,这些属性可以分成三组:
- 边框(border)。可以设置边框的宽窄、样式和颜色。
- 内边距(padding)。可以设置盒子内容区与边框的间距。
- 外边距(margin)。可以设置盒子与相邻元素的间距。
中和外边距和内边距
推荐大家把下面这条规则作为样式表的第一条规则:
* {margin:0; padding:0;}
这条规则把所有元素默认的外边距和内边距都设定为零。把这条规则放到样式表里后,所有默认的外边距和内边距都会消失。然后,你可以为那些真正需要外边距的元素再添加外边距。稍后我们会介绍,不同浏览器默认的内边距和外边距也不一样,特别是对表单和列表等复合元素。在这种情况下,用前面那条规则“中和”默认值,然后再根据需要添加,则会在各浏览器上获得一致的效果。
叠加外边距
垂直方向上的外边距会叠加。假设有3 个段落,前后相接,而且都应用以下规则:
p {height:50px; border:1px solid #000; backgroundcolor:#fff; margin-top:50px;
margin-bottom:30px;}
由于第一段的下外边距与第二段的上外边距相邻,你自然会认为它们之间的外边距
是80 像素(50+30),但是你错啦!它们实际的间距是50 像素。像这样上下外边距
相遇时,它们就会相互重叠,直至一个外边距碰到另一个元素的边框。就上面的例
子而言,第二段较宽的上外边距会碰到第一段的边框。也就是说,较宽的外边距决
定两个元素最终离多远,没错——50 像素。这个过程就叫外边距叠加。
注意啦,叠加的只是垂直外边距,水平外边距不叠加。对于水平相邻的元素,它们
的水平间距是相邻外边距之和。这跟你最初想的一样。
好吧,我想必须得解释一下为什么要让外边距叠加。如果有一连串段落都被应用了相同的样式,那么对其中第一段和最后一段来说,它们的上外边距和下外边距决定了它们与包含元素的间距。而那些位于中间的段落呢,根本不需要两个外边距加起来那么宽的间距。因此,相邻的外边距叠加起来是最合理的,哪个外边距宽,就以哪个外边距作为段间距。
外边距的单位
根据经验,为文本元素设置外边距时通常需要混合使用不同的单位。比如说,一个段落的左、右外边距可以使用像素,以便该段文本始终与包含元素边界保持固定间距,不受字号变大或变小的影响。而对于上、下外边距,以em 为单位则可以让段间距随字号变化而相应增大或缩小,比如:
/*这里使用了简写属性把上、下外边距设置为.75em,把左、右外边距设置为30 像素*/
p {font-size:1em; margin:.75em 30px;}
盒子有多大
1、没有宽度的盒子
所谓“没有宽度”就是指没有显式地设置元素的width 属性。另外,“元素”和“盒子”从现在起代表同一个意思,至于选择哪一个,就要看到时候两者哪个最直接明了。如果不设置块级元素的width 属性,那么这个属性的默认值是auto,结果会让元素的宽度扩展到与父元素同宽。
盒模型结论一:没有(就是没有设置width 的)宽度的元素始终会扩展到填满其父元素的宽度为止。添加水平边框、内边距和外边距,会导致内容宽度减少,减少量等于水平边框、内边距和外边距的和。
2、有宽度的盒子
盒模型结论二:为设定了宽度的盒子添加边框、内边距和外边距,会导致盒子扩展得更宽。实际上,盒子的width 属性设定的只是盒子内容区的宽度,而非盒子要占据的水平宽度。
浮动与清除
浮动和清除是用来组织页面布局的又一柄利剑,这柄剑的剑刃就是float 和clear属性。浮动,你看这俩字儿多形象,意思就是把元素从常规文档流中拿出来。拿出来干什么?一是可以实现传统出版物上那种文字绕排图片的效果,二是可以让原来上下堆叠的块级元素,变成左右并列,从而实现布局中的分栏。
浮动元素脱离了常规文档流之后,原来紧跟其后的元素就会在空间允许的情况下,向上提升到与浮动元素平起平坐。
如果浮动元素后面有两个段落,而你只想让第一段与浮动元素并列(就算旁边还能放下第二段,也不想让它上来),怎么办?用clear 属性来“清除”第二段,然后它就乖乖地呆在浮动元素下面了。
1、浮动
(1)文本绕排图片
说得形象一点,在你浮动一张图片或者其他元素时,你是在要求浏览器把它往上方推,直到它碰到父元素(也就是body 元素)的内边界。后面的段落(带灰色边框)不再认为浮动元素在文档流中位于它的前面了,因而它会占据父元素左上角的位置。不过,它的内容(文本)会绕开浮动的图片。
浮动非图片元素时,必须给它设定宽度,否则后果难以预料。图片无所谓,因为它
本身有默认的宽度。
(2) 创建分栏
如果几个相邻的元素都具有设定的宽度,都是浮动的,而且水平空间也足以容纳它们,它们就会并列排在一行。
2、围住浮动元素的三种方法
方法一:为父元素添加overflow:hidden。
第一个方法很简单,缺点是不太直观,即为父元素应用overflow:hidden,以强制它包围浮动元素。
实际上,overflow:hidden 声明的真正用途是防止包含元素被超大内容撑大。应用overflow:hidden 之后,包含元素依然保持其设定的宽度,而超大的子内容则会被容器剪切掉。除此之外,overflow:hidden 还有另一个作用,即它能可靠地迫使父元素包含其浮动的子元素。
方法二:同时浮动父元素
将父元素也添加浮动,与父元素同级的元素则清除浮动。
方法三:添加非浮动的清除元素
第三种强制父元素包含其浮动子元素的方法,就是给父元素的最后添加一个非浮动的子元素,然后清除该子元素。由于包含元素一定会包围非浮动的子元素,而且清除会让这个子元素位于(清除一侧)浮动元素的下方,因此包含元素一定会包含这个子元素——以及前面的浮动元素。在包含元素最后添加子元素作为清除元素的方式有两种。
第一种方式不太理想,也就是简单地在HTML 标记中添加一个子元素,并给它应用clear 属性。由于没有默认的样式,不会引入多余空间,div 元素很适合这个目的。
没有父元素时如何清除
有时候,在清除某些浮动元素时,不一定正好有那么个父元素可以作为容器来强行包围它们。此时,最简单的办法就是给一个浮动元素应用clear:both,强迫它定位在前一个浮动元素下方。然而,在空间足以容纳多个元素向上浮动时,这个简单的办法未必奏效,我们还得另辟蹊径。
定位
CSS 布局的核心是position 属性,对元素盒子应用这个属性,可以相对于它在常规文档流中的位置重新定位。position 属性有4 个值:static、relative、absolute、fixed,默认值为static。
1、相对定位
相对定位,相对的是它原来在文档流中的位置(或者默认位置)。接下来,可以使用top、right、bottom 和left 属性来改变它的位置了。但多数情况下,只用top 和left 就可以实现我们想要的效果。
2、绝对定位
绝对定位跟静态定位和相对定位比,绝对不一样。因为绝对定位会把元素彻底从文档流中拿出来。元素之前占据的空间被“回收了”。这说明,绝对定位的元素完全脱离了常规文档流,它现在是相对于顶级元素body 在定位。而这自然而然就引出了一个关于定位的重要概念:定位上下文。由于绝对定位元素的定位上下文是body,所以在页面滚动的时候,为了维护与body元素的相对位置关系,它也会相应地移动。
3、固定定位
从完全移出文档流的角度说,固定定位与绝对定位类似。但不同之处在于,固定定位元素的定位上下文是视口(浏览器窗口或手持设备的屏幕),因此它不会随页面滚动而移动。
4、定位上下文
把元素的position 属性设定为relative、absolute 或fixed 后,继而可以使用top、right、bottom 和left 属性,相对于另一个元素移动该元素的位置。这里的“另一个元素”,就是该元素的定位上下文。
在讲绝对定位的时候,我们知道绝对定位元素默认的定位上下文是body。这是因为body 是标记中所有元素唯一的祖先元素。而实际上,绝对定位元素的任何祖先元素都可以成为它的定位上下文,只要你把相应祖先元素的position 设定为relative 即可。
事实上,只要把元素的外边距和内边距设定好,多数情况下只用静态定位就足以实现页面布局了。很多刚开始接触CSS 的初学者都会错误地设定position 属性,最终才发现从文档流中挪出来的这些元素一点也不好控制。因此,除非真需要那么做,否则不要轻易修改元素默认的position 属性。
显示属性
正如所有元素都有position 属性,所有元素也都有display 属性。尽管display 属性的值有很多,但大多数元素display 属性的默认值不是block,就是inline。
- 块级元素,比如段落、标题、列表等,在浏览器中上下堆叠显示。
- 行内元素,比如a、span 和img,在浏览器中左右并排显示,只有前一行没有空间时才会显示到下一行。
display 属性还有一个值有必要提一下,就是none。把元素的display 设定为none,该元素及所有包含在其中的元素,都不会在页面中显示。它们原先占据的所有空间也都会被“回收”,就好像相关的标记根本不存在一样。与此相对的是visibility属性,这个属性最常用的两个相对的值是visible(默认值)和hidden。把元素的visibility 设定为hidden,元素会隐藏,但它占据的页面空间仍然“虚位以待”。
背景重复
在此之前先提醒大家一句,CSS3 还规定另外两个值(但尚未得到浏览器支持),以控制背景图片重复确切的次数,即所有图片都是完整的,不会出现半张图片的现象。
- background-repeat:round:为确保图片不被剪切,通过调整图片大小来适应背景区域。
- background-repeat:space,为确保图片不被剪切,通过在图片间添加空白来适应背景区域。
背景位置的值
设定背景位置时可以使用三种值:关键字、百分比、绝对或相对单位的数值。可以使用两个值分别设定水平和垂直位置。
关键字指的顺序不重要,left bottom 和bottom left 意思相同。为了设定的值在所有浏览器中都有效,最好不要混用关键字值与数字值。
使用数值(比如40% 30%)时,第一个值表示水平位置,第二个值表示垂直位置。要是只设定一个值,则将其用来设定水平位置,而垂直位置会被设为center。
在使用关键字和百分比值的情况下,设定的值同时应用于元素和图片。换句话说,如果设定了33% 33%,则图片水平33%的位置与元素水平33%的位置对齐。垂直方面也一样。
像素之类的绝对单位数值就不一样了。要是用像素单位来设定位置,那么图片的左上角会被放在距离元素左上角指定位置的地方。
有意思的是,还可以使用负值。这样就可以把图片的左上角定位到元素外部,从而在元素中只能看到部分图片。当然,给图片设定足够大的正值,也可以把图片的右下角推到元素外部,从而在元素中也只能看到部分图片。位于元素外部的那部分图片不会显示。
背景尺寸
background-size 是CSS3 规定的属性,但却得到了浏览器很好的支持。这个属性用来控制背景图片的尺寸,可以给它设定的值及含义如下。
- 50%:缩放图片,使其填充背景区的一半。
- 100px 50px:把图片调整到100 像素宽,50 像素高。
- cover:拉大图片,使其完全填满背景区;保持宽高比。
- contain:缩放图片,使其恰好适合背景区;保持宽高比。
背景粘附
background-attachment 属性控制滚动元素内的背景图片是否随元素滚动而移动。这个属性的默认值是scroll,即背景图片随元素移动。如果把它的值改为fixed,那么背景图片不会随元素滚动而移动。
background-attachment:fixed 最常用于给body 元素中心位置添加淡色水印,让水印不随页面滚动而移动。实现这种效果的CSS 规则如下:
body {
background-image:url(images/watermark.png);
background-position:center;
background-color:#fff;
background-repeat:no-repeat;
background-size:contain;
background-attachment:fixed;
}
其他CSS3 背景属性
CSS3 又新增了一些新的背景属性,这里来简单介绍一下。不过,这些属性受支持的程度并不一致,如果你想使用它们,别忘了测试自己的页面在这些属性不可用时会出什么问题。要不,就使用Modernizr 来检测浏览器对它们的支持情况,并为不支持它们的浏览器提供替代CSS。
Modernizr 是一个JavaScript 库,用于检测用户浏览器支持哪些HTML5 和CSS3 功能。更多信息,请参考这个网址:http://modernizr.com。
- background-clip。控制背景绘制区域的范围,比如可以让背景颜色和背景图片只出现在内容区,而不出现在内边距区域。默认情况下,背景绘制区域是扩展到边框外边界的。
- background-origin。控制背景定位区域的原点,可以设定为元素盒子左上角以外的位置。比如,可以设定以内容区左上角作为原点。
- background-break。 控制分离元素(比如跨越多行的行内盒子)的显示效果。
厂商前缀
为鼓励浏览器厂商尽早采用W3C 的CSS3 推荐标准,于是就产生了VSP(Vendor Specific Prefixes,厂商前缀)的概念。
有了这些CSS 属性的前缀,厂商就可以尝试实现W3C 涵盖新CSS 属性的工作草案。在迅速实
现新属性的同时,还可以声明它们是过渡的、部分实现的,或者实验性的。总之,后果由使用者自负。
就拿W3C 推荐的transform 属性为例,标准语法是这样的:
transform: skewX(-45deg);
然而,由于这个属性还没有完全定案,为保证在大多数浏览器以及它们的实验性实现中能够使
用这个属性,应该针对想要支持的浏览器为该属性添加VSP。每个浏览器只使用各自能理解的属性声明。
-moz-transform:skewX(-45deg); /* Firefox */
-webkit-transform:skewX(-45deg); /* Chrome 及Safari */
-ms-transform:skewX(-45deg); /* 微软Internet Explorer */
-o-transform:skewX(-45deg); /* Opera */
transform:skewX(-45deg); /* 最后是W3C 标准属性 */
VSP 的开头是一个连字符,然后是前缀名,接着又是一个连字符,最后是W3C 属性名。另外要特别注意,在带前缀的属性声明之后还要声明W3C 标准属性,以备将来有浏览器实现完整的不带前缀的属性时派上用场。这里的Safari 和Chrome 都使用相同的-webkit-前缀,是因为它们都使用Webkit 渲染引擎。
以下CSS3 属性必须加VPS:
border-image translate
linear-gradient transition
radial-gradient background*
transform background-image*
transform-origin
* 针对背景图片或渐变
背景渐变
渐变分两种,一种线性渐变,一种放射性渐变。线性渐变从元素的一端延伸到另一端,放射性渐变则从元素内一点向四周发散。
下面来看一个简单的线性渐变的例子,HTML 标记如下:
<div class='gradient1'></div>
<div class='gradient2'></div>
<div class='gradient3'></div>
CSS 规则如下。
/*为元素盒子添加样式*/
div {
height:150px;
width:200px;
border:1px solid #ccc;
float:left;
margin:16px;
}
/*例1:默认为从上到下*/
.gradient1 {
background:linear-gradient(#e86a43, #fff);
}
/*例2:从左到右*/
.gradient2 {
background:linear-gradient(left, #64d1dd, #fff);
}
/*例3:左上到右下*/
.gradient3 {
background:linear-gradient(-45deg, #e86a43, #fff);
}
- 渐变点
渐变点就是渐变方向上的点,可以在这些点上设定颜色和不透明度。通过设定下一
个渐变点的颜色值,就可以控制渐变的效果。可以添加任意多个渐变点。渐变点的
位置一般使用整个渐变宽度的百分比来表示。
/*例1:50%处有一个渐变点*/
.gradient1 {
background:linear-gradient(#64d1dd, #fff 50%, #64d1dd);
}
/*例2:20%和80%处有两个渐变点*/
.gradient2 {
background:linear-gradient(#e86a43 20%, #fff 50%, #e86a43 80%);
}
/*例3:25%、50%、75%处有三个渐变点*/
.gradient3 {
background:linear-gradient(#64d1dd, #fff 25%, #64d1dd 50%, #fff 75%,
#64d1dd);
}
/*例4:为同一个渐变点设定两种颜色可以得到突变效果*/
.gradient4 {
background:linear-gradient(#e86a43, #fff 25%, #64d1dd 25%, #64d1dd 75%,
#fff 75%, #e86a43);
}
linear.png
如果不是使用百分比或其他值声明渐变点的位置,则三种颜色会均匀分布于整个渐变,其实际位置是0%、50%和100%。
- 放射性渐变
放射性渐变比线性渐变复杂那么一点点,因为可用的控制点多一些。如果你写过程序,从属性值中的括号就可以看出,渐变属性其实是函数。什么是函数?函数可以接收参数,然后根据这些参数来生成渐变。在创建放射性渐变时,可以使用参数指定形状、位置、尺寸、颜色和不透明度。
.gradient1 {
background: -webkit-radial-gradient(#fff, #64d1dd, #70aa25);
}
.gradient2 {
background: -webkit-radial-gradient(circle, #fff, #64d1dd, #e86a43);
}
.gradient3 {
background: -webkit-radial-gradient(50px 30px, circle, #fff, #64d1dd,
#4947ba);
}
radial.png
这里虽然只声明了-webkit-前缀,但带有其他厂商前缀的属性也是必要的。
网友评论