1、盒模型的历史
CSS1没有盒模型的概念,盒模型的前身在CSS1里叫做面向盒的格式化模型。
CSS2.1明确了盒模型(box model)。元素抽象为盒,以盒为对象设计思路清晰多了。
CSS3的盒模型丰富了更多属性。
2、盒模型的构成以及相关CSS特性
2-1、概念
CSS假定每个元素都会生成一个或多个矩形框,这称为元素框,也叫盒模型、盒子模型、框模型。
CSS盒模型规定了元素框处理元素内容、内边距、边框和外边距的方式。
2-2、结构
一个盒模型由content、padding、border、margin这4个部分组成。
为了给文档树中的各个元素排版定位(布局),浏览器会根据渲染模型为每个元素生成四个嵌套的矩形框,分别称作content box、padding box、border box、margin box,它们是不可分割的,并可能会重合。它是以CSS的角度去看一个元素被渲染后的抽象形态。是一个元素自身的构成部分,不同于布局:多个元素在页面上的定位。
边界
content:content边界环绕在该元素的宽和高决定的一个矩形上,这个尺寸通常由该元素渲染后的内容决定。这四个content边界组成的矩形框就是该元素的content box。
padding:padding边界环绕在该元素的padding区域的四周,顾名思义,填充背景色,在此范围内有效。如果padding的宽度为0,则padding边界与content边界重合。这四个padding边界组成的矩形框就是该元素的Padding box。
border:border边界环绕在该元素的border区域的四周,如果border的宽度为0,则border边界与padding边界重合。这四个border边界组成的矩形框就是该元素的border box。
margin:margin边界环绕在该元素的margin区域的四周,如果margin的宽度为0,则margin边界与border边界重合。这四个margin边界组成的矩形框就是该元素的margin box。
举个栗子
2-3、相关的CSS特性
2-3-1、margin
margin是margin-top、margin-right、margin-bottom、margin-left的简写,表明margin的大小范围。它的值可以是宽度值、百分比值或auto这三者之一,注意,宽度值必须带有单位。
有几种元素,margin不起作用。
2-3-1-1
举个栗子
2-3-1-2
行内非替换元素,垂直方向的margin不起作用。
举个栗子
2-3-1-3
垂直方向上的不同元素的相邻margin在某些情况下,会发生折叠的现象。
举个栗子
2-3-2、padding
padding是padding-top、padding-right、padding-bottom、padding-left的简写,默认值是0。
可以应用到的元素:除了display值是table-row-group、table-header-group、table-footer-group、table-row、table-column-group、table-column的所有元素。
2-3-3、border
border是border-top、border-right、border-bottom、border-left的缩写,默认值是0。
border包含3个部分,border-width、border-style、border-color分别用来设置它的宽度,样式,颜色。适应用任何元素。
border-width是border-top-width、border-right-width、border-bottom-width、border-left-width。默认值是0。可用值有thin、medium、thick,以及常用的数值待单位的宽度值。
border-style:默认值是noen特性的值。可用值有:none、hidden、dotted、dashed、solid、double、groove、ridge、inset等。
border-color:默认值是color特性的值。
3、盒子的布局
视觉格式化根据CSS盒模型为文档的每个元素生成0,1或几个盒子。每个盒子的布局:
盒子的尺寸:指定或没有指定;
盒子类型:内联inline,内联级别,原子内联级别,块盒子;
定位方案position scheme:常规流、浮动、绝对定位;
书中的其他元素:它的子代与同代;
视口viewport尺寸与位置;
内涵图的固定尺寸;
其它信息。
4、盒子的生成
CSS视觉格式化模型的一部分工作是从文档元素生成盒子。生成内容不同于普通元素,有它自己的规则。盒子的类型取决于CSS属性display。
4-1、块级元素(blcok-level elements)与块盒子(block boxes)
块级元素:元素的CSS属性display为block、list-item或table。块级元素视觉上呈现为块,竖直排列。
块级盒子参与块级格式化上下文(block formatting context)。
主要块级盒子(principal block-level box):每个块级元素至少生成一个块盒子。一些元素,比如li,另外生成一个盒子来放置项目符号。不过多数只生成一个主要块级盒子。
主要块级盒子将包含后代元素以及生成内容生成的盒子。它也是可以使用定位方案position scheme的盒子。
一个块级盒子可能也是一个块容器盒子。
块容器盒子(block container box)只包含其它块级盒子,或生成一个内联格式化上下文(inline formatting context),因而只包含内联盒子。
注意块级盒子与块容器盒子概念不同。块级盒子描述元素跟它的父元素与兄弟元素之间的表现,块容器盒子描述元素跟它的后代之间的表现。一些块级盒子,比如表格,不是块容器盒子。相反,一些块容器盒子,比如非替换内联盒子及非替换表格单元格,不是块级容器。
同时是块容器盒子的块级盒子称为块盒子(block boxes)。
5、外边距折叠(Collapsing margins)
5-1、概况及名词解释
5-1-1、外边距重叠
指的是毗邻的两个或多个外边距(margin)会合并成一个外边距。
5-1-2、margin毗邻
*这两个或多个外边距没有被非空内容隔开、padding、border、clear分隔开,说明其位置关系。
*这些margin都处于普通流中。
*在没有被分隔开的情况下,一个元素的margin-top会和它普通流中的第一个子元素(非浮动元素等)的margint-top相邻。
举个栗子
由栗子可见,margin会把B的包含块撑开;
margin-top没有限制,所以margin-top的值是40px,margin-bottom没有折叠,所以margin-bottom的值是20px。
*只有在一个元素的height是auto的情况下,它的margin-bottom才会和它普通流中的最后一个子元素(非浮动元素等)的margin-bottom相邻。
举个栗子
5-1-3、两个或多个
说明其数量必须是大于一个,又说明,折叠是元素与元素之间的行为,不存在A和B折叠,B没有和A折叠的现象。
5-1-4、垂直方向
是指具体的方向,只有谁知方向的margin才会折叠,也就是说,水平方向的不会发生折叠。
5-2、折叠后margin的计算
5-2-1、参与折叠的margin都是正值
在margin都是正数的情况下,取其中margin较大的值为最终margin值。
举个栗子
由栗子可见,A盒子的margin-bottom值是10px,B盒子的margin-top值是30px,取其中margin较大的值,所以这两个盒子的距离是30px。
5-2-2、参与折叠的margin都是负值
当margin都是负值时,取的是其中绝对值较大的,然后从0位置,负向移动。
举个栗子
由栗子可见,A盒子的margin-bottom值是-40px,B盒子的margin-top值是-10px,取其中margin绝对值较大的,然后从0位置负向移动,A盒子和B盒子互相重叠。
5-2-3、参与折叠margin中有正值,有负值
有正有负,先取出负margin中绝对值中最大的,然后和正margin值最大的margin相加。
举个栗子
由栗子可见,A盒子的margin-bottom值是-50px,B盒子的margin-top值是100px,最终的margin应该是100+(-50)=50px。
5-2-4、相邻的margin要一起参与计算,不得分步计算
要注意:相邻的元素不一定非要是兄弟节点,父子节点也可以,即使不是兄弟父子节点也可以相邻。而且,在计算时,相邻的margin要一起参与计算,不得分步计算。
举个栗子
错误的计算方式:
算A和B之间的margin,分别算A和其父元素的折叠,然后与其父元素的父元素的折叠,这个值算出来之后,应该是90px。
依此法算出B的为80px,然后A和B折叠,margin为90px。
正确的计算方式:
A和B之间的margin折叠产生的margin,是6个相邻的margin折叠的结果。将其margin值分为两组:
正值:50px、150px、200px
负值:-60px、-100px、-120px
根据有正有负的计算规则,正值的最大值为200px,负值中绝对值最大的是120px,所以,最终折叠后的margin应该是200+(-120)=80px
5-3、margin collapse特性
5-3-1、浮动元素、inline-block元素、绝对定位元素的margin不会和垂直方向上其他元素的margin折叠
浮动元素的margin在垂直方向上不会发生margin折叠,即使和它相邻的子元素也不会。
举个栗子
由栗子可见,两个绿色模块之间相距100px,而若B和它的浮动包含块发生margin折叠的话,黄色的条应该位于绿色块的最上方,显然,没有发生折叠。
如果没有浮动?
由栗子可见,两个绿色模块之间相距50px。
5-3-2、创建了块级格式上下文的元素,不和它的子元素发生折叠
以overflow:hidden;的元素为例
由栗子可见,若B和它的overflow:hidden;包含块发生折叠的话,黄色背景条应该位于绿色块的最上方,否则,没有发生。
5-3-3、元素自身的margin-bottom和margin-top相邻时也会发生折叠
自身margin-bottom和margin-top相邻,只能是自身内容为空,垂直方向上border、padding为0。
5-4、margin collapsing产生条件
在CSS2.1中,水平margin永远不折叠,垂直margin重合有以下几种情况:
普通流中两个或多个块框相邻的垂直margin会折叠。
浮动框和其他框之间的垂直margin不会折叠(浮动框与浮动框内的浮动框margin不折叠)。
BFC框之间垂直margin不折叠(BFC框与BFC框垂直margin不折叠)。
绝对定位框之间margin不折叠(绝对定位框与绝对定位框内的绝对定位框margin不折叠)。
inlin-block框之间margin不折叠(inline-block框与inline-block框内的inline-block框margin不折叠)。
如果框的margin-top和margin-bottom都与其他框毗邻,那很可能发生折叠,框的位置由折叠后决定。
如果元素的margin-top与父元素的margin-top折叠,那么元素的border-top边距和父元素的border-top边距一样。
否则,要么元素的父元素没有参与margin折叠,要么只有父元素的margin-bottom折叠。如果元素有1个非0的border-bottom时,元素的border-top边框和父元素。