Maison >interface Web >tutoriel CSS >Pourquoi CSS doit-il effacer float ? Quel est le principe du dégagement des flotteurs ?
CSS float , une propriété que nous aimons et détestons à la fois. J'adore, car grâce au flottement, nous pouvons mettre en page la mise en page très facilement ; je déteste ça, il reste trop de problèmes après le flottement qui doivent être résolus, en particulier IE6-7 et versions antérieures sans instructions spéciales, reportez-vous au navigateur IE de la plate-forme Windows.
Float, une propriété que nous aimons et détestons à la fois. J'adore, car grâce au flottement, nous pouvons mettre en page la mise en page très facilement ; je déteste ça, il reste trop de problèmes après le flottement qui doivent être résolus, en particulier IE6-7 (ce qui suit fait référence au navigateur IE de la plate-forme Windows, sauf indication contraire). spécifié). Peut-être que beaucoup de gens se posent cette question : d'où vient le flottement ? Pourquoi CSS efface-t-il les flottants ? Quel est le principe du dégagement des flotteurs ? Cet article analysera les secrets en profondeur, étape par étape, rendant le flottement plus pratique à utiliser.
1. Flotteur de compensation ou flotteur de fermeture (Flotteur enfermant ou Flotteur de compensation) ?
Beaucoup de gens ont l'habitude de l'appeler des flotteurs de compensation. Je l'ai toujours appelé ainsi auparavant, mais ce n'est pas exact. Nous devons traiter le code avec une attitude rigoureuse, ce qui peut également nous aider à mieux comprendre les trois questions du début.
1) Clear float : Le mot correspondant pour clear est clear, et l'attribut correspondant en CSS est clear : left | right two | Élément, réduisant ainsi l'impact du flottement.
Veuillez consulter l'élégante démo pour connaître la différence entre les deux.
Grâce aux exemples ci-dessus, nous avons constaté que l'effet que nous souhaitons obtenir est plus précisément de fermer le flotteur, plutôt que de simplement le dégager. le pied de page : les deux sont clairs. Flottant ne résout pas le problème de l'effondrement de la hauteur de chaîne.
Conclusion : L'utilisation d'un flotteur fermé est plus rigoureuse que la suppression d'un flotteur, nous l'appellerons donc un flotteur fermé dans l'article suivant.
2. Pourquoi devons-nous nettoyer les flotteurs ? Pour répondre à cette question, il faut d'abord parler du mécanisme de positionnement en CSS : flux ordinaire, flottant, positionnement absolu (où "position:fixed" est une sous-classe de "position:absolute").
1) Flux ordinaire : de nombreuses personnes ou articles l'appellent flux de documents ou flux de documents ordinaire. En fait, ce mot n'existe pas du tout dans la norme. Si la traduction littérale du flux de documents en anglais est flux de documents, il n'y a qu'un autre mot dans la norme, appelé flux normal, ou flux normal. Mais il semble que tout le monde soit plus habitué au nom de flux de documents, car c'est de là que proviennent de nombreux livres traduits en chinois. Par exemple, dans "CSS Mastery", le livre anglais original n'a que le terme "flux normal" du début à la fin, et le flux de documents n'est jamais apparu
2) Flottant : les boîtes flottantes peuvent être déplacées vers la gauche ou la droite jusqu'à ce qu'elles soient. le bord extérieur rencontre le bord de la boîte conteneur ou d’une autre boîte flottante. Les boîtes flottantes n'appartiennent pas au flux ordinaire dans le document. Lorsqu'un élément flotte, cela n'affectera pas la disposition de la boîte au niveau du bloc, mais affectera uniquement la disposition des boîtes en ligne (généralement du texte). Le document se comportera comme Tout comme la boîte flottante n'existe pas, lorsque la hauteur de la boîte flottante dépasse la boîte contenante, la boîte contenante ne s'étirera pas automatiquement pour fermer l'élément flottant (phénomène d'effondrement de la hauteur). Comme son nom l’indique, il flotte sur des courants ordinaires, comme des nuages flottants, mais ne peut flotter qu’à gauche et à droite.
C'est précisément à cause de cette caractéristique de flottement qu'une fois que les éléments du flux ordinaire ont flotté, puisqu'il n'y a pas d'autres éléments de flux ordinaires à l'intérieur de la boîte contenante, la hauteur sera de 0 (effondrement de la hauteur). Dans la mise en page réelle, ce n'est souvent pas ce que nous voulons, nous devons donc fermer l'élément flottant pour que sa boîte contenant affiche une hauteur normale.
Je ne dirai pas grand chose sur le positionnement absolu, cela n’entre pas dans le cadre de cet article et sera détaillé la prochaine fois.
3. Le principe de la suppression des flotteurs - comprendre les contextes de formatage hasLayout et Block Regardez d'abord les différentes méthodes de suppression des flotteurs : (
Le clearfix CSS le plus complet pour effacer les flotteurs)1) Ajouter des balises supplémentaires
C'est une méthode que le professeur nous a expliquée à l'école, en ajoutant une balise vide à la fin de l'élément flottant comme 07df87df7feccfdff6aece562bfacd7694b3e26ee717c64999d7867364b1b4a3, d'autres balises telles que br sont également acceptables.
<p class="warp" id="float1"> <h2>1)添加额外标签</h2> <p class="main left">.main{float:left;}</p> <p class="side left">.side{float:right;}</p> <p style="clear:both;"></p> </p> <p class="footer">.footer</p>Avantages : Facile à comprendre et facile à maîtriser
Inconvénients : Vous pouvez imaginer combien de balises vides sans signification seront ajoutées grâce à cette méthode, ce qui viole la structure et la séparation des performances sera un cauchemar lors d'une maintenance ultérieure, ce qui est absolument intolérable, donc après avoir lu cet article, il est recommandé de ne pas l'utiliser.
2) Utilisez la balise br et son propre attribut html
Cette méthode est quelque peu niche, br a l'attribut clear="all | left | right | none"
<p class="warp" id="float2"> <h2>2)使用 br标签和其自身的 html属性</h2> <p class="main left">.main{float:left;}</p> <p class="side left">.side{float:right;}</p> <br clear="all" /> </p> <p class="footer">.footer</p>
Démo élégante
Avantages : sémantique légèrement plus forte que la méthode des balises vides, moins de volume de code
Inconvénients : elle viole également la séparation de la structure et des performances et n'est pas recommandée
3) Parent débordement des paramètres de l'élément : caché
Définissez la valeur de débordement de l'élément parent sur caché ; dans IE6, hasLayout doit également être déclenché, comme zoom : 1
Le code est le suivant :
<p class="warp" id="float3" style="overflow:hidden; *zoom:1;"> <h2>3)父元素设置 overflow </h2> <p class="main left">.main{float:left;}</p> <p class="side left">.side{float:right;}</p> </p> <p class="footer">.footer</p>
优点:不存在结构和语义化问题,代码量极少
缺点:内容增多时候容易造成不会自动换行导致内容被隐藏掉,无法显示需要溢出的元素;04年POPO就发现overflow:hidden会导致中键失效,这是我作为一个多标签浏览控所不能接受的。所以还是不要使用了
4)父元素设置 overflow:auto 属性
同样IE6需要触发hasLayout,演示和3差不多
优点:不存在结构和语义化问题,代码量极少
缺点:多个嵌套后,firefox某些情况会造成内容全选;IE中 mouseover 造成宽度改变时会出现最外层模块有滚动条等,firefox早期版本会无故产生focus等, 请看 嗷嗷的 Demo ,不要使用
5)父元素也设置浮动
优点:不存在结构和语义化问题,代码量极少
缺点:使得与父元素相邻的元素的布局会受到影响,不可能一直浮动到body,不推荐使用
6)父元素设置display:table
优雅的 Demo
优点:结构语义化完全正确,代码量极少
缺点:盒模型属性已经改变,由此造成的一系列问题,得不偿失,不推荐使用
7)使用:after 伪元素
需要注意的是 :after是伪元素(Pseudo-Element),不是伪类(某些CSS手册里面称之为“伪对象”),很多清除浮动大全之类的文章都称之为伪类,不过csser要严谨一点,这是一种态度。
由于IE6-7不支持:after,使用 zoom:1触发 hasLayout。
该方法源自于: How To Clear Floats Without Structural Markup
原文全部代码如下:
代码如下:
<style type="text/css"> .clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } .clearfix {display: inline-block;} /* for IE/Mac */ </style> <!--[if IE]> <style type="text/css"> .clearfix {zoom: 1;/* triggers hasLayout */ display: block;/* resets display for IE/Win */} </style> <![endif]-->
鉴于 IE/Mac的市场占有率极低,我们直接忽略掉,最后精简的代码如下:
代码如下:
.clearfix:after {content:"."; display:block; height:0; visibility:hidden; clear:both; } .clearfix { *zoom:1; }
优点:结构和语义化完全正确,代码量居中
缺点:复用方式不当会造成代码量增加
小结
通过对比,我们不难发现,其实以上列举的方法,无非有两类:
其一,通过在浮动元素的末尾添加一个空元素,设置 clear:both属性,after伪元素其实也是通过 content 在元素的后面生成了内容为一个点的块级元素;
其二,通过设置父元素 overflow 或者display:table 属性来闭合浮动,我们来探讨一下这里面的原理。
在CSS2.1里面有一个很重要的概念,但是国内的技术博客介绍到的比较少,那就是 Block formatting contexts (块级格式化上下文),以下简称 BFC。
CSS3里面对这个规范做了改动,称之为:flow root,并且对触发条件进行了进一步说明。
那么如何触发BFC呢?
float 除了none以外的值
overflow 除了visible 以外的值(hidden,auto,scroll )
display (table-cell,table-caption,inline-block)
position(absolute,fixed)
fieldset元素
需要注意的是,display:table 本身并不会创建BFC,但是它会产生匿名框(anonymous boxes),而匿名框中的display:table-cell可以创建新的BFC,换句话说,触发块级格式化上下文的是匿名框,而不是 display:table。所以通过display:table和display:table-cell创建的BFC效果是不一样的。
fieldset 元素在www.w3.org里目前没有任何有关这个触发行为的信息,直到HTML5标准里才出现。有些浏览器bugs(Webkit,Mozilla)提到过这个触发行为,但是没有任何官方声明。实际上,即使fieldset在大多数的浏览器上都能创建新的块级格式化上下文,开发者也不应该把这当做是理所当然的。CSS 2.1没有定义哪种属性适用于表单控件,也没有定义如何使用CSS来给它们添加样式。用户代理可能会给这些属性应用CSS属性,建议开发者们把这种支持当做实验性质的,更高版本的CSS可能会进一步规范这个。
BFC的特性:
1)块级格式化上下文会阻止外边距叠加
当两个相邻的块框在同一个块级格式化上下文中时,它们之间垂直方向的外边距会发生叠加。换句话说,如果这两个相邻的块框不属于同一个块级格式化上下文,那么它们的外边距就不会叠加。
2)块级格式化上下文不会重叠浮动元素
根据规定,一个块级格式化上下文的边框不能和它里面的元素的外边距重叠。这就意味着浏览器将会给块级格式化上下文创建隐式的外边距来阻止它和浮动元素的外边距叠加。由于这个原因,当给一个挨着浮动的块级格式化上下文添加负的外边距时将会不起作用(Webkit和IE6在这点上有一个问题——可以看这个测试用例)。
3)块级格式化上下文通常可以包含浮动
详见: W3C CSS2.1 - 10.6.7 'Auto' heights for block formatting context roots
通俗地来说:创建了 BFC的元素就是一个独立的盒子,里面的子元素不会在布局上影响外面的元素,反之亦然,同时BFC任然属于文档中的普通流。
至此,您或许明白了为什么 overflow:hidden或者auto可以闭合浮动了,真是因为父元素创建了新的BFC。对于张鑫旭在对《overflow与zoom”清除浮动”的一些认识 》一文中对于用包裹来解释闭合浮动的原理,我觉得是不够严谨的,而且没有依据。并且说道“Firefox等浏览器并没有haslayout的概念”,那么现代浏览器是有BFC的,从表现上来说,hasLayout 可以等同于 BFC。
IE6-7的显示引擎使用的是一个称为布局(layout)的内部概念,由于这个显示引擎自身存在很多的缺陷,直接导致了IE6-7的很多显示 bug。当我们说一个元素“得到 layout”,或者说一个元素“拥有 layout” 的时候,我们的意思是指它的微软专有属性 hasLayout http://www.php.cn/ ... rties/haslayout.asp 为此被设为了 true 。IE6-7使用布局的概念来控制元素的尺寸和定位,那些拥有布局(have layout)的元素负责本身及其子元素的尺寸设置和定位。如果一个元素的 hasLayout 为false,那么它的尺寸和位置由最近拥有布局的祖先元素控制。
触发hasLayout的条件:
position: absolute
float: left|right
display: inline-block
width: 除 “auto” 外的任意值
height: 除 “auto” 外的任意值 (例如很多人清除浮动会用到 height: 1% )
zoom: 除 “normal” 外的任意值 (MSDN) http://www.php.cn/ ... properties/zoom.asp
writing-mode: tb-rl (MSDN) http://www.php.cn/ ... ies/writingmode.asp
在 IE7 中,overflow 也变成了一个 layout 触发器:
overflow: hidden|scroll|auto ( 这个属性在IE之前版本中没有触发 layout 的功能。 )
overflow-x|-y: hidden|scroll|auto (CSS3 盒模型中的属性,尚未得到浏览器的广泛支持。他们在之前IE版本中同样没有触发 layout 的功能)
hasLayout更详细的解释请参见 old9翻译的 大名鼎鼎的 《On having layout》一文(英文原文:http://www.php.cn/),由于old9博客被墙,中文版地址:
IE8使用了全新的显示引擎,据称不使用 hasLayout属性了,因此解决了很多深恶痛绝的bug。
综上所述:
在支持BFC的浏览器(IE8+,firefox,chrome,safari)通过创建新的BFC闭合浮动;
在不支持 BFC的浏览器 (IE6-7),通过触发 hasLayout 闭合浮动。
四、闭合浮动方法——精益求精
上面已经列举了7种闭合浮动的方法,通过第三节分析的原理,我们发现其实更多的:display:table- cell,display:inline-block等只要触发了BFC的属性值都可以闭合浮动。从各个方面比较,after伪元素闭合浮动无疑是相对比较好的解决方案了,下面详细说说该方法。
代码如下:
.clearfix:after {content:"."; display:block; height:0; visibility:hidden; clear:both; } .clearfix { *zoom:1; }
1) display:block 使生成的元素以块级元素显示,占满剩余空间;
2) height:0 避免生成内容破坏原有布局的高度。
3) visibility:hidden 使生成的内容不可见,并允许可能被生成内容盖住的内容可以进行点击和交互;
4)通过 content:"."生成内容作为最后一个元素,至于content里面是点还是其他都是可以的,例如oocss里面就有经典的 content:"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",有些版本可能content 里面内容为空,一丝冰凉是不推荐这样做的,firefox直到7.0 content:”" 仍然会产生额外的空隙;
5)zoom:1 触发IE hasLayout。
通过分析发现,除了clear:both用来清除浮动的,其他代码无非都是为了隐藏掉content生成的内容,这也就是其他版本的闭合浮动为什么会有font-size:0,line-height:0。
精益求精方案一:
相对于空标签闭合浮动的方法代码似乎还是有些冗余,通过查询发现Unicode字符里有一个“零宽度空格”,也就是U+200B ,这个字符本身是不可见的,所以我们完全可以省略掉 visibility:hidden了 代码如下:
.clearfix:after {content:"\200B"; display:block; height:0; clear:both; }
.clearfix { *zoom:1; }.
精益求精方案二:
由Nicolas Gallagher 大湿提出来的,原文:A new micro clearfix hack,该方法也不存在firefox中空隙的问题。
代码如下:
/* For modern browsers */ .cf:before,.cf:after { content:""; display:table; } .cf:after { clear:both; }/* For IE 6/7 (trigger hasLayout) */ .cf { zoom:1; }
需要注意的是:
上面的方法用到了 :before伪元素,很多人对这个有些迷惑,到底我什么时候需要用before呢?为什么方案一没有呢?其实它是用来处理margin边距重叠的,由于内部元素 float 创建了BFC,导致内部元素的margin-top和 上一个盒子的margin-bottom 发生叠加。如果这不是你所希望的,那么就可以加上before,如果只是单纯的闭合浮动,after就够了!并不是如同大漠《Clear Float》一文所说的:但只使用clearfix:after时在跨浏览器兼容问题会存在一个垂直边距叠加的bug,这不是bug,是BFC应该有的特性。
在实际开发中,改进方案一由于存在Unicode字符不适合内嵌CSS的GB2312编码的页面,使用方案7完全可以解决我们的需求了,改进方案二等待大家的进一步实践。方案3、4通过overflow闭合浮动,实际上已经创建了新的 块级格式化上下文,这将导致其布局和相对于浮动的行为等发生一系列的变化,清除浮动只不过是一系列变化中的一个作用而已。所以为了闭合浮动去改变全局特性,这是不明智的,带来的风险就是一系列的bug,比如firefox 早期版本产生 focus,截断绝对定位的层等等。始终要明白,如果单单只是需要闭合浮动,overflow就不要使用,而不是某些文章所说的“慎用”。
前前后后花了三天写完了这篇css为什么要清除浮动? 清除浮动的原理的文章。如果觉得本文对您有帮助,您的留言就是对我最大的支持,同时由于精力有限,欢迎指出文中错误与不足,共勉之!