内容简介:说起BFC,就必须先了解一下CSS文档流中的定位机制,而且这部分说简单也简单,但却有个坑有可能误导我们,特在本文作出解释。CSS有三种基本定位机制,我想大多数朋友都掌握了,在此简要概述一下(不浪费时间):所以,此时大部分初学者都会结合现实世界感觉到这三种流的立体感就是如下图所示的这样:
说起BFC,就必须先了解一下CSS文档流中的定位机制,而且这部分说简单也简单,但却有个坑有可能误导我们,特在本文作出解释。
一、文档流中的定位机制
1. 三种基本方式
CSS有三种基本定位机制,我想大多数朋友都掌握了,在此简要概述一下(不浪费时间):
- 普通流(或称常规流):CSS默认的定位方式,触发方式包括为position: static/relative,且float:none
- 浮动:浮动脱离普通流,可以左右移动,直到它的外边框边缘碰到包含框或另一个浮动框的边缘,触发方式基本就是float:left/top等。
- 绝对定位:盒子脱离普通流,不影响普通流上其他元素的布局
2. 注意事项
所以,此时大部分初学者都会结合现实世界感觉到这三种流的立体感就是如下图所示的这样:
这里我想说的是,上图这种表达方式不能说是完全正确,虽然层级明确了,但这会给初学者带来错误的理解:浮动元素既然已经玩飘了,且普通流中的div也不会再给它留地方了,那浮动元素对普通应该就彻底没影响了吧? 当然不是! 直接上个小例子看看(多余上色之类的代码去掉了):
<body> <div class='parent'> <div class='child1'> Child1 </div> <div class='child2'> 冷咖啡离开了杯垫 我忍住的情绪在很后面 </div> </div> </body> <style> .parent { width:400px; min-height:100px; } .child1 { width:50px; height:50px; } .child2 { width:100px; height:100px; } </style> 复制代码
效果如下:
好的,那接下来,按照我们的想法,把child1设为浮动,此时它就应该脱离普通流,且普通流中的元素不再考虑它的位置了,child1添加float:left后如下:
咦!child1确实感觉浮动了,child2也确实毫不客气的把child1原本的位置给顶替了,可child2里面的元素是咋回事?为什么像躲摔倒的老太太一样躲避child1了呢?这就是我想提醒朋友们一定要注意的地方。下面看看解释:
float起初被设计出来的初衷其实是为了实现报纸上的那种文字环绕图片的效果,就像我们上例这种普通流中的文字环绕在child1的周围。但之后大家才发现结合float + div 可以实现一定的网页布局,所以,这是浮动的特性。即浮动只是脱离了文档流,即不会按照你的设计而进行布局,就算它在任何位置上那也是和文档流中的其他内容是是平级关系的,我们在使用浮动时,基本上就考虑它的布局定位就行了,不要觉得它彻底飘了,它的影响还在。
好了,这个坑帮不知道的朋友解决了,接下来就好理解BFC了。
二、BFC探索之路
你可能在不知道BFC是啥玩意的前提下却知道解决子div浮动而造成父div塌陷的一个经典的办法就是给父div设置overflow:hidden,但要是面试官问你为啥,你可能就歇菜了,别问我怎么知道,我曾经就是那个菜鸡...,所以,了解了BFC,你就知道为啥了。
1. BFC概念
BFC(Block Formatting Context,块格式上下文)是Web页面的可视化CSS渲染的一部分,并且有自身的一套渲染规则,它决定了其子元素如何定位,以及和其他元素的关系和相互作用。
2. BFC特点
具有BFC特性的元素可以看成是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且BFC具有普通容器所没有的一些特性。
3. 触发BFC的条件
有朋友罗列了好多,记住一些常规的即可:
- 根元素或包含根元素的元素,这里应该就是body元素;
- 浮动元素(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 / inline-table,分别是html table 、row、tbody、thead、tfoot的默认属性);
- 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,即使该元素没有报过在一个多列容器中;
所以,每次看到 overflow:hidden、float:left/right 、position:absolute/fixed ,不用怀疑,一定是BFC
4. BFC的特性
- 内部的box会在垂直方向,从顶部开始一个接一个地放置;
- box垂直方向的距离由margin决定,属于同一个BFC的两个相邻的box的垂直方向的margin会发生叠加;
- 在BFC中,每个盒子的左外边缘(margin-left)会触碰到容器的左边缘(border-left)。对于从右到左的格式来说,则触碰到右边缘,即使是浮动的也是如此,即不会发生margin穿透;
- 形成了BFC的区域不会与float box重叠;
- 计算BFC高度时,子浮动元素也参与计算(BFC会确切包含浮动的子元素,即闭合浮动);
所以,再遇到下面这些问题时,就可以回答了:
- 如何保证一个div元素不被同级的浮动元素覆盖:设置该div元素为BFC;
- 为什么父div设置overflow:hidden就可以在其子div为浮动的情况下依然可以撑开:因为此时父div是个BFC。
5. 实际使用场景
BFC在实际开发布局中基本可以做这两件事:
- 避免由于子元素浮动造成父元素塌陷;
- 避免同一个BFC中的两个块级元素的垂直方向margin重叠(设置其中一个为一个新的BFC,永久隔绝外部影响);
- 自适应两栏布局。
6. BFC实例
直接看看吧
<body> <div class='box'> <div class='left'>左边</div> <div class='right'>右边 <div class='little'>1</div> <div class='little'>2</div> <div class='little'>3</div> </div> </div> </body> <style> .box { background:#888; overflow:hidden; margin-left:50px; } .left { background: #73DE80; /* 绿色 */ width:200px; height:200px; } .right { background: #EF5BE2; /* 粉色 */ width:400px; min-height:100px; } .little { background: #fff; width: 50px; height: 50px; margin: 10px; float:left; } </style> 复制代码
效果如下:
如果突然把div left元素 添加一个float:left:
看到了吧!div right元素的子元素腾地方了,那接下来把div right变成一个BFC,比如使用:overflow:hidden,效果如下:
这样,就满足了BFC内部元素不受外界干扰,且不会与float元素重叠两个特性。
但是这里我有一点不太确认,就是如果我给box right 元素设置了绝对定位,那它是会覆盖box left这个浮动元素的,可这就不符合BFC的特性了,希望大神帮我解答一下:
以上就是我想提醒广大和我一样的初级朋友,欢迎大家批评指正,谢谢您!!!~~~
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 认识绝对定位,相对定位
- 移动端页面头部固定定位的绝对定位实现
- webgl(three.js)实现室内定位,楼宇bim、实时定位三维可视化解决方案——第五课
- IP 地址怎么定位?
- # CSS 绝对定位释义
- 如何定位渲染耗时瓶颈
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。