浮动float
下面先来理解一些基本概念。
文档流:是html元素按顺序进行排列显示,这个顺序是从左到右,从上到下。也叫标准流。
css两大功能:1.控制元素外观。2.控制元素位置(布局)
布局前提:浏览器交出页面布局的权限,交给用户。即CSS所控制元素将从文档流脱离出来。而脱离出来的元素一定会变成块级元素。
脱离文档流的手段:浮动,绝对定位
注意:浮动并未完全脱离,只是可以控制元素在水平方向上自由移动,但是垂直方向依然在文档流中。
请看下面代码,定义了3个DIV容器并设置宽高和背景色。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>浮动float</title> <style> .boxA { width: 150px; height: 150px; background: lightblue; } .boxB { width: 150px; height: 150px; background: lightcoral; } </style> </head> <body> <div class="boxA">boxA</div> <div class="boxB">boxB</div> <div class="boxC">boxC</div> </body> </html>
点击 "运行实例" 按钮查看在线实例
现在是标准文档流。boxA排在boxB前面。但是如果我们给boxA设置浮动,则boxA则脱离的文档流,处于文档流最前面的则会变成boxB。
我们可以发现,页面上只有显示boxA的背景色。那boxB跑哪去了。boxB就在boxA下面。因为两者的宽高一样,所以被完全覆盖住了。如果我们把boxB宽高修改比boxA大,则如图所示:
总结:一个元素向左浮动,该元素将紧靠在页面左边,如果页面左边已有另一个浮动元素,则就紧靠着这个元素的左边。
如果boxB也向左浮动,则boxB就和boxA在水平方向紧贴着排列。
.boxB{float:left;}
总结:一个元素向左浮动,该元素将紧靠在页面左边,如果页面左边已有另一个浮动元素,则就紧靠着这个元素的左边。
前面讲到,浮动主要是对后面的元素有影响,如何清除这种影响呢。
且看下面例子:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>浮动float</title> <style> .boxA { width: 150px; height: 150px; background: lightblue; float: left; } .boxB { width: 250px; height: 250px; background: lightcoral; float: right; } .boxC { width: 300px; height: 300px; background: lightgreen; float: right; } .boxD { height: 100px; background: lightslategray; } </style> </head> <body> <div class="boxA">boxA</div> <div class="boxB">boxB</div> <div class="boxC">boxC</div> <div class="boxD">boxD</div> </body> </html>
点击 "运行实例" 按钮查看在线实例
现在boxA,boxB,boxC都把boxD覆盖住了。我们给boxD添加以下代码
.boxD{clear:left;}
我们清除了左浮动的影响,这个boxA就没盖住boxD。
接下来清除右浮动,
.boxD{clear:right;}
boxB和boxC也没盖住boxD。boxD则和有最大高度的boxC紧挨着。
消除子元素浮动对父元素造成的影响
那子元素浮动,会对父元素造成什么影响呢,且看下面下面例子
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>消除子元素浮动对父元素的影响</title> <style> .box1 { width: 300px; border: 5px dashed black; } .box2 { width: inherit; height: 250px; background: lightcoral; } </style> </head> <body> <div class="box1"> <div class="box2"></div> </div> </body> </html>
点击 "运行实例" 按钮查看在线实例
box1是box2的父级元素。box1包裹住了box2的区块。此时,我们给box2添加浮动,会发生什么呢?
.box2 {float:left;}
结果如图:
我们可以清楚的看到,代表虚线的box1没办法包裹住box2的区块。
解决办法
1、父元素设置和子元素相同的高度
.box1 {height:250px;}
如果子元素高度发生变化,box1的高度就要重新设置。这种方法太笨了,不推荐。
2、父元素也浮动起来
.box1 {float:left;}
此时,如果box1上面还有一层父元素依然会产生上面的影响。又必须给父元素的父元素添加浮动。这种方法局限性太大,也不推荐。
3、专门添加一个块级元素,用来清除浮动。
html部分
<body> <div class="box1"> <div class="box2"></div> <div class="clear"></div> </div> </body>
css部分
.clear {clear:both;}
此时,虽然父元素依然包裹住子元素区块。但是增加一个不是很必要块级元素,会造成页面冗余。这个方法也不推荐。
4、给父级元素添加overflower属性。
overflow属性定义及使用说明
overflow属性指定当内容溢出一个元素的框,会发生什么。比如内容被修剪后者添加滚动条。下面表格是overflow支持的属性值以及对值的描述:
值 | 描述 |
---|---|
visible | 默认值。内容不会被修剪,会呈现在元素框之外。 |
hidden | 内容会被修剪,并且其余内容是不可见的 |
scroll | 内容会被修剪,但是浏览器会显示滚动条以便查看其余的内容。 |
auto | 如果内容被修剪,则浏览器会显示滚动条以便查看其余的内容。 |
inherit | 规定应该从父元素继承 overflow 属性的值。 |
从上面的表格可以看出,子元素浮动会导致父元素无法包含子区块。是因为浏览器使用overflow:visible这个默认属性导致的。因此我们可以在box1修改其默认属性
.box1 {overflow:hidden;}
通过合理的使用该属性,我们得到了想要的结果,不会造成代码冗余也不会导致修改不便。因此推荐第4种方法。
网页三列布局的实现原理
要实现网页的布局,我们需要了解CSS定位的相关知识。
css定位将元素在页面重新排列。就是从标准文档流种获取了对指定元素的控制权。
CSS定位,要使用position属性来指定元素的定位类型。下面表格列出了position可能的值及对值的描述。
值 | 描述 |
---|---|
static | 默认值。没有定位,元素处于文档流(忽略 top, bottom, left, right 或者 z-index 声明)。 |
relative | 相对定位,元素仍在文档流,只是相对它原来的位置发生偏移 |
absolute | 绝对定位,元素脱离文档流,相对于离它最近的,具有定位属性的父级元素进行定位。元素的位置通过 "left", "top", "right" 以及 "bottom" 属性进行规定。 |
fixed | 固定定位,始终相对于浏览器的窗口进行定位(即相对于body元素)。元素的位置通过 "left", "top", "right" 以及 "bottom" 属性进行规定。 |
下面来实现网页的三列布局。
首先,经过观察,一般网页都包含有头部,主体,底部三大部分。
每个部分都可以用DIV标签定义,然后可以在三大部分设置一个共有的父级容器container。请看下面例子:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>实现网页的三列布局</title> <style> .container { width: 1000px; margin: 0 auto; } .header, .footer { height: 60px; background-color: lightsteelblue; } .main { min-height: 800px; background-color: lightsalmon; margin: 5px auto; } </style> </head> <body> <!-- 虽然我们可以直接使用body元素作为网站内容的父级元素,但是为了更好控制页面布局还是自定义一个容器。 定义一个大容器并设置左右外边距为auto,使大容器自动居中。上下外边距设置0像素。该容器,不用设置高度,只需设置一个通用宽度1000像素。 --> <div class="container"> <!-- 定义大容器的下的头部,给60个像素的高度,设置背景色。 --> <div class="header">头部</div> <!-- 定义大容器的主体部分,先给个最小高度把主体撑开,然后设置外边距使主体内容跟头部、底部相距5个像素。更好区分显示主体内容。 --> <div class="main">主体</div> <!-- 定义大容器下的底部,设置和头部一样的高度和背景色 --> <div class="footer">底部</div> </div> </body> </html>
点击 "运行实例" 按钮查看在线实例
上面的代码就是标准的文档流布局。每个区块显示的位置都是按照代码书写的顺序来排列的。
我们要实现的三列布局,主要在主体部分。通过定义三个div区块来把主体分成左、中、右三个部分水平排列。
这就需要使用CSS来控制元素的定位,使其脱离文档流,按照我们的设想来显示。
下面使用css的绝对定位来实现三列布局
我们先定义好主体的左、中、右三个部分。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>绝对定位实现网页的三列布局</title> <style> .container { width: 1000px; margin: 0 auto; color: cornsilk; font-size: 1.5em; } .header, .footer { height: 60px; background-color: lightsteelblue; } .main { /* min-height: 800px; 主体部分已有内容所以高度不用设置*/ background-color: lightsalmon; margin: 5px auto; } .left { width: 200px; background-color: red; min-height: 800px; } .content { background-color: blue; min-height: 800px; } .right { width: 200px; min-height: 800px; background-color: green; } </style> </head> <body> <!-- 虽然我们可以直接使用body元素作为网站内容的父级元素,但是为了更好控制页面布局还是自定义一个容器。 定义一个大容器并设置左右外边距为auto,使大容器自动居中。上下外边距设置0像素。该容器,不用设置高度,只需设置一个通用宽度1000像素。 --> <div class="container"> <!-- 定义大容器的下的头部,给60个像素的高度,设置背景色。 --> <div class="header">头部</div> <!-- 定义大容器的主体部分,先给个最小高度把主体撑开,然后设置外边距使主体内容跟头部、底部相距5个像素。更好区分显示主体内容。 --> <div class="main"> <div class="left">主体左侧</div> <div class="content">内容区</div> <div class="right">主体右侧</div> </div> <!-- 定义大容器下的底部,设置和头部一样的高度和背景色 --> <div class="footer">底部</div> </div> </body> </html>
点击 "运行实例" 按钮查看在线实例
效果如图
上图是文档流的显示效果。
要使用绝对定位,我们需要给最近的父级元素设置定位属性。
这里最近的父级元素就是<div class="main"></div>
.main {position:relative;}
然后左侧、右侧各自定位main区块的最左上角和最右上角。
.left { position:absolute; left:0; top:0; } .right { position:absolute; right:0; top:0; }
效果如图:
此时,主体左侧、右侧已经脱离了文档流,主体内容区已经被覆盖了。比如我们在主体内容添加一个段落。
段落文字被覆盖,我们看不到整个段落。所以我们需要给主体内容区设置左右外边距,使其内容区刚刚好落在中间不被覆盖的区域。而覆盖的主体左侧、右侧各占200个像素,所以外边距可以这设置:
.content {margin:0 200px;}
完整代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>绝对定位实现网页的三列布局</title> <style> .container { width: 1000px; margin: 0 auto; color: cornsilk; font-size: 1.5em; } .header, .footer { height: 60px; background-color: lightsteelblue; } .main { /* min-height: 800px; 主体部分已有内容所以高度不用设置*/ background-color: lightsalmon; margin: 5px auto; position: relative; } .left { width: 200px; background-color: red; min-height: 800px; position: absolute; left: 0; top: 0; } .content { background-color: blue; min-height: 800px; margin: 0 200px; } .right { width: 200px; min-height: 800px; background-color: green; position: absolute; right: 0; top: 0; } </style> </head> <body> <!-- 虽然我们可以直接使用body元素作为网站内容的父级元素,但是为了更好控制页面布局还是自定义一个容器。 定义一个大容器并设置左右外边距为auto,使大容器自动居中。上下外边距设置0像素。该容器,不用设置高度,只需设置一个通用宽度1000像素。 --> <div class="container"> <!-- 定义大容器的下的头部,给60个像素的高度,设置背景色。 --> <div class="header">头部</div> <!-- 定义大容器的主体部分,先给个最小高度把主体撑开,然后设置外边距使主体内容跟头部、底部相距5个像素。更好区分显示主体内容。 --> <div class="main"> <div class="left">主体左侧</div> <div class="content">主体内容区 <p>绝对定位absolute 作用:使元素脱离自然流 特点: 1、脱离自然流 2、设置尺寸的百分比比的是最近可定位的祖先元素 3、lrtb如果设置为0,它将对齐到最近可定位祖先元素的各边(衍生水平垂直居中妙计) 4、如果没有最近可定位祖先元素,会认作为可定位祖先元素 5、z-index可以控制堆叠顺序 </p> </div> <div class="right">主体右侧</div> </div> <!-- 定义大容器下的底部,设置和头部一样的高度和背景色 --> <div class="footer">底部</div> </div> </body> </html>
点击 "运行实例" 按钮查看在线实例
下面使用css的浮动方式来实现三列布局
我们是主体的左侧,内容区,右侧一起浮动起来。
注意:在给主体的三部分浮动之前,需要给这3部分的父级元素添加overflow:hidden;属性。用来清除子元素浮动对父元素的影响。其中还需要给主体内容区设置宽度:大容器是1000像素,左右两侧各占200像素,所以内容区设置600像素即可。
代码如下:
.main{overflow:hidden;} .left {float:left;} .content {float:left; width:600px;} .right {float:right;}
完整代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>浮动方式实现网页的三列布局</title> <style> .container { width: 1000px; margin: 0 auto; color: cornsilk; font-size: 1.5em; } .header, .footer { height: 60px; background-color: lightsteelblue; } .main { /* min-height: 800px; 主体部分已有内容所以高度不用设置*/ background-color: lightsalmon; margin: 5px auto; } .left { width: 200px; background-color: red; min-height: 800px; } .content { background-color: blue; min-height: 800px; } .right { width: 200px; min-height: 800px; background-color: green; } .main { overflow: hidden; } .left { float: left; } .content { float: left; width: 600px; } .right { float: right; } </style> </head> <body> <!-- 虽然我们可以直接使用body元素作为网站内容的父级元素,但是为了更好控制页面布局还是自定义一个容器。 定义一个大容器并设置左右外边距为auto,使大容器自动居中。上下外边距设置0像素。该容器,不用设置高度,只需设置一个通用宽度1000像素。 --> <div class="container"> <!-- 定义大容器的下的头部,给60个像素的高度,设置背景色。 --> <div class="header">头部</div> <!-- 定义大容器的主体部分,先给个最小高度把主体撑开,然后设置外边距使主体内容跟头部、底部相距5个像素。更好区分显示主体内容。 --> <div class="main"> <div class="left">主体左侧</div> <div class="content">主体内容区 <p>绝对定位absolute 作用:使元素脱离自然流 特点: 1、脱离自然流 2、设置尺寸的百分比比的是最近可定位的祖先元素 3、lrtb如果设置为0,它将对齐到最近可定位祖先元素的各边(衍生水平垂直居中妙计) 4、如果没有最近可定位祖先元素,会认作为可定位祖先元素 5、z-index可以控制堆叠顺序 </p> </div> <div class="right">主体右侧</div> </div> <!-- 定义大容器下的底部,设置和头部一样的高度和背景色 --> <div class="footer">底部</div> </div> </body> </html>
点击 "运行实例" 按钮查看在线实例
如果我们不给要主体添加overflow属性的话,因为子元素浮动的影响,底部会出现在头部下面。
这是因为,浮动元素会影响后面的元素的。所以需要在给底部区块添加clear属性:
.footer {clear:both;}
需要注意的是,此时底部和主体之间的外边距出现在内容区和主体右侧之间。主体的高度则变成0。
此时,页面的布局已经被破坏掉了。给后面的开发增大了难度。所以不推荐这种方式。而是直接给主体添加overflow属性,才能按照我们一开始的设想布局。
总结:float浮动和绝对定位,会使元素脱离文档流。而只要脱离了文档流的元素就有可能对处于文档流的元素产生各种各样的影响,比如遮挡住了正常内容显示或者使父级元素的高度产生变化等等。布局就是通过设置元素的外边距或者合理使用相应的属性的来消除各种影响。