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值。