CSS中浮动与浮动清除

前言

       最近在准备春招面试,好几个前端朋友面试的时候被问到了浮动与浮动清除的问题。虽然平时经常用到浮动,但对浮动只是一知半解,不清楚原理到底是怎样的。不知道各位有没有跟我一样的感觉,所以我找了一段整块时间研究了一下浮动的原理和清除浮动的方法,并写下这篇分享文章。此分享仅供参考,有什么理解错误的地方敬请大家指正。

CSS常用的三种布局方式

       在CSS中元素分三类:行内元素(inline)、块级元素(block)和行内块级元素(inline-block),在不同的布局方式下,元素会表现出不同的行为。

文档流(标准流)

       这是浏览器默认的布局方式,在这种布局下,行内元素和行内块级元素水平布局,块级元素垂直布局。

浮动流

       半脱离标准流的布局方式,只有水平排版方式,只能设置元素左对齐或者右对齐,没有居中对齐。浮动流中不区分元素类型,无论哪种元素都可以水平排版,与标准流中的行内块级元素很像。

定位流

       其中static是默认方式,也就是标准流,relative不脱离标准流,以其原本在标准流中的位置相对定位,会在标准流中占位(效果可以大致理解为设置了margin),absolute和fixed完全脱离标准流,对标准流没有任何影响。

       三种布局方式的层级关系:浮动流高于标准流,定位流高于浮动流。这句话现在不理解没关系,后面我们会具体看到。

浮动

       下面我们具体看一下浮动布局。在我们默认的标准流中,每个块级元素占一行,自上而下排列。
CSS中浮动与浮动清除_第1张图片
       我如果希望在一行中显示多个div,显然标准流是做不到的,这个时候我们就需要用到浮动,让这个div脱离标准流,顾名思义就是飘浮在标准流上面。我给div1加一个float:left;看看会发生什么。
CSS中浮动与浮动清除_第2张图片
       我们发现绿色的div2不见了,其实div2并没有消失,而是“钻”到div1下面去了。因为给div1加左浮动之后,div1脱离标准流飘起来,而div2依然在标准流中,这时div2发现标准流中他的前面没有其他元素了,所以他就“钻”到了div1的下面,也就是div1原本在标准流中的位置。
       现在我们再回过头看前面我们说到的,浮动流是半脱离标准流的布局方式,并且浮动流的层级高于标准流。为什么说是半脱离标准流呢?这是因为浮动元素不能改变其自身和上面的标准流元素的垂直位置关系。那么为什么又说浮动流的层级比标准流高呢?因为浮动流元素下面的标准流元素会“钻”到他的下方。

浮动清除

       浮动有时候会给我们的布局带来很多便利,但同时,我们也必须面对和处理浮动带来的影响。首先,我们来看浮动会带来什么问题,现在有三个div,属于标准流,各占一行。如图:
CSS中浮动与浮动清除_第3张图片
       现在我希望前两个div在同一行而div3的位置在div1和div2的下面,这个时候就用到浮动了,给前两个div添加一个浮动,结果并不是我们想要的,如图:
CSS中浮动与浮动清除_第4张图片
       原因就是上面所说的,前两个浮动的div脱离了标准流,而浮动流的层级高于标准流,所以就相当于前两个div飘起来了,所以属于标准流的div3发现标准流上面没有元素了,它自然会顶上去。但这并不是我们希望要的效果,所以现在就要用到浮动清除。这里先说第一个方法,隔墙法。
       顾名思义,隔墙法就是在需要清除浮动的元素和浮动元素之间添加一个空的块级元素,并给他一个clear属性,或者给div3一个clear属性,其中clear属性可以是如下这几个值:both/left/right/none/inherit,分别表示左右两边均不允许出现浮动元素、左边不允许出现浮动元素、右边不允许出现浮动元素、不清除浮动、继承父元素的值。直接上代码(第一种,这是W3C推荐的方法):

<body>
<div id="div1">div1</div>
    <div id="div2">div2</div>
    <div class="clear"></div>
    <div id="div3">div3</div>
