浮动原理
浮动VS “inline-block”
1. 对比
浮动 | inline-block |
使块元素在同一行显示 | 使块元素在同一行显示 |
使内嵌元素支持宽高 | 使内嵌元素支持宽高 |
没设置宽度时,默认内容撑开 | 没设置宽度时,默认内容撑开 |
代码空格、换行不被解析 | 代码空格、换行被解析 |
没有IE6、IE7兼容性问题 | IE6、IE7下块元素不支持 |
会使margin 0 auto左右居中失效 | 会使margin 0 auto左右居中失效 |
2. 通过上面的对比表格,可以得出下面结论:
a) 浮动既保留了“inline-block”的所有优点,又没有“inline-block”身上的所有缺陷。
b) 浮动可以看做是“inline-block”的升级版。
原理
1. 浮动的三大属性,如下:
a) left (从左向右浮动)
b) right (从右向左浮动)
c) none (没有)
2. 例1(左浮动):
a) 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>浮动</title> <style> div,span{width:100px;height:100px;background:red;border:1px solid #000; float:left;} </style> </head>
<body> <div>div1</div> <!-- 按照文档至上而下的顺序div1将第一个接收到左浮动命令--> <div>div2</div> <span>span1</span> <span>span2</span> </body> </html> |
b) 效果
3. 例2(右浮动):
a) 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>浮动</title> <style> div,span{width:100px;height:100px;background:red;border:1px solid #000; float:right;} </style> </head>
<body> <div>div1</div> <div>div2</div> <span>span1</span> <span>span2</span> </body> </html> |
b) 效果
脱离文档流
1. 元素加了浮动后会脱离文档流,按照指定的一个方向移动,直到碰到父级的边界或者另一个浮动元素停止。
a) “浮动”顾名思义是一个“浮”和一个“动”组成。
i. “浮”就是漂浮起来脱离文档流。
ii. “动”就是按照指定的一个方向移动。
2. 例1(使用浮动前):
a) 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>浮动</title> <style> .div1{width:100px;height:100px;background:red;} .div2{width:200px;height:200px;background:blue;} </style> </head>
<body> <div class="div1">div1</div> <div class="div2">div2</div> </body> </html> |
b) 效果
3. 例2(使用浮动后):
a) 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>浮动</title> <style> .div1{width:100px;height:100px;background:red;float:left;} .div2{width:200px;height:200px;background:blue;} </style> </head>
<body> <div class="div1">div1</div> <div class="div2">div2</div> </body> </html> |
b) 效果
提升层级(浮动提升半层)
1. “浮动”中“浮”其实就是给元素提升了层级,提升的幅度为半层。
2. 层
a) 如果我们将整个元素看成是一层的话,那么下半层是元素本身(包含背景样式等),上半层就是元素中的内容。
3. 例:
a) 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>浮动</title> <style> .div1{width:100px;height:100px;background:red;float:left;} .div2{width:200px;height:200px;background:blue;} </style> </head>
<body> <div class="div1">div1</div> <div class="div2">div2</div> </body> </html> |
b) 效果
4. 图解上例
clear
1. 元素的某个方向上不能有浮动元素。
2. clear属性只能加在块元素上,加在内嵌元素上是不起作用的。
a) 这也是后面“:after”清浮动为什么要加“display:block”的原因。
3. 常用4个属性
a) left (左边 方向)
b) right (右边 方向)
c) both (左右 两边方向)[常用,独占一行,连浮动都休想与之共处一行]
d) none (无)
4. 例:
a) 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>浮动</title> <style> .div1{width:100px;height:100px;background:red;float:left;} .div2{width:200px;height:200px;background:blue;clear:left;} </style> </head>
<body> <div class="div1">div1</div> <div class="div2">div2</div> </body> </html> |
b) 效果
i. 不加 “clear:left;”效果如下:
ii. 添加“clear:left;”后
练习(布局)
题目:要求布局结构如下:
答:
详解
1. 第一步:分析图
a) 勾画
b) 分析结果: 一个大div盒子box , box里面包含3个中div盒子left、center和right。
2. 第二步:完成主体结构代码
a) 代码如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>练习</title> <style> </style> </head>
<body> <div class="box"> <div class="left"> <div></div> <div></div> </div> <div class="center"> <div></div> <div></div> <div></div> </div> <div class="right"> <div></div> <div></div> </div> </div> </body> </html> |
3. 第三步:添加主体样式
a) 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>练习</title> <style> body{margin:0;} .box{width:900px;margin:0 auto;} .left{width:300px;float:left;} /* ".left div"不指定宽度时,会看不到显示,因为块元素添加了浮动后,不指定宽高时,内容撑开宽高*/ .left div{height:298px;background:#9f0;border:1px solid #fff;} .center{width:300px;float:left;} .center div{height:198px;background:#9f5;border:1px solid #fff;} /* ".right"这里其实给左浮动或右浮动效果是一样的,因为刚好只剩300px了*/ .right{width:300px;float:right;} .right div{height:298px;background:#9fa;border:1px solid #fff;} </style> </head>
<body> <div class="box"> <div class="left"> <div></div> <div></div> </div> <div class="center"> <div></div> <div></div> <div></div> </div> <div class="right"> <div></div> <div></div> </div> </div> </body> </html> |
b) 效果
遗留问题
问题 : 上面“详解”中主体结构完成的很好,但是,当我们为box元素添加一个边框就可以很直观的看出现问题了。
1. 为box元素添加一个边框“border:2px solid #000;” ,修改局部代码,如下:
a) 原代码:“.box{width:900px;margin:0 auto;}”
b) 修改后:“.box{width:900px;margin:0 auto;border:2px solid #000;}”
2. 刷新效果(加边框只是为了更直观的看出问题):
3. 小结
a) 当为box元素的三个子元素添加了浮动后,box元素就没有内容来撑起高度了。
解决(第一种清浮动)
1. 为box元素添加高度,代码修改如下:
a) 原代码:“.box{width:900px;margin:0 auto;border:2px solid #000;}” 。
b) 修改后:“.box{width:900px;margin:0 auto;border:2px solid #000;height:600px;}” 。
2. 刷新效果(Ctrl + F5 快捷键可以跳过浏览器缓存)
3. 小结
a) 这种解决方法优点很简单,但缺点也很明显,就是扩展性不好,当页面中内容发生了改变,就很有可能出现错位情况,就需要再一次调整box的高度,很不方便,如果我们能使内容撑开高度,就不会出现这种问题了(下面就会讲到)。
清浮动
问题的产生
1. 例1(未添加浮动时):
a) 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>浮动</title> <style> .box{width:300px;margin:0 auto;border:10px solid #000;} .div{width:200px;height:200px;background:red;} </style> </head>
<body> <div class="box"> <div class="div"></div> </div> </body> </html> |
b) 效果
c) 小结
i. 可以看出在没有加浮动情况下,box元素的高度是完全可以被子元素撑开的。
2. 例2(添加浮动后,产生问题)
a) 为box元素的子元素添加浮动,修改“例1”代码
i. 原代码:“ .div{width:200px;height:200px;background:red;} ” 。
ii. 修改后:“.div{width:200px;height:200px;background:red;float:left;}” 。
b) 效果
c) 小结
i. 当为“box”元素的子元素“div”添加浮动后,“div”就脱离文档流浮起来了,那么这时候父级“box”元素就包不住子元素“div”了。
清浮动方法
第一种(给父元素设置高度)
1. 给父元素设置高度,上面“练习”中已经讲过,这里就不重复讲了。
第二种(给父元素也添加浮动)
1. 使父元素也浮动起来,这样就提升父元素的层级跟子元素一样了,就能包起子元素了。
2. 例:
a) 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>清浮动</title> <style> .box{width:300px;margin:0 auto;border:10px solid #000;float:left;} .div{width:200px;height:200px;background:red;float:left;} </style> </head>
<body> <div class="box"> <div class="div"></div> </div> </body> </html> |
b) 效果
c) 小结
i. 这种方式虽然解决了问题,但产生了其它问题,如下:
1. 万一“box”元素还有父元素“abox”呢,那么“abox”也需要加浮动,再万一“abox”元素还有父元素“bbox”呢,这样会造成页面中所有元素都要加浮动。
2. 父元素“box”的外边距margin左右居中失效。
ii. 所以这种方法不实用,或者说太麻烦了。
第三种(inline-block)
1. 给浮动元素的父元素添加“display:inline-block”。
2. 例:
a) 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>清浮动</title> <style> .box{width:300px;margin:0 auto;border:10px solid #000;display:inline-block;} .div{width:200px;height:200px;background:red;float:left;} </style> </head>
<body> <div class="box"> <div class="div"></div> </div> </body> </html> |
b) 效果
c) 小结
i. 给浮动元素的父元素添加“inline-block”后,效果达到,并且“inline-block”也不会使元素脱离文档流,这样就算父元素“box”还有父元素“abox”,“box”元素也可以撑开“abox”元素。
ii. 但是,这种方式缺点也是多多的,这种方式也会使“box”元素的外边距margin左右居中失效,你还需要再给“box”元素的父元素使用“text-align:center”来左右居中。
第四种(添加自定义“clear”div;IE6最小高度问题)[早些年流行]
1. 在浮动元素下面添加自定义元素“clear”和样式 (会有最小高度问题产生)
a) 元素本身:“<div class="clear"></div>” 。
b) 样式:.clear{height:0;font-size:0;clear:both;}
i. “clear:both;”表示此元素左右方向不能有浮动元素,这样会使此元素在浮动元素下一行显示,而不会被浮动元素覆盖。
ii. “font-size:0;” 可以解决IE低版本(如:IE6)中默认元素最小19像素高度的兼容性问题,其实这还并未彻底解决,这只能解决到最后2px,在后面的课程中小潘潘还会有进一步的优化方案。
2. 例:
a) 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>清浮动</title> <style> .box{width:300px;margin:0 auto;border:10px solid #000;} .div{width:200px;height:200px;background:red;float:left;} .clear{height:0;font-size:0;clear:both;} </style> </head>
<body> <div class="box"> <div class="div"></div> <!—因为clear元素并未脱离文档流,所以会撑起box元素的高--> <div class="clear"></div> </div> </body> </html> |
b) 效果
第五种(br元素的clear属性)
1. br元素有一个clear=“all”的属性功能跟样式中的 “clear:both;”相同,并且br元素本身没有高度,所以也就不会存在IE低版本下最小高度问题。
2. 只需要在浮动元素下添加一句 : <br clear=”all” />
3. 例:
a) 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>清浮动</title> <style> .box{width:300px;margin:0 auto;border:10px solid #000;} .div{width:200px;height:200px;background:red;float:left;} </style> </head>
<body> <div class="box"> <div class="div"></div> <br clear="all"/> <!—就这一句解决问题--> </div> </body> </html> |
b) 小结
i. 优点:使用非常简单,只需要在浮动元素下添加一句就搞定,没有副作用,不存在IE6等低版本的最小高度问题。
ii. 缺点:不符合w3c倡导的结构、样式、行为三者分离的要求(即相互独立,互不干扰的原则)。
1. 问题是因为一条浮动样式 “float:left;”引起的,但我们却用改变结构来解决(添加了<br clear=”all”/>结构语句),这违背了结构、样式、行为三者独立互不干扰的原则(当然,如果没有人较真也没关系的)。
第六种(使用overflow)[常见]
关于overflow
1. 当内容超出时就需要使用到overflow属性
a) 内容超出后在不同浏览器下显示效果不一样,连IE各个版本显示效果都不同,所以当内容超出时必须要用overflow属性来解决达到统一样式目的。
2. overflow常用三大属性
a) auto (溢出显示滚动条)
b) scroll (默认就显示滚动条)
c) hidden (溢出隐藏)[常用]
overflow清浮动
1. overflow在非IE6浏览器下可以包住浮动元素
2. 我们之前说元素添加了浮动后,就会脱离文档流,浮动元素的父级元素就包不住了,其实如果父级元素使用了overflow属性就可以包住浮动元素了,但是在IE6下overflow属性却是包不住的浮动元素的。
3. 例:
a) 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>清浮动</title> <style> .box{margin:0 auto;border:10px solid #000;zoom:1;overflow:auto;} .div{width:200px;height:200px;background:red;float:left;} </style> </head>
<body> <div class="box"> <div class="div"></div> </div> </body> </html> |
b) 效果
i. 标准浏览器 (”overflow:auto” 起的作用)
ii. IE6(”zoom:1” 起的作用)
4. 总结
a) 评价
i. 优点:使用简单
ii. 缺点:不适用任何情况
b) 工作中有很多人喜欢用overflow来清浮动,因为方便,但是在使用它时有时容易出错,比如下图,当鼠标移动到”我的淘宝“时弹出下面两项(即2),如果我们给1添加了”overflow:hidden”的话,那么2就会被截断。
c) 如果要用” overflow”清浮动的话,需要跟zoom一起使用。
d) 代码
兼容IE6 | 兼容IE6以外的 |
zoom:1 | overflow:auto/overflow:hidden |
e) 两个一起使用,解决所有浏览器下的清浮动
zoom:1;overflow:hidden; 或 zoom:1;overflow:auto; |
第七种(使用after伪类)[各大公司都在推荐]
关于after伪类
1. after伪类的特性:after伪类可以为一个元素追加内容。
2. IE6、IE7不支持after伪类。
3. 例:
a) 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>after伪类</title> <style>
p{width:200px;border:1px solid #000;} p:after{content:"!!!!!";width:100px;height:100px;background:red;display:block;}
</style> </head>
<body> <p>我的课堂</p> </body> </html> |
b) 效果
i. 标准浏览器
ii. IE6
c) 小结
i. after伪类追加内容非常灵活。
ii. 问题:之前我们已经学过IE6不支持除了a元素以外的所有元素的伪类,IE6以上的浏览器支持所有标签的hover伪类,所以after伪类不支持IE6。
after清浮动(上)
1. 例:
a) 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>清浮动</title> <style> .box{width:300px;margin:0 auto;border:10px solid #000;} .div{width:200px;height:200px;background:red;float:left;} .clear:after{content:"";display:block;clear:both;} </style> </head>
<body> <!-- 使用clear样式为此div追加一个没有内容的块,且块两边无浮动--> <div class="box clear"> <div class="div"></div> </div> </body> </html> |
b) 效果
i. 标准浏览器
ii. IE6/IE7
c) 小结
i. 疑问:不是说IE6和IE7不支持after伪类的吗,为什么上面IE6/IE7却也清除了浮动?
ii. 答:其实在IE6、IE7下浮动元素的父级有宽度就不用清浮动(标准浏览器不这样)。如下:
1. 例1(不清浮动,且浮动元素父级元素有宽度时):
a) 代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>清浮动</title> <style> .box{width:300px;margin:0 auto;border:10px solid #000;} .div{width:200px;height:200px;background:red;float:left;} </style> </head>
<body> <div class="box"> <div class="div"></div> </div> </body> </html> |
b) 效果
i. 标准浏览器
ii. IE6/IE7
2. 例2(去掉浮动元素父元素的宽度后):
a) 将box元素样式代码中的设置宽度去掉
i. 原代码:“.box{width:300px;margin:0 auto;border:10px solid #000;}”。
ii. 修改后:“.box{margin:0 auto;border:10px solid #000;}”。
b) 效果
i. 标准浏览器
ii. IE6/IE7
3. 小结
a) 问:为什么会出现上面的情况呢?
b) 答:是IE浏览器中的“hasLayout”搞的鬼,当一个元素使用了某些属性(如:width、height、zoom(除了normal外任意值)、等等)时,就会激发“hasLayout”属性工作(从hasLayout=”false”变为hasLayout=”true”), hasLayout一旦工作就会自动修正布局,hasLayout会根据元素内容的大小或父级的大小来重新计算元素的宽高,上面“例1”中就是浮动元素的父级元素使用了width属性从而激发了hasLayout工作,将box元素的子元素“div”的宽高(width:200px;height:200px;)作为父级box的宽高,所以不需要清浮动了。
after清浮动(下)
1. 通过上部分的分析得到结论如下:
a) .clear:after{content:"";display:block;clear:both;} 可以清除非IE6、IE7的所有浮动。
i. after伪类IE6、IE7不支持。
b) .clear{zoom:1;} 可以激发IE6、IE7的hasLayout工作,从而可以自动修正布局,所以也就不需要我们手动清浮动了。
i. zoom属性可以放大缩小元素(取值1表示原比例大小),这个属性本身有的浏览器是不兼容的(如火狐),不兼容的浏览器也不会起到任何效果(所以无害),而IE6、IE7是兼容的,刚好用它激发IE6、IE7的hasLayout工作。
c) 总结
i. 分析(可清所有浏览器下的浮动):
兼容IE6、IE7 | 兼容除了IE6、IE7以外的 |
.clear{zoom:1;} | .clear:after{content:"";display:block;clear:both;} |
ii. 两句话一起用,搞定所有浏览器下的清浮动:
.clear{zoom:1;} .clear:after{content:"";display:block;clear:both;} |