css元素及盒模型(一)
CSS中,每个元素会产生一个或者多个矩形盒,称为元素盒。元素盒的中心区域是内容区域,由内向外依次被padding,border,margin区域包裹。这些包裹的区域都可以设置为0,其中只有margin能设负值。
内容区域的背景,默认是延伸至border边界下面。这可以在border样式设置为虚线时清楚的看到。border的颜色在没有设置的情况下,默认为元素内容的颜色。
元素分类及不同盒模型
Nonreplaced element 非置换元素
内容包含在文档中的元素。如p元素,内容包含在元素中。
Replaced element 置换元素
作为一个内容不被包含在文档中的占位符。如img元素,指向一个image文件,这个外部文件插入img元素所在位置。其他置换元素还有input,button等等。
Root element 根元素
文档树顶端的元素。一般是html元素。
Block element 块元素
Block box 块盒
块级元素产生的盒子,如div、p等。任何元素都可以通过设置display:block来产生块盒。
Inline box 行内盒
strong、span等产生的盒子。任何元素都可以通过设置display:inline来产生行内盒。
Inline-block box 行内块盒
简单的说就是不换行的块盒。
containing block
元素盒的定位环境。通常情况下是产生list item或者块盒的最近祖先元素的内容区域。
<body>
<div>
<p>This is a paragraph.</p>
</div>
</body>
p的包含块为div,div的包含块为body,body的包含块为html元素,html元素产生的盒为initial containing block原始包含块。有点特殊的地方是它的尺寸大小不是由根元素的内容区域决定的,而是viewport浏览
器窗口大小决定。
需要注意的是,任何元素可以通过display属性来产生不同的盒模型,不代表能使得元素类型发生改变。
常用元素的类型
| Element | Type | Subtype | Notes |
| a | inline | special | |
| abbr | inline | phrase | |
| acronym | inline | phrase | |
| address | block | Behaves similarly to p in common practice | |
| blockquote | block | Must contain at least one block element when the declared !DOCTYPE is Strict | |
| body | Encloses the entire document canvas; commonly takes on a margin (in IE, Firefox, and Safari) or padding (in Opera) of 10px in screen media | ||
| cite | inline | phrase | |
| div | block | ||
| em | inline | phrase | |
| fieldset | block | Commonly rendered by default with border: 1px black; | |
| form | block | ||
| h1 … h6 | block | heading | |
| input | inline | formctrl | |
| img | inline | special | |
| label | inline | formctrl | |
| li | block | Element type not specified in Document Type Definition, but this element may contain either block or inline elements; the complete CSS 2.1 Recommendation sets aside a display value for list items | |
| ol | block | list | |
| p | block | May only contain inline elements; commonly rendered with top and bottom margins | |
| span | inline | special | |
| strong | inline | phrase | |
| table | block | ||
| ul | block | list |
元素水平定位原理
非置换元素
默认情况下元素的width为内容区域的宽度。一个块盒水平的七属性的和等于包含块内容区域。七属性分别为:margin-left,border-left,padding-left,width,padding-right,border-right,and margin-right
水平七属性中只有width,margin-left,margin-right能设置auto值。auto值的确定由包含块width值和七属性值已确定值的和的差值决定。比如
div {width: 500px;}
p {margin-left: auto; margin-right: 100px;width: 100px;} /* 'auto' left margin evaluates to 300px */
如果都是设置的确定值,而和与包含块width不相等时,那么margin-right被强制为auto
div {width: 500px;}
p {margin-left: 100px; margin-right: 100px;width: 100px;} /* right margin forced to be 300px */
其他情况:
div {width: 500px;}
p {width: 300px; margin-left: auto; margin-right: auto;} /* each margin is 100 pixels wide, because (500-300)/2 = 100 */
div {width: 500px;}
p {margin-left: auto; margin-right: 100px;width: auto;} /* left margin evaluates to 0; width becomes 400px */
当margin值为负数时:
div {width: 500px; border: 3px solid black;}
p.wide {margin-left: 10px; width: auto; margin-right: -50px; }
10px + 0 + 0 + 540px + 0 + 0 - 50px = 500px /* 计算出width值为540px*/因此超出包含块边界区域
百分数值
<p style="width: 67%; padding-right: 5%; padding-left: 5%; margin-right: auto;
margin-left: 5%;”>playing percentages
/ 18% (100% - 67% - 5% - 5% - 5%)/置换元素
与非置换元素不同的一点就是:如果width设置为auto,那么宽度等于置换元素本来的宽度,当设置宽度的具体值时,高度与宽度始终维持同一比例,除非也手动设置了高度的具体值。
元素垂直定位原理
一个元素的内容决定了元素的默认高度。如果内容高度超出了高度设定值,可以通过overflow属性来控制内容的显示与否。在CSS2以后,非置换元素的高度值不能省略,必须设置为auto或者其他具体的非负值,除了使用百分比的特定情况。
与水平元素的定位一样,一个块盒垂直的七属性的和等于包含块内容区域的高度。有趣的是,如果margin-top或者margin-bottom设置为auto那么都自动变为0,也就不能很容易的垂直定为一个块盒了。
<div style="height: 6em;">
<p style="height: 50%;">Half as tall</p>
</div>
/* p的高度将为3em,如果要将P垂直剧中于div,那么必须设置margin-top与margin-bottom的值为25%,而不能像水平元素那样设置为auto,因为在垂直方向上margin值为auto的值为0*/
如果父元素的高度设置为auto,那么子元素的百分比高度将被重置为auto,也就是p的高度和div的高度都等于内容的高度。
<div style="height:auto">
<p style="height: 50%;">NOT half as tall; height reset to auto</p>
</div>
自动高度
由上面的例子可以得出,当高度值设置为auto时,块盒的高度只要包裹行内元素的line box就可以了。后面会介绍line box的范围为行内所有元素inline-height的最小值到最大值的区域。就如p元素相对于它离开的行内元素。
如果块盒下只有块盒子元素,就如div相对于p元素,那么它默认的高度值为子元素border-box以内的内容。不包含margin区域。p元素的margin值会伸出div外,参与相邻元素margin塌陷值的计算。但是如果它有padding区域或者border区域,那么子元素的marigin值就包含进了div元素。
<div style="height: auto;background: silver;">
<p style="margin-top: 2em; margin-bottom: 2em;">A paragraph!</p>
</div>
<div style="height: auto; border-top: 1px solid; border-bottom: 1px solid;background: silver;">
<p style="margin-top: 2em; margin-bottom: 2em;">Another paragraph!</p>
</div>
margin塌陷
因为CSS中存在一个margin collapse,即边界塌陷或者说边界重叠。对于上下两个并列的div块而言,上面div的margin-bottom和下面div的margin-top会塌陷,也就是会取上下两者margin里最大值作为显示值。如果遇到上下两个并排内容块的安排,最好只设置其中每个块上或下margin的一处即可。
<ul>
<li> list1
<li> list2
</ul>
<h1> heading
ul {margin-bottom: 15px;background-color: grey;border: 1px solid;}
li {margin-top: 10px; margin-bottom: 20px;}
h1 {margin-top: 28px;}
由上面可知,ul的高度是不包括list1的margin-top,和list2的margin-bottom;通过设置
ul {margin-bottom: 15px; border: 1px solid;} margin值就包含在了ul的高度中。
负margin及塌陷
对于上下两个并列的元素块,会取上下两者margin绝对值最大的margin值。