CSS基础——盒模型那些事儿
1.基础盒模型
对文档进行布局的时候,浏览器的渲染引擎会根据CSS基础盒模型,将所有元素表示成一个个矩形的盒子,CSS决定的是这些盒子的大小,颜色以及其他属性。
盒子模型包括内容(content),内边距(padding),边框(border)以及外边距(margin)四个区域构成,一般而言,元素被放置在内容区域内,有个属性box-sizing
用来定义如何计算一个元素的总宽度和总高度。默认情况下,box-sizing:content-box
对元素设置宽高(width, min-width,max-width,height,min-height,max-height)只会应用到内容区域内,当设置box-sizing:border-box
时,元素设置宽高还包括border和padding。
margin
,border
和padding
都分为上下左右四个部分,分别通过设置margin/border/padding-left/right/top/bottom
进行设置,为了简化设置,可以直接通过配置margin/border/padding
快速生成,配置顺序为上右下左(顺时针):
.demo {
padding: 20px; // 上下左右都是20px
margin:20px 10px; // 上下20px,左右10px
border: 20px 10px 0; // 上20px,左右10px,下0px(0px时px需要直接忽略)
}
2.常见的盒模型场景
2.1 外边距重叠(外边距塌陷)
块的上外边距和下外边距有时合并(折叠)为单个边距,其大小为单个边距的最大值(或如果它们相等,则仅为其中一个),这种行为称为边距折叠,有三种情况会发生外边距重叠行为。
设定float和position=absolute的元素以及display=inline-block不会产生外边距折叠行为。在这里要跟BFC区别一下,这三种情况都会触发BFC,但不代表BFC就一定会阻止外边距重叠(overflow=hidden并不能阻止折叠)
-
同一层的相邻元素之间
<style> .p1 { width: 200px; height: 200px; margin-bottom: 20px; background-color: hotpink; } .p2 { /* position: absolute; */ /* display: inline-block; */ /* float: left; */ width: 200px; height: 200px; margin-top:20px; background-color: hotpink; } /* .p2::after{ clear: left; } */ </style> <p class="p1"> 哈哈哈 </p> <p class="p2"> 哈哈哈 </p> </body>
按照上图的代码,看上去会以为p1和p2之间相隔40px,但实际上它们之间只相隔20px,解决方法是对后一个元素添加注释中任意一行(添加float之后记得要clear一下),如果想在第一个元素上进行设置,只能设置display=inline-block;
-
没有内容将父元素和后代元素分开
<body> <style> .box-demo { margin: 20px; background: pink; } .p1 { margin-top: 30px; width: 200px; height: 200px; margin-bottom: 20px; background-color: hotpink; } .p2 { /* display: inline-block; */ width: 200px; height: 200px; margin-top:20px; margin-bottom: 30px; background-color: hotpink; } </style> <div class="box-demo"> <p class="p1"> 哈哈哈 </p> <p class="p2"> 哈哈哈 </p> </div> </body>
如上图,看上去会以为p1与body之间上外边距会相差50px,p2的下半边距是50px,实际上只按照最大的margin值显示,p1与body之间的上边距为30px,p2的下边距为30px。这种情况下解决办法和第一种情况类似,但是要注意兄弟元素之间的相对位置
-
空的块级元素
当一个块元素上边界margin-top直接贴到元素下边界margin-bottom时也会发生边界折叠
2.2 BFC(Block Formatting Context)
块格式化上下文是Web页面的可视CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。实际上可以把它看成一个独立的盒子,在这个盒子里面怎么玩,都跟盒子外面的世界没有任何关系。创建BFC的方法
- 根元素(
<html>)
- 浮动元素(元素的
float
不是none
) - 绝对定位元素(元素的
position
为absolute
或fixed
) - 行内块元素(元素的
display
为inline-block
) - 表格单元格(元素的
display
为table-cell
,HTML表格单元格默认为该值) - 表格标题(元素的
display
为table-caption
,HTML表格标题默认为该值) - 匿名表格单元格元素(元素的
display
为table、``table-row
、table-row-group、``table-header-group、``table-footer-group
(分别是HTML table、row、tbody、thead、tfoot 的默认属性)或inline-table
) overflow
计算值(Computed)不为visible
的块元素display
值为flow-root
的元素contain
值为layout
、content
或 paint 的元素- 弹性元素(
display
为flex
或inline-flex
元素的直接子元素) - 网格元素(
display
为grid
或inline-grid
元素的直接子元素) - 多列容器(元素的
column-count
或column-width
(en-US) 不为auto,包括 ``column-count
为1
) column-span
为all
的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中
内部的盒子会在垂直方向,一个接一个地放置;
盒子垂直方向的距离由 margin 决定,属于同一个 BFC 的两个相邻盒子的 margin 会发生重叠;
每个元素的 margin 的左边,与包含块 border 的左边相接触(对于从左往右的格式化,否则相反),即使存在浮动也是如此;
BFC 的区域不会与 float 盒子重叠;
BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
计算 BFC 的高度时,浮动元素也参与计算。
浮动定位和清除浮动时只会应用于同一个BFC内的元素。浮动不会影响其它BFC中元素的布局,而清除浮动只能清除同一BFC中在它前面的元素的浮动。