</body>
<style>
.clear{
		clear:both;
	}
</style>

       在div1.2和div3中间空的div起到像一面墙把浮动元素和不浮动的元素隔开,我们看一下效果图:
CSS中浮动与浮动清除_第5张图片
       那么clear是怎么做到这一点的呢?clear 会为元素添加空白空间(可以理解为外边距),使得该元素会被放置在它前一个浮动元素之下,这跟增加元素外边距使得元素占据满行而强制换行是一个道理。
       了解了clear之后,我们再来看看浮动会带来的第二种问题,现在有如下结构和样式的页面:

<body>
	<div id=”div3”>
<div id="div1">div1</div>
    	<div id="div2">div2</div>
    </div>
</body>
<style>
	#div1{
   		background: red;
    	height: 100px;
    	width: 100px;
    	color: #000;
    	font-size: 20px;
  	}
  	#div2{
    	background: greenyellow;
    	height: 100px;
    	width: 100px;
    	color: #000;
    	font-size: 20px;
  	}
  	#div3{
    	background: lightblue;
  	}
</style>

       看一下效果,很容易理解div1和div2把父元素撑开了,如图:
CSS中浮动与浮动清除_第6张图片
       这时,一个鬼魅的操作涌上心头,我想让div1和div2放在一行,所以现在我给div1和div2加一个浮动,来看看会有什么变化:
CSS中浮动与浮动清除_第7张图片
       背景去哪了?原来是因为div1和div2加了浮动脱离了标准流,原本撑开父元素的标准流里的div1和div2飘起来了,没有元素来把父元素撑开,所以父元素就“消失”了,这就是常说的“高度塌陷”,但我们不想让高度塌陷,所以这个时候就要清除浮动了。现在给出清除浮动的第二种方法,在父元素上设置overflow属性为auto或者hidden,这样一来父元素就会扩展包含浮动(根本原因是因为父元素变成BFC,能包含浮动元素)。现在我们给父元素加上overflow属性:

<body>
	<div id"div3">
<div id="div1">div1</div>
    	<div id="div2">div2</div>
    </div>
</body>
<style>
	#div1{
   		background: red;
    	height: 100px;
    	width: 100px;
    	color: #000;
    	font-size: 20px;
  	}
  	#div2{
    	background: greenyellow;
    	height: 100px;
    	width: 100px;
    	color: #000;
    	font-size: 20px;
  	}
  	#div3{
    	background: lightblue;
		overflow:hidden;
  	}
</style>

       来看看效果:
在这里插入图片描述
       现在外面的父元素就又出现了,需要注意的是,overflow原本不是用来清除浮动的,有可能会导致即使高度没有超出限制,但还是出现滚动条的情况。
       还有一种方法就是使用:after伪元素,话不多说直接上代码。

<body>
	<div id="div3">
		<div id="div1">div1</div>
    	<div id="div2">div2</div>
    </div>
</body>
<style>
	#div1{
   		background: red;
    	height: 100px;
    	width: 100px;
    	color: #000;
    	font-size: 20px;
  	}
  	#div2{
    	background: greenyellow;
    	height: 100px;
    	width: 100px;
    	color: #000;
    	font-size: 20px;
  	}
  	#div3{
    	background: lightblue;
  	}
  	.clear:after {
    	content: "";
    	display: block;
    	height: 0;
    	clear: both;
  	}
</style>

       可以看到这种方法把清除浮动写成公共样式,只要在需要清除浮动的地方添加这个类就可以,最终效果跟上面是一样的。相对来说这种方法最方便,重用性好,兼容主流浏览器,最推荐使用。

参考文献

https://www.cnblogs.com/zhongweizhu/p/6003537.html


       以上是我对浮动与清除浮动的理解,如有错误还请大牛指正,如有不同意见也欢迎质疑,希望对大家有所帮助,也希望同样在准备春招的朋友一切顺利。

你可能感兴趣的:(前端技术)