`

浮层的原理与清除

 
阅读更多

1、为什么会产生浮层

 

首先我们看一下float这个属性,套用w3c标准,对该属性的定义如下:

 

 

float 属性定义元素在哪个方向浮动。以往这个属性总应用于图像,使文本围绕在图像周围,不过在 CSS 中,任何元素都可以浮动。浮动元素会生成一个块级框,而不论它本身是何种元素。

 

如果浮动非替换元素,则要指定一个明确的宽度;否则,它们会尽可能地窄(根据内容来计算其宽度,如果没有内容也没有设置该浮动层的宽度,则该浮动层在页面中是看不见的)。

 

注释:假如在一行之上只有极少的空间可供浮动元素,那么这个元素会跳至下一行,这个过程会持续到某一行拥有足够的空间为止

 

设置了该属性的left或right值后,该浮动元素(floats)就会被移出文档流。这就产生了一个问题:浮动元素所在父元素不会自动伸长以便闭合浮动元素。看下面的代码

 

 

<div id="outer">    
  <div id="inner"> <h2>A Column</h2> </div>    
  <h1>Main Content</h1>    
  <p>Lorem ipsum
</div>

      我们可以为“#inner”设定一个宽度值(比如说20%),但是由于div是块级元素,即使我们设定了宽度,其后面的内容也只能在下一行中显示,除非我们给它设定一个浮动属性(无论是向左浮动或者向右浮动)。那么此时会产生我们上面提到的问题了。

      如果“#inner”的宽度和高度都比“#outer”小,这不会有问题。

      但是,如果“#inner”的高度超过了“#outer”,那么的底部就会超出“#outer”的底部。这是因为我们为“#inner”设定了float属性后,它就会脱离文档流,无论其宽度和高度怎么变化都不会使“#outer”跟随变化。

 

      看下面代码:设置浮动层后,由于inner的高度超出了outer的高度,他会浮动起来,脱离文档流,而outer下面的div元素会根据outer的高度来定位自己的位置,这时outer没有自动变化高度,所以outer下面的元素就会显示在浮动层的右侧,在各主流浏览器都是这个效果。

 

 

       <div id="outer" style="border:1px solid #f2f2f2;">
		<div id="inner" style="float:left;height:300px;">
			<h2>A Column</h2>
		</div>
		<h1>Main Content</h1>
		<p>Lorem ipsum</p>
	</div>
	<div>
	有浮层显示的效果
	</div>

     如果我们在定义了浮动层影响父元素的内部加上清除浮动的方法后,页面就会正常显示,看下面代码

 

 

     <div id="outer" style="border:1px solid #f2f2f2;">
		<div id="inner" style="float:left;height:300px;">
			<h2>A Column</h2>
		</div>
		<h1>Main Content</h1>
		<p>Lorem ipsum</p>
		<div style="clear:both;"></div>
	</div>
	
	<div>
	有浮层显示的效果
	</div>

 

     在浏览器中再次预览效果,发现页面正常显示了,这里要说一点,就是浮动清除元素放到哪个位置,应该放到inner的下面(不一定紧挨着inner)。

 

2、 浏览器中可以自动完成闭合浮动元素的情况(即子元素设置了浮层,但父元素会自动撑开高度)

 

 

    2.1、标准浏览器中可以自动完成闭合浮动元素的方法,在标准浏览器中,这称之为Block-Formatting-Contexts(块格式化上下文):

       a.浮动元素;

       b.拥有绝对定位属性的元素;

       c.设置inline-block元素;

       d.table-cell元素;

       e.设置了overflow的元素,比如:auto/hidden。

【注】CSS3中,将Block-formatting-contexts 叫做 flow root。对于触发方式也做了修改:The value of ‘position’ is neither ‘static’ nor ‘relative’;

 

       那么在IE/win中,就依靠那个“hasLayout”了,触发“layOut”的方法有:

       a.浮动元素

       b.绝对定位元素

       c.display:inline-block

       d.zoom:比如常见的设置zoom:1;

       e.width/height,比如设置height:1%的方法;

       f.overflow/overflow-x/overflow-y [IE7 新增];

       g.max/min-width/height [IE7 新增];

 

   这里简单的举一个例子,看以下代码

 

 

<div>浮动中套浮动的效果</div>

	<div style="border: 1px solid #f2f2f2;">
		<div style="float: right;">
			<div style="float: left; height: 100px; border: 1px solid #f2f2f2;">由于父元素也是浮层,所以会自动闭合浮动层的(即父元素自适应高度的)</div>
			<div>内容</div>
		</div>
		<div style="clear: both;"></div>
	</div>

 

  最里边的浮动层由于父元素设置了浮动层,所以会自动闭合的

 

3、清除浮动常见方法

 

    我们知道了产生浮动的原理并且各浏览器清除浮层的不同后,清除浮动就好办了。主要有以下几种方式

 

 

   (1)空标签法:

       这种方法应该说是最简单的一种了,W3C建议在容器的末尾增加一个“clear:both"的元素,强迫容器适应它的高度以便装下所有的float,并没限制使用什么样的标签,有用<br style=”clear:both”/>的,有用空<div style=”clear:both”></div>的;比如: 

 

 

<div> 
     <div style ="float:left; width:40%;">
         <p> Some content </p>
     </div> 
     <p> Text outside the float </p> 
     <div style ="clear:both;" ></div> 
</div>

 

 

(2)父元素使用overflow的方法:

       通过设置父元素overflow值设置为hidden或者auto;不过,在<=IE6中使用这个方法,还需要haslayout,还有,使用overflow=hidden的时候,一旦你有定位需求可能会因此而难以实现,使用这种方法前你应该至少确定:

       a.父元素的height是自适应的;

       b.浮动元素的宽度不大于父元素的宽度,即没有溢出需求;所以,这种方法也有它的局限性;

 

 

<div style ="overflow:hidden; width:100%;"> 
    <div style ="float:left;width:30%;" > 
    <p>the widths of the combined floats never exceed the width of the container</p>
   </div>
</div>

 (3)伪类:after

       这种方法应该说是目前应用最广泛的方法,它的优势:没有多余的标记添加到容器中;通过使用:after产生的content不能接受某些属性,包括'position','float',列表属性,表格属性,但是clear属性可以被接受。

       不过,不幸的是,IE不支持:after方法,但又幸运的是,回顾前面,如果IE在父容器拥有Width/Height等layout状态下,会完成自动闭合,称之为“auto-clearing”;那么,对于IE/win,我们使用设定zoom:1的方法的方法来实现和:after一样的效果.于是一个类似这样的样式出现了:

 

 

.clearfix:after{
    content:".";
    display:block;
    height:0;
    clear:both;
    visibility:hidden;
}

.clearfix{zoom:1;}

    上面的代码应该是现在主流的清理浮动方式。现在支付宝就使用这样的方式。另外还有一种更简洁的方案:

 

(4)伪类:before和:after结合使用

 

 

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

     原理跟第三种是一样的。使用 :after 伪类来提供浮动块后的 clear:both。不同的是,隐藏这个空白使用的是 display: table。而不是设置 visibility:hidden;height:0;font-size:0; 这样的 hack。

     值得注意的是这里中的 :before 伪类。其实他是来用处理 top-margin 边折叠的,跟清理浮动没有多大的关系。但因为浮动会创建 block formatting context,这样浮动元素上的另一元素上如果刚好有 margin-bottom 而这个浮动元素刚好有margin-top 的话,应该让他们不折叠(虽然这种情况并不常见)。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics