本文从一个简单的HTML页面入手,对为什么要有浮动,如何设置浮动,元素设置浮动后自身的变化及对整个布局产生的影响,以及如何消除浮动带来的影响都做了详细的过程解析,理解浮动对页面布局来说很重要,希望本文能有所帮助!
一、认识浮动
普通标准文档流中,浏览器从HTML文件的最上面开始,从上至下,从左至右,逐个显示每个元素,每个元素在HTML文档中的位置就限制了他在页面中的位置。
先看一个简单的HTML
html>
浮动#header,#footer{background:pink;}
div{border: 1px solid grey;margin: 5px 10px;}
body{border: 1px solid black;}
#content{background:skyblue;}
#sidebar{padding: 5px;float: right;}
点击去购买
以上HTML由三大部分组成:div#header、div#main、div#footer,其中div#main又由两小部分组成:div#content和div#sidebar
浏览器从上到下依次渲染,如下
上面就是标准的文档流,各个元素在页面中的位置和顺序由元素在HTML中的位置和顺序决定
如果想形成丰富的页面效果,让元素能够按照我们指定的位置摆放,就需要用到浮动属性float了,让元素"浮"起来,"动"起来。
比如这里想让div#main中的子元素div#sidebar以侧边栏的形式显示在div#main的右侧,并和div#content左右分离,以两栏显示。
接下来,我们一步一步解析如何实现:
浮动就是指将元素脱离文档流向左或向右布局,使用float属性来设置,有三个取值:none(不浮动)、left(向左浮动)、right(向右浮动)
这里对div#sidebar设置float属性,取值right,加载如下
前后对比,有两个明显的不同
一是div#sidebar原来是占满整个浏览器宽度的,浮动之后,宽度自动变成内容的宽度;
二是元素设置浮动之后,会脱离标准流,浮在页面上,后面的元素div#footer上移,父元素div#main高度收缩,如果父元素中只有div#sidebar这一个元素,设置浮动之后父元素塌陷情况会更严重
这里需要注意的一点是,由于div#sidebar元素在div#container的后面,虽然设置了浮动,浏览器也是从上到下依次解析,先解析div#content,后解析div#sidebar,将它从标准流删除,浮动到div#content下方的最右侧。所以这里要实现两边栏的效果,需要先对调div#sidebar和div#content在HTML中的位置,此时再加载
我们看到div#sidebar如预期的那样出现在了div#content的右边,但是由于脱离标准流浮动在页面上,div#main和div#footer右边的部分区域被浮在上面的元素盖住了,虽然div#container中的内容碰到浮动元素的边缘就会换行,自动绕流,但是背景色和背景图片还是会被盖住,整个页面结构不够清晰。
我们期望的效果是:
1、视觉上div#sidebar好像包含在父盒子中,整个父盒子高度能自适应。div#sidebar和div#footer上下分离,不能发生重合
2、视觉上div#content和div#sidebar在div#main中左右分离
为了达到以上效果,就需要清除浮动带来的影响
二、清除浮动带来的影响
浮动引起的主要问题之一是元素设置浮动之后,脱离标准流,不再占用原来的空间,导致父元素塌陷。所以可以直接为父元素设置一个高度,视觉上看起来包裹所有的子元素,包括已脱离标准流的浮动元素。
方法一:给父元素设置一个高度
分析:在知道子元素高度的前提下,设置高度能直接的达到目的。但如果父元素中的子元素个数不固定,高度不固定呢?如果指定一个高度,父元素的高度就不能随着子元素个数和高度的变化而变化了,限制了整个自适应布局。
要想清除浮动带来的影响,又不破坏父元素的高度自适应,就需要借助一个新属性clear。
方法二:使用clear属性
clear属性用于设置元素哪一侧不允许有浮动元素,有四种取值
具体实现:
在父元素div#main的所有子元素的后面添加一个专门用来清除浮动的子元素div.clear,并设置div.clear的clear属性为right(因为此处只需要清除右侧的浮动)
因为div.clear的作用只是用来清除浮动,所以内容为""空,另外本案例为了观察更明确,给所有div设置了边框,这里设置div.clear的border-width为0px,覆盖原来的border属性。
代码做修改后,看一下效果
现在div#footer和div#sidebar上下成功分离,div#sidebar和div#content好像也撑起了盒子(本质上div#sidebar还是浮动在页面上的),但是div#content和div#sidebar还是没有做到左右视觉上的分离,因为div#content为了实现自适应布局,此处没有指定宽度,默认占据整个父元素的宽度,而div#sidebar是脱离标准流的,自然会重合。
这里可通过设置div#content的margin-right属性来巧妙的实现左右视觉上分离。
具体实现:
先为div#sidebar指定一个width,这里设置为120px,再设置div#content的margin-right为150px,目的就是为了通过div#content的右外边距控制和div#sidebar之间的距离,外边距只要大于浮动元素的宽度即可。效果如下
为了验证实现自适应布局的效果,我们手动改变浏览器的宽度,如下
以上通过浮动属性,clear属性及margin属性的综合运用,把一个自上而下的标准流的布局变成了页面布局更清晰的分栏布局,同时也是自适应的页面布局,随着浏览器的伸缩不会破坏整个布局。
修改后的完整代码
html>
浮动#header,#footer{background:pink;}
div{border: 1px solid grey;margin: 5px 10px;}
body{border: 1px solid black;}
#content{background:skyblue;margin-right: 150px;}
#sidebar{padding: 5px;float: right;width: 120px;}
#footer{}
.clear{clear: both;border-width: 0px;}
点击去购买
当然清除浮动还有别的方式,这里暂时先做以上讨论。
注:以上布局主要是为了说明浮动的"浮"和"动"特性,其他方面先不做考虑。如有疏漏之处,欢迎指正,我们一起成长快乐。