高度坍塌问题--BFC模式解析

2024-09-01 02:58

本文主要是介绍高度坍塌问题--BFC模式解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  问题引起是2016IFE春季问题的任务三,总的父元素parent包含三个浮动的子元素,容器的高度不能自动伸长以适应内容的高度,出现了高度坍塌问题。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>高度坍塌问题-BFC模式解析</title><style>.parent{margin:20px;background-color: red;border: 2px solid black;}.left,.center,.right{float: left;width: 200px;height: 200px;background-color: yellow;border: 2px solid blue;}</style>
</head>
<body><div class="parent"><div class="left">left</div><div class="center">center</div><div class="right">right</div></div>
</body>
</html>        

这里写图片描述
(最上面的一条黑线就是parent元素了,可以看到它的高度为0)

   原因就是浮动使子元素脱离文档流,父元素无法感知子元素的存在,而且父元素内部不存在其他处于文档流中的元素,也就表现为高度为0。

既然是由浮动引起的,就用clear属性清除浮动吧,其实这是错误的,clear属性规定的是元素哪一侧不允许有其他浮动元素,但是我们并不是想让父元素周围没有其他浮动元素,而是减少浮动带来的影响,也就是使浮动元素闭合

先来看看闭合浮动的方法:

 1)添加额外标签

通过在浮动元素末尾添加一个空的标签,例如 <div style=”clear:both”></div>,其他标签br等亦可。

<div class="wrap" id="float1"><h2>1)添加额外标签</h2><div class="main left">.main{float:left;}</div><div class="side left">.side{float:right;}</div><div style="clear:both;"></div>
</div>
<div class="footer">.footer</div>

优点:通俗易懂,容易掌握。
缺点:可以想象通过此方法,会添加多少无意义的空标签,有违结构与表现的分离,在后期维护中将是噩梦,这是坚决不能忍受的,所以你看了这篇文章之后还是建议不要用了吧。

2)使用 br标签和其自身的 html属性

这个方法有些小众,br 有 clear=“all | left | right | none” 属性

<div class="wrap" id="float2"><h2>2)使用 br标签和其自身的 html属性</h2><div class="main left">.main{float:left;}</div><div class="side left">.side{float:right;}</div><br clear="all" />
</div>
<div class="footer">.footer</div>

优点:比空标签方式语义稍强,代码量较少
缺点:同样有违 结构与表现的分离,不推荐使用

3)父元素设置 overflow:hidden      

通过设置父元素overflow值设置为hidden;在IE6中还需要触发 hasLayout ,例如 zoom:1;

<div class="wrap" id="float3" style="overflow:hidden; *zoom:1;"><h2>3)父元素设置 overflow </h2><div class="main left">.main{float:left;}</div><div class="side left">.side{float:right;}</div>
</div>
<div class="footer">.footer</div>

优点:不存在结构和语义化问题,代码量极少
缺点:内容增多时候容易造成不会自动换行导致内容被隐藏掉,无法显示需要溢出的元素;04年POPO就发现overflow:hidden会导致中键失效,这是我作为一个多标签浏览控所不能接受的。所以还是不要使用了

4)父元素设置 overflow:auto 属性

同样IE6需要触发hasLayout,演示和3差不多

优点:不存在结构和语义化问题,代码量极少
缺点:多个嵌套后,firefox某些情况会造成内容全选;IE中 mouseover 造成宽度改变时会出现最外层模块有滚动条等,firefox早期版本会无故产生focus等, 请看 嗷嗷的 Demo ,不要使用

5)父元素也设置浮动

优点:不存在结构和语义化问题,代码量极少
缺点:使得与父元素相邻的元素的布局会受到影响,不可能一直浮动到body,不推荐使用

6)父元素设置display:table
    

优点:结构语义化完全正确,代码量极少
缺点:盒模型属性已经改变,由此造成的一系列问题,得不偿失,不推荐使用

7)使用:after 伪元素

需要注意的是
:after是伪元素(Pseudo-Element),不是伪类(某些CSS手册里面称之为“伪对象”),很多闭合浮动大全之类的文章都称之为伪类,不过csser要严谨一点,这是一种态度。

