CSS进阶(9)—— 那些年骗过你的float和“清浮动”

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dkr380205984/article/details/84560541

  如果你被这个标题骗进来,那恭喜你,你获得了一个重新认识float的机会,这句话不仅是我想对前端程序猿说的,也是我想对自己说的。在使用flex布局之前,float一度是我最最喜欢用的布局方式,在没有接触CSS world之前,我甚至认为float才是最符合"流"特质的属性,我自己将float属性定义成CSS的“果冻属性”,可能是因为float元素会像一颗果冻一样在图文间滑来滑去。事实上,我们都知道,float是一种破坏文档流的属性,除了float,position属性不为static/relative的时候也会破坏文档流,但他们破坏的方式却差很多,相比之下,float要温和的多,因为float还要顾虑相邻节点的感受,在遇到图文的时候,float会选择绕道而行,而position:absolute/fixed则不同,他们只管最近的具有定位属性的父节点。因此,float的破坏方式较为温和,像个果冻,而position的破坏方式比较暴力,像一片云,超脱于一切之上,完全飘了的感觉。

  说了这么多,有些跑题,下面正式开始本章的内容,深入了解float,在过程中揭秘我们对浮动以及清浮动深深的“误解”。

1.探究图片环绕文字的传说

  在深入了解float之前,相信大家都听过一个传说,就是float被设计出来的目的是为了实现文字环绕图片的效果,可能是初学的时候忘了,还是受了“清浮动”的毒,我自己都忘了有没有用float去实现过这个效果。因此下面我们先来实现一下float的设计初衷,文字环绕图片效果。

<div style="width: 200px">
	<div style="float: left;">
		<img width="100" height="100" src="../小和尚.jpg">
	</div>
	<p>我想实现文字环绕,因此需要多一些文字看一下效果我想实现文字环绕,因此需要多一些文字看一下效果</p>
</div>

  非常简单的一段代码,也不需要什么牛逼哄哄的操作,float就帮助我们实现了文字环绕图片的效果。为了实现这种效果,CSS设计师在设计float属性的时候定义了float的两个特性。

  (1)“破坏文档流”,使得父元素得高度塌陷。

  (2)禁止行框盒子与浮动元素发生重叠。

  下面我们结合这两个特性,来说说图片是如何环绕文字的。第一点,破坏文档流,使得父元素高度塌陷,这个时候,我们的p标签作为一个block元素,肯定是想着我要填满父容器的宽度,而事实上,块级元素也是不辱使命的完成了自己的任务,我们可以给块级标签加个背景色,然后把图片搞成小透明,看一下是不是这样。

  果然,第一个条件生效了,然而高度塌陷只是让浮动元素和块级元素在一个水平线上了,如何实现文字环绕效果呢?这个时候就需要我们的第二个属性出场了,就是float元素禁止与行框盒子发生重叠(个人认为这是float和绝对定位的最大区别之一),对“行框盒子”还不理解的童鞋请转内联元素那章。注意,我特意强调了行框盒子,也就是本例中匿名内联元素生成的每一行,这个跟块级元素的盒子没有半毛钱关系。为了验证这个想法,我们可以把p标签转化成内联元素(display:inline)看下效果。为了看上去更明显,我把图片的透明度设成了0,可以看到,浮动元素确实是和行框盒子发生了不重叠的关系。

  至此,我们已经完全了解了那个float的传说。

2.浮动锚点和浮动参考?听都没听过!

  我估计在座的各位和我一样(是个辣鸡),都是第一次听说浮动锚点和浮动参考,更别说去了解特么的概念了。干巴巴的讲概念在CSS世界里根本行不通,很多东西都要通过实践,确认过眼神才能够去猜测其内部的原理。那么我们就通过一个例子来了解一下这两个概念。

<!-- 测试浮动参考 -->
<div style="width: 200px;text-align: justify;background: yellow">
	<span>这里有很多文字,且要超出一行且要超出一行且要超出一行</span>
	<span style="float: right;color:blue">更多</span>
</div>

  首先上面这个例子,文字超出一行的时候,浮动元素会浮在哪儿?是文字的第一行?还是文字的最后一行?还是随便浮?答案是,最后一行,看一下具体效果就知道了。

  既然结果已经出来了,那么,为什么呢?

  这个时候就要邀请我们的浮动参考出场了。浮动参考,顾名思义,就是指float元素要对齐参考的实体是谁?

  在CSS世界中,float元素的浮动参考是“行框盒子”,这个行框盒子特么又出来了,怎么感觉哪儿都有它。注意是行框盒子,跟其父容器子元素等等等等都没半毛钱关系。这里作者温馨提示,在新的标准中,float的浮动参考不仅仅是行框盒子,但他没有展开,我也懒得查阅,就当留个悬念。知道了浮动参考的概念后,我们就可以解释上面这个例子了,由于float元素是参考行框盒子对齐的,因此,float可能在第一行,也可能在第二行,为什么在第三行呢?

  这里其实作者没有说明,我提出一个假设就是浮动元素参考的是离他最近的行框盒子,这个观点由本人提出,由本人验证后发现事实就是这样,所以有时候CSS的世界就是瞎猜一通然后验证。下面我来简单验证一下这个观点,其实很简单,只要把浮动元素放到span标签前面就可以了。如下所示

