CSS盒模型总结

198 阅读8分钟

CSS比较全,可以参考的网站:W3Help

参考链接:

[布局概念] 关于CSS-BFC深入理解
再读规范中浮动与定位细节

1. 外边距合并发生情况 
2. 浮动表现与清除


1. CSS包含块
2. BFC
3. 值为百分比计算
4. 定位根据父元素的什么进行放置(padding?)应该是包含块进行放置和计算
5. 祖先元素/父元素
6. 浮动
7. z-index
8. 包含块与父元素的关系:为什么不是所有的包含块都是父元素的内容区域?

盒模型

  1. 边界(edge)

2. 盒(box)

   盒是一个矩形区域
• 内容边界(content edge)或内边界(inner edge)
	○ 内容边界围绕着由盒子的width和height确定的矩形,而这个矩形取决于元素的渲染内容。这四条内容边界定义了盒子的内容盒(content box)。即content这个矩形
• 内边距边界(padding edge)
	○ 内边距边界围绕着盒子的内边距。若内边距的宽度为0,则内边距边界就与内容边界相同。这四条内边距边界定义了盒子的内边距盒(padding box)。即padding+content这个矩形
• 边框边界(border edge)
	○ 边框边界围绕着盒子的边框。若是边框的宽度为0,边框边界就与内边距边界相同。这四条边框边界定义了盒子的边框盒(border box)。即Border+Padding+Content这个矩形
• 外边距边界(margin edge)或外边界(outer edge)
	○ 外边距边界围绕着盒子的外边距。若是外边距的宽度为0,外边距边界就与边框边界相同。这四条外边距边界定义了盒子的外边距盒(margin box)即margin+Border+Padding+Content这个矩形

定位(position)

 static:没有定位,元素出现在正常流中,忽略left、top等或者z-index属性
 relative:相对定位,元素根据其正常位置进行定位。
 absolute:绝对定位,元素根据最近的非static定位的祖先元素进行定位
 fixed:固定定位,元素根据浏览器窗口进行定位
 inhert:规定从父元素继承position属性的值
 sticky:粘性定位元素,

1、包含块

参考: KB008: 包含块( Containing block )

  一个元素的尺寸和位置经常受其包含块(containing block)的影响。

什么是包含块?:

     包含块区域是由祖先元素的内容边界(content edge)或者内边距边界(padding edge)构成的一个矩形区域。
     
 absolute元素的包含块是其祖先元素的padding-box,因此值为百分比根据padding-box的宽高计算。定位根据padding-box的最外边缘进行放置
 
 如果 position 属性为 static 、 relative 或 sticky,包含块可能由它的最近的祖先块元素(比如说inline-block, block 或 list-item元素)的内容区的边缘组成,也可能会建立格式化上下文(比如说 a table container, flex container, grid container, 或者是 the block container 自身)。
 relative元素的包含块是其祖先元素的content-box,同样,计算和定位根据content-box来走。【relative元素根据其原来的位置进行定位:relative元素位置是其父元素的content-box的外边缘(content edge),如果设置了top,left..则在此基础上进行偏移即可】
 
 浮动元素的包含块: 浮动元素的包含块就是离浮动元素最近的块级祖先元素
	浮动元素在浮动的时候,其margin不会超过包含块的padding
	这一点很简单,浮动元素的浮动位置不能超过包含块的内边界【经测试,位置是包含块的conent-box,宽高为百分比时,也是根据包含块的content-box进行计算】
   *absolute的包含块:
          a. 祖先元素为行内元素:
                 包含块就是该元素生成的第一个和最后一个行内盒的padding box形成的(根据8.6)
                 如果祖先元素是行内元素,包含块取决于祖先的direction属性
                 1)direction是ltr(左到右)。包含块的上,左边缘是祖先元素生成的第一个框的上,左内边距边界(padding edge) ;包含块的下,右边是祖先元素最后一个盒子的下,右内边距边界(padding edge)
                  2)direction是rtl(右到左)。包含块的上,右边是祖先元素第一个盒子的上,右内边距边界;包含块的下,左是祖先元素最后一个盒子的下,左内边距边界。
          b. 祖先元素为块级元素:
                 包含块是由它最近的position的值不是static的祖先元素的内边距区的边缘(padding edge)组成。
 position属性为fixed,在连续媒体的情况下,包含块是viewport。在分页媒体的情况下,包含块是分页区域(page area)
 如果 position 属性是 absolute 或 fixed,包含块也可能是由满足以下条件的最近父级元素的内边距区的边缘组成的:
	1. A transform or perspective value other than none
	2. A will-change value of transform or perspective
	3. A filter  value other than none or a will-change value of filter(only works on Firefox).
	4. A contain value of paint (例如: contain: paint;)