由于IE6-7不支持:after,使用 zoom:1触发 hasLayout

 .clearfix:after {content:"."; /*生成内容作为最后一个元素,至于content里面是点还是其他都是可以的 */       display:block;         
使生成的元素以块级元素显示,占满剩余空间;height:0;               
避免生成内容破坏原有布局的高度。visibility:hidden;      使生成的内容不可见,并允许可能被生成内容盖住的内容可以进行点击和交互;clear:both;  闭合浮动,
}.clearfix{zoom:1; /* 兼容ie6,触发IE hasLayout */}<div class="father clearfix"><div class="son"></div></div><div class="next"></div>

8)使用 :before和 :after 双伪元素

.clearfix:before,.clearfix:after{display: table;content: "";
}
.clearfix:after {clear: both;
}
.clearfix {zoom: 1;
}

小结

通过对比,我们不难发现,其实以上列举的方法,无非有两类:

其一,通过在浮动元素的末尾添加一个空元素,设置 clear:both属性,after伪元素其实也是通过 content 在元素的后面生成了内容为一个点的块级元素;

其二,通过设置父元素 overflow 或者display:table 属性来闭合浮动,我们来探讨一下这里面的原理。

原理

原理就是 Block formatting contexts(块级格式化上下文,BFC),是css2.1规范定义的,是页面css视觉渲染的一部分,用于决定盒子的布局及浮动相互影响范围的一个区域。简单来说,BFC就是一种属性,会影响着元素的定位以及与其兄弟元素之间的相互作用

下面的情况会产生新的BFC:

  1. 根元素或其他包含它的元素
  2. 浮动(元素的float不为none)
  3. 绝对定位元素(position为absolute或者fixed)
  4. 行内块(display:inline-block)
  5. 表格单元格(display:table-cell,html表格单元格默认属性)
  6. 表格标题(display:table-caption,html表格标题默认属性)
  7. overflow的值不为visible的元素
  8. 弹性盒flex boxes(display:flex或者inline-flex)

其中,最常见的就是overflow:hidden、float:left/right、position:absolute。也就是说,每次看到这些属性的时候,就代表了该元素已经创建了一个BFC了。

    需要注意的是,display:table 本身并不会创建BFC,但是它会产生匿名框(anonymous boxes , 没有名字不能被选择器选中的盒,它们的所有属性都为inherit或初始默认值;),而匿名框中的display:table-cell可以创建新的BFC,换句话说,触发块级格式化上下文的是匿名框,而不是display:table。所以通过display:table和display:table-cell创建的BFC效果是不一样的。(目前没有懂????)
 

BFC的 特性

  1. 内部的盒会在垂直方向一个接一个排列(可以看作BFC中有一个的常规流);
  2. 处于同一个BFC中的元素相互影响,可能会发生外边距叠加,如果这两个相邻的块框不属于同一个块级格式化上下文,那么它们的外边距就不会叠加。;
  3. 每个元素的margin box的左边,与容器块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此;
  4. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然;
  5. 计算BFC的高度时,考虑BFC所包含的所有元素,连浮动元素也参与计算;
  6. 浮动盒区域不叠加到BFC上;

    BFC包含创建该上下文元素的所有子元素,但不包括创建了新BFC的子元素的内部元素,也就是一个元素不能同时存在于两个BFC中。

    通俗地来说:创建了 BFC的元素就是一个独立的盒子,里面的子元素不会在布局上影响外面的元素,反之亦然,同时BFC仍然属于文档中的普通流。