<!-- 验证浮动参考是离他最近的行框盒子 -->
<div style="width: 200px;text-align: justify;background: yellow">
	<span style="float: right;color:blue">更多</span>
	<span>这里有很多文字,且要超出一行且要超出一行且要超出一行</span>
</div>

  结果完全印证了我的想法是正确的,我吹爆我自己!

  说完了浮动参考,那么什么是浮动锚点?浮动锚点是float元素所在流中的一个点,你可以理解为是一个空的内联元素,为什么要有这个点呢?道理很简单,有时候我们的浮动元素没有可以参考的行框盒子,也就是他的四周都被一群block大汉包围的时候该怎么办?往哪里定位?没有关系,他自己带一个可以参考的浮动锚点。由于这个属性没什么特殊之处,这里就不过多介绍了,了解一下就好。

3.那些年你被骗过的clear“清浮动”

  相信我们初学浮动的第一课便被灌输了“浮动”破坏文档流是个祸害的思想,为了解决浮动元素导致高度坍塌的“bug”,我们被要求清浮动。然后给了一大堆清浮动的方法,最后提出最好用的是after伪类清浮动,当时还真觉得煞有其是,现在看来真的是人言可畏。如果CSS自家制定的标准都被当作了bug,那还有什么不是bug呢?

  看完这一章后,你应该可以明白两个概念,第一,浮动引起的高度坍塌是为了解决图文环绕效果而被制定的标准,并不是所谓的bug。第二,所谓的clear清浮动,并没有清除掉浮动

  为什么说clear没有清除掉浮动呢?从字面意思上理解,clear确实是清除的意思,然而官方对于clear的解释是:

  元素盒子的边不能和前面的浮动元素相邻。

  这句话听起来很拗口,但可以明确的知道,clear并没有改变任何浮动元素的特性,浮动元素依旧是那个浮动元素,不管你清不清,他还是在那边,浮着。

  那么这句话的涵义是什么呢?仔细剖析一下,你会发现,“清浮动”的奥秘就在于这个不能相邻的标准。事实上,clear被制定出来就是为了解决口耳相传的“高度坍塌bug”,因此浮动元素本身的特性被完美保留。概念讲的干了,来看一个例子吧

<!-- 清浮动原理探究 -->
<div>
	<div class="li"></div>
	<div class="li"></div>
	<div class="li"></div>
	<div class="li"></div>
	<div class="li"></div>
	<div class="li"></div>
	<div class="li"></div>
	<div class="li"></div>
	<div class="li"></div>
	<div class="li"></div>
</div>
<style>
	.li{
		float: left;
		margin: 10px;
		width: 40px;
		height: 40px;
		background: yellow
	}
	.li:nth-of-type(3){
		clear: both;
	}
</style>

  上面这个例子,最终li会被清浮动分割成几行?

   最终结果是:两行,如下所示。

  我们用所学的理论知识来解释下为什么是两行,在样式表中,第三个浮动元素使用了清浮动的属性,此时,根据标准,当前元素不能和前面的浮动元素相邻,也就是第三个元素不能和第二个元素做朋友了,那只能换行了,然而标准没有规定第三个元素不能和后面的元素做朋友,因此第三个元素以及之后的元素依旧保持左浮动的特性规则排列。由于第一行和第二行都保持了浮动的特性,因此高度全部坍塌,此时父级容器div的高度依旧是0,不会因为清了浮动,父容器的高度就变成第一行的高度了,父容器高度依旧是0!注意是0!

  看完了上面的例子,再来简单了解下clear的四个属性,分别是none(默认,就是没有),left(清左浮动),right(清右浮动)以及我们最常用的both(全清)。作者这里给出了clear的基本使用方式就是clear:both。left和right属性根本没有软用,让CSS自己判断就好了,因为不可能有一个元素既是left又是right浮动的,因此无需考虑是清左浮动还是右浮动,全清就完事了。

  由于clear只能确保和前面的元素发生关系,因此我们最常使用的是after伪类清浮动,而不是before,因为before生成的元素根本没法和后面的元素交流clear的事情。最后我们放上我们最喜欢使用的after伪类清浮动的方法,注意clear属性只有块级元素才有效,而伪类的默认属性是内联值,不要忘了display:block申明。

<div class="clearfix">
	<div class="li"></div>
	<div class="li"></div>
	<div class="li"></div>
	<div class="li"></div>
	<div class="li"></div>
	<div class="li"></div>
	<div class="li"></div>
	<div class="li"></div>
	<div class="li"></div>
	<div class="li"></div>
</div>
<style>
	.li{
		float: left;
		margin: 10px;
		width: 40px;
		height: 40px;
		background: yellow
	}
	.li:nth-of-type(3){
		clear: both;
	}
	.clearfix::after{
		content: '';
		display: block;
		clear: both;
	}
</style>

  本章到这里其实还没有结束,下一章的内容会继续探讨float的BFC特性,以及如何用overflow真正的清除浮动。

  其实我自己也还没看,只是做个预告,感兴趣的关注下吧~

猜你喜欢

转载自blog.csdn.net/dkr380205984/article/details/84560541
今日推荐