总结: 判断包含块的图如下:

2、BFC

  说明:块级格式化上下文,是一个独立的渲染区域,决定了内部的盒模型如何布局,并且和外部不相关。
  产生情况:
      绝对定位
      浮动
      line-block(非块盒的块容器)
      overflow设为visible之外的值
	1. 根元素: 即HTML元素
	2. 浮动元素: 即float的值不为none
	3. 绝对定位元素: Position定位属性为absolute或fixed
	4.  overflow的值为visible之外的值
	5. 行内块元素: display的值为line-block
	6. display的值为flow-root的元素
	7. 表格单元格: display为table-cell(HTML表格单元格默认为该值)
	8. 表格标题:  display为table-caption(HTML表格标题默认为该值)
	9. 匿名表格单元格元素: display为table、table-row、table-row-group、table-header-group、table-footer-group(分别是HTML table、 row、 tbody、 thead、tfoot的默认值)或者inline-table
	10. 弹性元素: display为flex或inline-flex元素的直接子元素
	11. 网格元素: display为grid或inline-grid元素的直接子元素
	12. 多列元素:  column-count或cloumn-width不为auto, 包括column-count为1
	13. column-span为all的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中。
	14. contain的值为layout,content或paint的元素

  特性:从包含块顶部竖直方向排列
       同一个BFC里的兄弟盒子之间的margin合并---可以通过把兄弟之一变成BFC解决合并
       可以阻止margin合并

3、值为百分比计算

margin/padding设百分比时:
     没有定位时,相对于直接父元素进行计算。
     有定位时, 根据定位的父级元素进行计算
 width、padding、margin值为百分比时,根据父元素的width进行计算。
 height根据父元素的height进行计算。

absolute值为百分比时,根据离其最近的有定位属性的祖先元素的(内容宽/高+padding宽/高)来计算的,与border无关   

4、定位

参考:relative 和 absolute 元素的百分比定位

   relative 元素是在包含块(containing block)的 content box 区域执行定位的;
   absolute 元素是相对包含块的 padding box 区域定位的。【包含块设置box-sizing为border-box如何?同样是根据包含块的padding box最外边沿进行定位的。但width和height为百分比时,要刨除包含块的border再进行计算。因为boder-box设置的width=padding*2+border*2+content并且absolute设为百分比是根据包含块的padding+content进行计算的】
    上面描述有些问题,应该是先找到父元素的包含块(父元素的padding-box或contnet-box),再根据包含块进行定位和计算的

6、清除浮动

  浮动定位和清除浮动时只会应用于同一个BFC内的元素。浮动不会影响其它BFC中元素的布局,而清除浮动只能清除同一BFC中在它前面的元素的浮动。外边距折叠(Margin collapsing)也只会发生在属于同一BFC的块级元素之间。

8.6 双向环境(bidirectional context)中行内元素的盒模型

对于每一个行框(line box),UA必须为每个元素生成行内盒(inline box)并按照可视顺序(不是逻辑顺序)呈现外边距,边框和内边距

当元素的'direction'属性为'ltr'时,元素出现的第一个行框最左端生成的盒具有左外边距,左边框和左内边距,并且元素出现的最后一个行框最右端生成的盒具有右内边距,右边框和右外边距

当元素的'direction'属性为'rtl'时,元素出现的第一个行框最右端生成的盒具有右内边距,右边框和右外边距,并且元素出现的最后一个行框最左端生成的盒具有左外边距,左边框和左内边距