从实际代码来分析BFC
实例解析BFC

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>高度坍塌问题-BFC模式解析</title><style>* {margin: 0;padding: 0;}.box{background:#888;  /* 灰色 */height: 100%;margin-left: 50px;}.left{background: #73DE80;    /* 绿色 */opacity: 0.5;border: 3px solid #F31264;width: 200px;height: 200px;float: left;}.right{                     /* 粉色 */background: #EF5BE2;opacity: 0.5;border: 3px solid #F31264;width:400px;min-height: 100px;}</style>
</head>
<body><div class='box'><div class='left'></div><div class='right'></div></div>
</body>
</html> 

这里写图片描述

绿色框(’#left’)向左浮动,它创建了一个新BFC,但暂时不讨论它所创建的BFC。由于绿色框浮动了,它脱离了原本normal flow的位置,因此,粉色框(’#right’)就被定位到灰色父元素的左上角(特性3:元素左边与容器左边相接触),与浮动绿色框发生了重叠。

  同时,由于灰色框(’#box’)并没有创建BFC,因此在计算高度的时候,并没有考虑绿色框的区域,发生了高度坍塌,这也是常见问题之一。
 实例二:
 
现在通过设置overflow:hidden来创建BFC闭合浮动,再看看效果如何。

.BFC{overflow: hidden;
}
<div class='box BFC'><div class='left'> </div><div class='right'> </div>
</div>

这里写图片描述
灰色框创建了一个新的BFC后,高度发生了变化,计算高度时它将绿色框区域也考虑进去了(特性5:计算BFC的高度时,浮动元素也参与计算);

而绿色框和红色框的显示效果仍然没有任何变化。
实例三
现在,现将一些小块添加到粉色框中,看看效果:

<style>.little{background: #fff;width: 50px;height: 50px;margin: 10px;float: left;}
</style><div class='box BFC'><div class='left'> </div><div class='right'><div class='little'></div><div class='little'></div><div class='little'></div></div>
</div>

这里写图片描述
由于粉色框没有创建新的BFC,因此粉色框中白色块受到了绿色框的影响,被挤到了右边去了(特性6:浮动盒区域不叠加到BFC上)。先不管这个,看看白色块的margin,发生了外边距叠加。

实例四:
利用同实例二中一样的方法,为粉色框创建BFC,防止与浮动元素(绿色框)重叠:

<div class='box BFC'><div class='left'> </div><div class='right BFC'><div class='little'></div><div class='little'></div><div class='little'></div></div>
</div>

这里写图片描述
 一旦粉色框创建了新的BFC以后,粉色框就不与绿色浮动框发生重叠了,同时内部的白色块处于隔离的空间(特性4:BFC就是页面上的一个隔离的独立容器),白色块也不会受到绿色浮动框的挤压。

实例总结

  以上就是BFC的分析,BFC的概念比较抽象,但通过实例分析应该能够更好地理解BFC。在实际中,利用BFC可以闭合浮动(实例二),防止与浮动元素重叠(实例四)。同时,由于BFC的隔离作用,可以利用BFC包含一个元素,防止这个元素与BFC外的元素发生margin collapse。
  

那么到底为什么坍塌?

  float 脱离了普通流,并且创建了新的BFC,而父元素不具备产生 BFC 的条件,所以它的高度为0。

如何解决?

  通过了解BFC的特性我们知道,BFC会把它包含的浮动元素高度也算在里面,也就是闭合浮动
  拿 overflow: auto 举例:overflow: auto 并不会闭合浮动,而是 overflow: auto 会创建一个新的BFC,避免浮动的元素侵入其他元素。

  IE6-7有一个特有的属性就是haslayout,当一个元素的hasLayout属性值为true时,我们说这个元素有一个布局(layout),它负责对自己和可能的后代元素进行尺寸计算和定位,当属性值为false时,它的尺寸和位置由最近拥有布局的祖先元素控制。

  很多情况下,把 hasLayout的状态改成true 可以解决很大部分ie下显示的bughasLayout属性不能直接设定,通过设定一些特定的css属性来触发并改变 hasLayout 状态

  元素hasLayout而导致的问题其实一般都很容易发现:往往是内容出现错位甚至完全不可见。 如:当一个元素内含浮动或绝对定位的内容时,它通常会表现出奇怪和错误的行为。

  一般如果是因为layout而引起的显示不符期望效果的话,在ff下会表现正常,而在ie下会出现错误。这个时候可以尝试触发父容器及其中的子容器的haslayout属性,通常可以通过加上zoom: 1;来调试。直到找到了产生问题的元素,再进行针对性的修正。最好的办法是对这个元素设置尺寸属性。但是,有时不便指定尺寸属性的情况下,就只能寻找替代方案了。
  对于ie7 ,最好的办法是设置最小高度属性为0;这个技术是无害的,因为0本来就是这个属性的初始值。而且没有必要对其他浏览器隐藏这个属性。
  而对于ie6和更早版本中触发一个元素hasLayout的方法是在overflow属性是visible的情况下设置这个元素的高度属性为1%,然后对其他浏览器隐藏这个设置。这种技术就是著名的Holly hack。

触发hasLayout的条件:

  1. position: absolute
  2. float: left|right
  3. display: inline-block
  4. width: 除 “auto” 外的任意值
  5. height: 除 “auto” 外的任意值 (例如很多人闭合浮动会用到 height: 1% )
  6. zoom: 除 “normal” 外的任意值
  7. writing-mode: tb-rl
    在 IE7 中,一些额外的属性也可以触发该属性:

  8. min-height: (任何值)

  9. max-height: (任何值除了none)
  10. min-width: (任何值)
  11. max-width: (任何值除了none)
  12. overflow: hidden|scroll|auto ( 这个属性在IE之前版本中没有触发 layout 的功能。 )
  13. overflow-x|-y: hidden|scroll|auto (CSS3 盒模型中的属性,尚未得到浏览器的广泛支持。他们在之前IE版本中同样没有触发 layout 的功能)

综上所述:

在支持BFC的浏览器(IE8+,firefox,chrome,safari)通过创建新的BFC闭合浮动;

在不支持 BFC的浏览器 (IE6-7),通过触发 hasLayout 闭合浮动。

这篇关于高度坍塌问题--BFC模式解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1125746

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

好题——hdu2522(小数问题:求1/n的第一个循环节)

好喜欢这题,第一次做小数问题,一开始真心没思路,然后参考了网上的一些资料。 知识点***********************************无限不循环小数即无理数,不能写作两整数之比*****************************(一开始没想到,小学没学好) 此题1/n肯定是一个有限循环小数,了解这些后就能做此题了。 按照除法的机制,用一个函数表示出来就可以了,代码如下

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

购买磨轮平衡机时应该注意什么问题和技巧

在购买磨轮平衡机时,您应该注意以下几个关键点: 平衡精度 平衡精度是衡量平衡机性能的核心指标,直接影响到不平衡量的检测与校准的准确性,从而决定磨轮的振动和噪声水平。高精度的平衡机能显著减少振动和噪声,提高磨削加工的精度。 转速范围 宽广的转速范围意味着平衡机能够处理更多种类的磨轮,适应不同的工作条件和规格要求。 振动监测能力 振动监测能力是评估平衡机性能的重要因素。通过传感器实时监

缓存雪崩问题

缓存雪崩是缓存中大量key失效后当高并发到来时导致大量请求到数据库,瞬间耗尽数据库资源,导致数据库无法使用。 解决方案: 1、使用锁进行控制 2、对同一类型信息的key设置不同的过期时间 3、缓存预热 1. 什么是缓存雪崩 缓存雪崩是指在短时间内,大量缓存数据同时失效,导致所有请求直接涌向数据库,瞬间增加数据库的负载压力,可能导致数据库性能下降甚至崩溃。这种情况往往发生在缓存中大量 k

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

【VUE】跨域问题的概念,以及解决方法。

目录 1.跨域概念 2.解决方法 2.1 配置网络请求代理 2.2 使用@CrossOrigin 注解 2.3 通过配置文件实现跨域 2.4 添加 CorsWebFilter 来解决跨域问题 1.跨域概念 跨域问题是由于浏览器实施了同源策略,该策略要求请求的域名、协议和端口必须与提供资源的服务相同。如果不相同,则需要服务器显式地允许这种跨域请求。一般在springbo

OWASP十大安全漏洞解析

OWASP(开放式Web应用程序安全项目)发布的“十大安全漏洞”列表是Web应用程序安全领域的权威指南,它总结了Web应用程序中最常见、最危险的安全隐患。以下是对OWASP十大安全漏洞的详细解析: 1. 注入漏洞(Injection) 描述:攻击者通过在应用程序的输入数据中插入恶意代码,从而控制应用程序的行为。常见的注入类型包括SQL注入、OS命令注入、LDAP注入等。 影响:可能导致数据泄