理解CSS布局和块格式化上下文
在进行html布局及css编写的时候,你是否遇到过这样的问题:
- 子元素设置浮动脱离文档流后,父元素无法将其完全包裹
- 子元素浮动实现两栏布局时,另一个子元素与浮动子元素重叠
- 垂直方向的外边距margin重叠 ...
通常我们使用块级格式化上下文(BFC)就能解决。
什么是BFC?
块格式化上下文(Block Formatting Context,BFC) 是Web页面的可视化CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。
FC(formatting context)直译过来是格式化上下文,它是页面中的一块渲染区域,有一套渲染规则,决定了其子元素如何布局,以及和其他元素之间的关系和作用。
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,并且容器元素不会影响兄弟元素的布局。
什么情况下会创建BFC
- 根元素或包含根元素的元素
- 浮动元素(元素的 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 值不为 visible 的块元素
- display 值为 flow-root 的元素(新方式,文末会提及)
- contain 值为 layout、content或 strict 的元素
- 弹性元素(display为 flex 或 inline-flex元素的直接子元素)
- 网格元素(display为 grid 或 inline-grid 元素的直接子元素)
- 多列容器(元素的 column-count 或 column-width 不为 auto,包括 column-count 为 1) column-span 为 all 的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中。
常见应用场景
使父元素包含浮动元素
下面例子解释如何让浮动内容和父元素等高,清楚浮动负面影响
html
<div class="outer">
<div class="float">I am a floated element.</div>
I am text inside the outer box.
</div>
css
.outer {
border: 5px dotted rgb(214,129,137);
border-radius: 5px;
width: 450px;
padding: 10px;
margin-bottom: 40px;
}
.float {
padding: 10px;
border: 5px solid rgba(214,129,137,.4);
border-radius: 5px;
background-color: rgba(233,78,119,.4);
color: #fff;
float: left;
width: 200px;
margin: 0 20px 0 0;
}
通过给左侧文字设置向左浮动实现文字环绕效果是很常见的做法,当文本足够长时,会看到如下效果,父元素可以完全包裹子元素。
但事实上,float中的文字已经脱离文档,如果文档流文字过少,浮动元素就会溢出父元素边缘。
这时候为父元素设置overflow: auto
或者除invisible
默认值之外的任何有效值都能创建BFC解决这个问题,使父元素包含浮动元素
.outer {
overflow: auto;
}
BFC防止垂直外边距重叠
外边距折叠的规则是:当两个块级元素相邻并且在同一个块级格式化上下文时,它们垂直方向上的外边距会产生重叠
html
<div class="outer">
<p>I am paragraph one and I have a margin top and bottom of 20px</p>
<p>I am paragraph two and I have a margin top and bottom of 20px</p>
</div>
css
.outer {
background-color: #ccc;
margin: 0 0 40px 0;
}
p {
padding: 0;
margin: 20px 0 20px 0;
background-color: rgb(233,78,119);
color: #fff;
}
由于p元素的边缘和外部div上的边距之间没有内容,因此两者将会合并,因此段落最终与框的顶部和底部齐平。我们在段落的上方和下方看不到任何灰色。如下图:
当父元素设置了BFC之后,父元素与子元素p重叠区域将不再合并
.outer {
background-color: #ccc;
margin: 0 0 40px 0;
overflow: auto;
}
BFC防止文本环绕
依然像上面例子文字环绕效果的布局和样式
html
<div class="outer">
<div class="float">I am a floated element.</div>
<div class="text">I am text...</div>
</div>
css
.float{
float: left;
}
这时候如果不想要右侧文字环绕浮动文字盒子,在左侧div设置浮动的情况下,我可以通过使右边div成为BFC,使两个兄弟div互相隔离、互不影响,从而达到去除文字环绕的效果。
.text {
overflow: auto;
}
创建BFC的新方式
创建BFC的许多方法通常会带来一些副作用,目前为止似乎最安全的就是overflow
属性,但某些情况下我们不需要滚动条,此时滚动条就变成了这种方式的副作用,因此display
有个新的属性flow-root
可以在任何需要创建BFC场景下使用,它并且不会带来任何副作用。
flow-root
浏览器兼容情况:
浏览器对此值的支持是有限的,如果要在不支持flex或网格布局浏览器创建回退,了解BFC阻止浮动元素的负面影响十分必要。
PS:更多前端资讯、技术干货,请关注公众号「前端新视界」
- HTML 教程
- HTML 简介
- html div 标签介绍
- html span 标签介绍
- html a 超链接标签
- HTML Br换行标签介绍
- HTML P段落标签介绍
- HTML br与p标签区别
- Html H 标题标签
- html px em pt长度单位
- HTML form 标签
- HTML radio 单选框
- HTML B 加粗标签
- HTML strong加粗粗体标签
- HTML em 强调标签
- HTML i 斜体标签
- HTML u下划线标签
- HTML s 删除线标签
- Html img 图片标签
- Html上标注sup与下标注sub标签
- HTML nobr 禁止换行标签
- HTML hr 水平线标签
- HTML label 标签
- HTML input 标签
- HTML textarea 标签
- HTML select下拉列表标签
- HTML checkbox 多选框
- HTML font color 标签
- HTML iframe 框架标签
- HTML Table 表格
- HTML dl dt dd 标签
- HTML ol li有序列表标签
- HTML ul li 无序列表标签
- HTML 注释
- CSS 教程
- CSS 简介
- CSS 语法
- CSS Id 和 Class选择器
- CSS 样式的创建
- CSS background 背景介绍
- CSS 文本样式
- CSS font 字体
- CSS A 链接
- CSS ul ol列表样式
- CSS TABLE 样式
- CSS 框模型
- CSS border 边框
- CSS Outlines 轮廓
- CSS 外边距 Margin
- CSS Padding 内边距
- CSS 分组和嵌套选择器
- CSS 尺寸 (Dimension)
- CSS Display 属性
- CSS Position 定位
- CSS Float 浮动
- CSS 水平对齐(Horizontal Align)
- CSS 组合选择符
- CSS 伪类
- CSS 伪元素
- CSS 导航栏
- CSS 下拉菜单
- CSS 图片廊
- CSS 图像透明/不透明
- CSS sprite 图像拼合技术
- CSS 媒体类型
- CSS 属性选择器
- CSS 实例
- 表白利器,马赛克拼贴照片制作
- 【014期】JavaSE面试题(十四):基本IO流
- 微信小程序开发实战(24):选择图像
- 反 996 有理:催程序员交代码,写不出好软件
- 一千个不用 Null 的理由!
- WebAssembly 是 Deno 的好搭档
- Chrome开发者工具的11个高级使用技巧
- 怒爬某破Hub站资源,简单4步撸个鉴黄平台!
- 审阅“史上”最烂的代码
- BeanUtils 是用 Spring 的还是 Apache 的好?
- 一看就会的mysql索引优化(真实案例)
- 【015期】JavaSE面试题(十五):网络IO流
- 算法篇:二分查找基础篇
- 算法篇:双指针之接雨水
- 因用了Insert into select语句,美女同事被开除了!