盒子模型,外边距合并,BFC
前言
保持写作但是想不到写什么…那就盒子模型吧。其实文章有些东西我都没试过,因为我身边没有 Windows 机器,更别说 IE6 这种古董了,我只记得,用上 Chrome 的时候上网冲浪更流畅了一点~
标准盒子模型
其实就是width = content width
,整个元素的宽度是content width + 2padding + 2border + 2margin
,其中的 2 是上下两边或者左右两边的意思,而你设置的宽高,仅仅代表内容的宽高。
怪异盒模型
既然写了标准两个字,那就肯定也有不标准的,就是那个搞事情的 IE,IE 的width
并不是contetnt width
,而是width + 2padding + 2border
,仅仅只有margin
不属于,如果空间不够,就往里面压缩。
box-sizing
这个属性有两个值,默认是content-box
,就是标准的,第二个值是border-box
,就能做到怪异盒的效果,有些情况还是能用上,这样看来喊怪异盒真的太冤枉了…
margin 合并
可以看下这个 🌰,设置明明两个都是margin
,但是中间区域看上都不像有 200px,这就是margin
合并,这还不止一种情况,还有两种:
这里的
foo.marginTop
和bar.marginTop
合并了
这里的 bar 完全不见了,而且也发生第一种的情况
MDN 这边详细写了三种情况在什么时候会发生和注意事项:
- 相邻元素之间
- 毗邻的两个元素之间的外边距会折叠(除非后一个元素需要清除之前的浮动)。
- 父元素与其第一个或最后一个子元素之间
- 如果在父元素与其第一个子元素之间不存在边框、内边距、行内内容,也没有创建块格式化上下文、或者清除浮动将两者的 margin-top 分开;或者在父元素与其最后一个子元素之间不存在边框、内边距、行内内容、height、min-height、max-height 将两者的 margin-bottom 分开,那么这两对外边距之间会产生折叠。此时子元素的外边距会“溢出”到父元素的外面。
- 空的块级元素
- 如果一个块级元素中不包含任何内容,并且在其 margin-top 与 margin-bottom 之间没有边框、内边距、行内内容、height、min-height 将两者分开,则该元素的上下外边距会折叠。
- 一些需要注意的地方:
- 上述情况的组合会产生更复杂的外边距折叠。
- 即使某一外边距为 0,这些规则仍然适用。因此就算父元素的外边距是 0,第一个或最后一个子元素的外边距仍然会“溢出”到父元素的外面。
- 如果参与折叠的外边距中包含负值,折叠后的外边距的值为最大的正边距与最小的负边距(即绝对值最大的负边距)的和。
- 如果所有参与折叠的外边距都为负,折叠后的外边距的值为最小的负边距的值。这一规则适用于相邻元素和嵌套元素。
解决办法其实也很简单,全部给他加一个 1 像素paddingTop
或者borderTop
就可以了,但是也有其他办法
BFC
块格式化上下文(Block Formatting Context,BFC)可以解决这个问题,但是他是啥?他算是一个独立的空间,正如他中文一样,独立块格式化上下文,被他包裹的都不会出现margin
合并,浮动没有包裹等问题,举个例子。
两个之间
margin
正常了,然后第二个浮动也包裹住了
这里展示了浮动和margin
合并的示例,均可靠 BFC 解决,触发 BFC 的情况比较多:
body
根元素float
除none
以外的值position
(absolute
、fixed
)display
为inline-block
、table-cell
、table-caption
、table
、table-row
、table-row-group
、table-header-group
、table-footer-group
、flex
或inline-flex
元素的直接子元素、grid
或inline-grid
元素的直接子元素、flow-root
overflow
除了visible
以外的值 (hidden
、auto
、scroll
)- 多列容器(元素的
column-count
或column-width
不为auto
,包括column-count
为 1) column-span
为all
的元素始终会创建一个新的 BFC,即使该元素没有包裹在一个多列容器中