“流”
什么是“流”,我们通过一个实例来认识一下“流”。
1 2 3 4 5 6 7 8 9 10 11 12
| .div { width: 100%; height: 50px; } .div { height: 50px; }
|
流特性就像在有水的容器里面放入木块。放入一个块状元素,就会自动占满一行;放入行内元素,元素就会按照从左往右,在一行内依次排开。
浮动
css中的float属性会把元素向左或者向右浮动。浮动的初衷是为了实现文字环绕效果。float会破坏上面的流特性,让原本按照流特性布局的元素,重新按照浮动布局。
float
float属性在使用之后,元素本身的某些特性会发生更改,也会增添一些新特性。
包裹性
float元素会“收缩到合适”,这里的合适,理解为inline-block元素的特性,会自动根据子元素来定义宽和高。通常包裹性可以理解为两个方面,一个是“包裹”,一个是“自适应”。
1 2 3 4 5 6
| <div class="contain"> <div class="float"> <img src="https://fallbacks.carbonads.com/nosvn/fallbacks/731050e6bd3fc6979e1cb1a972294dae.png"> 测试文字测试文字测试文字测试文字测试文字 </div> </div>
|
1 2 3 4 5 6 7 8 9 10
| .contain { width: 200px; } .contain img { width: 150px; } .float { float: left; }
|
当我们没有上面的测试文字的时候,我们就能发现float元素的宽度为150px,这就是float元素的包裹性;当我们添加上测试文字的时候,我们就会发现float元素的宽度为200px,这就是float元素的自适应性。
查看示例
块状性
元素在使用float属性的时候,且其值不为none的时候,元素的dispaly属性会自动成为block或者table。再去定义display属性的时候就是多余的操作。
1
| <span class="float">测试文字</span>
|
1 2 3 4
| .float { float: left; display: block; }
|
我们可以在js脚本中获取这个元素然后打印出其display属性的值来验证。
查看示例
没有margin合并
这个也很好理解,多个块状元素布局的时候,上下margin会自动合并,其值取决于margin较大的值。使用浮动的时候,会发现元素的margin不会合并。
1 2 3 4 5
| <div class="margin"> <div class="box">margin-top合并</div> <div class="box">margin-top合并</div> <div class="box float">margin-top没有合并</div> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12
| .float { float: left; } .margin { margin-top:50px; height: 200px; } .box { height:20px; margin: 10px 0 20px; border: 1px dashed #999; }
|
你会发现第二个.box元素和上面的.box元素外间距为20px,而第二个和第三个.box元素的外间距为30px。
查看示例
破坏文档流
其主要表现在于,float元素会脱离文档流,导致父元素的高度坍塌。
1 2 3
| <div class="father"> <div class="block float">高度坍塌</div> </div>
|
1 2 3 4 5 6 7 8 9 10
| .father { margin-top: 20px; border: 1px solid #0f0; } .block { height: 50px; } .float { float: left; }
|
在页面中,你会发现.contain元素的父元素会出现高度坍塌。
查看示例
clear
css中有一个专门来处理float属性带来的高度坍塌等问题的属性,这个属性就是clear。官方对clear属性的解释是:“元素盒子的彼岸不能和前面的浮动元素相邻”。里面提到的前面到底是左面还是右面,这里和元素的float属性取值有关,取值为left的时候,就是左面,取值为right的时候,就是右面;还有就是clear属性并没有清楚浮动,浮动一直还在,只是改变了浮动的一些规则。关于这里面的疑问,下面例子会给出解释。
只能作用于块级元素
我们知道,利用伪元素来解决高度坍塌问题的方案,中间有一个很重要的属性,就是display属性必须设置为块级元素才能生效,也就是clear属性只有块级元素才能生效。
1 2 3
| <div class="clearb father"> <div class="block float">解决高度坍塌</div> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| .clearb::after { height: 0; content: ''; display: block; clear: both; } .father { margin-top: 20px; border: 1px solid #0f0; } .block { height: 50px; } .float { float: left; }
|
查看示例
margin-top失效
当我们前面的元素使用float的时候,当起元素使用了clear的时候,就会发现该元素的margin-top会失效。
1 2 3 4 5
| <div class="margin"> <div class="box w50 float"></div> <div class="box w50 float"></div> <div class="box w50 clearl mt"></div> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| .margin { margin-top:50px; height: 200px; } .box { height:20px; margin: 10px 0 20px; border: 1px dashed #999; } .w50 { width: 50px } .mt { margin-top: -999px; } .clearl { clear: left; }
|
查看示例
只能消除影响
因为clear属性作用的本质是让自己不和float元素在一行显示,并不是真正意义上的清除浮动。
BFC
块级格式化上下文(block formatting context ),如果一个元素具有 BFC特性,内部子元素再怎么翻江倒海,都不会影响外部的元素 。同时他也是一个结界,外面的一些影响也不会进入到该结界内部。
也就是说满足BFC特性的元素就无须使用 clear:both 属性去清除浮动对外部或者兄弟元素带来的影响了。
只要元素满足下面的任意一个条件,那么它就具有BFC特性。
- 根元素;
- float 的值不为 none;
- overflow 的值为 auto、scroll 或 hidden;
- display 的值为 table-cell、table-caption 和 inline-block 中的任何一个;
- position 的值不为 relative 和 static。
overflow
要想彻底清除浮动的影响,最合适的属性不是clear而是overflow,一般使用overflow:hidden,利用 BFC 的“结界”特性彻底解决浮动对外部或兄弟元素的影响。上述BFC特性的条件很多,但其他的属性都会让元素产生“包裹性”,会影响原来元素的样式布局。
彩蛋
这个是之前主站M端我做的一个处理。选择城市后,因为城市名字不一样,所以宽度会发生变化,会影响后端元素的宽度,怎样仅用css动态的去处理,而不是依靠js去计算。
这里我就使用了float + overflow 然后解决了这个问题。
1 2 3 4 5 6 7 8 9
| <div class="egg"> <div class="left-area">北京</div> <div class="right-area">测试文字</div> </div> <div class="egg"> <div class="left-area">呼和浩特</div> <div class="right-area">测试文字</div> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| .egg { height: 30px; line-height: 30px; margin: 20px; } .left-area { background-color: #999; height: 30px; border-radius:5px; float: left; margin-right: 10px; } .right-area { background-color: #999; height: 30px; border-radius:5px; overflow: hidden; }
|
查看示例
本文参考
《css世界》-张鑫旭著