资讯专栏INFORMATION COLUMN

【前端Talkking】CSS系列——CSS深入理解之float浮动

yankeys / 3581人阅读

摘要:包裹性所谓包裹性,其实是由包裹和自适应两部分组成。官方对属性的解释是元素盒子的边不能和前面的浮动元素相邻。清除高度塌陷的问题在上面的章节中,如果子元素设置浮动属性,则父元素就会出现高度塌陷的问题。

float属性是CSS中常用的一个属性,在实际工作中使用的非常多,如果使用不当就会出现意料之外的效果。虽然很多人说浮动会用就行、浮动过时了,但是对于优秀的前端开发人员,需要有"刨根问底"的精神,这样在出现一些问题的时候才不至于"手慌脚乱"!因此,今天就特别整理和总结一下float属性。
1. float介绍

CSS世界中的float属性是一个年代非常久远的属性,设置了float属性的元素会根据设置的属性值向左或者向右浮动,直到它的外边缘碰到包含框或另一个浮动框的边框为止。设置了float属性的元素会从普通文档流中脱离,相当于不占据任何空间,所以文档中普通流中的元素表现的就像浮动元素不存在一样,因此,设置float属性的后会影响我们的页面布局。具体说来就是:让block元素无视float元素,让inline元素像流水一样围绕着float元素实现浮动布局

float属性设计的初衷:仅仅是让文字像流水一样环绕浮动元素,就像下图中展示的一样:

2. float的特性

float有哪些有意思的特性呢?具体如下:

包裹性

高度塌陷

块状化

没有任何margin合并

下面将详细阐述这几点的含义。

2.1 包裹性

所谓"包裹性",其实是由"包裹"和"自适应"两部分组成。假设有以下CSS代码:

/* CSS代码 */
.father{
    border: 1px solid deeppink;
    width: 200px;
}
.son {
    float: left;
    font-size: 0;
    border: 1px solid blue;
    padding: 5px;
}
.father img {
    width: 128px;
}

1)包裹。本例中将浮动元素父元素宽度设置为200px,浮动元素的子元素是一个128px宽度的图片,则此时浮动元素宽度表现为"包裹",也就是里面图片的宽度128px。

/* HTML代码 */

2)自适应性。在浮动子元素的中增加一些文字:

/* HTML代码 */
美女1,美女2,美女3,美女4,美女5,美女6,后宫1,后宫2,后宫3,后宫

此时,浮动元素宽度就自适应父元素的200px宽度,最终的宽度表现也是200px。如下图所示:

2.2 高度塌陷

float属性有一个著名的特性:会让父元素的高度塌陷。如章节2.1中的效果图,父元素div的高度并没有被子元素撑开(粉色区域),这种效果可以称为"高度塌陷"。float给div.son施了个障眼法,让该元素的高度塌陷为0了,这样外层div计算高度时,认为div.son的高度为0,相当于div.son的content的高度为0,则div.father认为其没有子元素,所以产生了高度塌陷。后文中将讲述如何解决高度塌陷的问题。

2.3 块状化

块状化的意思是,一旦元素float的属性不为none,则其display计算值就是block或者table。举个例子:

/* JavaScript代码 */
var span = document.createElement("span")
document.body.appendChild(span)
console.log("1." + window.getComputedStyle(span).display)
// 设置元素左浮动
span.style.cssFloat = "left"
console.log("2." + window.getComputedStyle(span).display)

在控制台中的结果如下:

1.inline
2.block

不知道大家有没有跟我一样的疑问:既然设置float后,元素就块状化了,那么怎么还能产生包裹性的效果呢?回答这个问题,需要重新阐述下块状化的意思,这里的块状化意思是可以像block元素一样设置宽和高,并不是真正的块元素。

因此,没有任何理由出现下面的样式组合:

span{
    display: block; /* 多余 */
    float: left;
}
span{
    float: left;
    vertical-align: middle; /* 多余 */
}
2.4 没有任何的margin重叠

在这里,我们将.son类增加margin:10px样式,在浏览器中查看实际效果。

/* HTML 代码 */

我们增加.son类的margin为10px,在浏览器中查看相邻的.son元素的空白区域的高度是20px,可以发现设置了float属性的元素没有任何的margin重叠,这和普通的元素margin重叠不一样。

3. float与流体布局

使用float可以通过破坏正常的文档流实现CSS环绕,但是却带来了"高度塌陷"的问题!然而我们可以利用float破坏正常文档流的特性实现一些常用的布局:

文字环绕变身-中间内容居中,左中右布局

直接看例子:

.box{
    background-color: #f5f5f5;
}
.fl{
    float: left;
}
.fr{
    float: right;
}
.text-center{
    text-align: center;
}

从下图中看出,实现了中间内容居中的左中右布局。

文字环绕的衍生-单侧固定

美女1,美女2,美女3,美女4,美女5,美女6,后宫1,后宫2,后宫3,后宫4,后宫5,后宫6

.father{
    border: 1px solid #444;
    overflow: hidden;
}
.father > img {
    width: 60px; height: 64px;
    float: left;
}
.girl {
    /* 环绕和自适应的区别所在 */
    margin-left: 70px;
}

和文字环绕效果相比,区别就是.girl多了一个margin-left: 70px,同时图片的宽度设置60px,因此不会发生文字环绕的效果。这里,我们也可以不使用margin-left,改用border-left或者padding-left都可以达到改变content box的尺寸,从而实现宽度自适应布局效果。

4. float的克星

既然使用float属性会带来一系列的问题,那么有没有办法消除这些问题呢?答案是:肯定有。接着看下文。

4.1 clear属性

在CSS中可以使用clear来清除float属性带来高度塌陷等问题,使用格式如下:

clear: none | left | right | both

none:默认值,允许两边都有浮动对象;

left:不允许左侧有浮动对象;

right:不允许右侧有浮动对象;

both:两侧不允许有浮动对象。

如果单从字面上的意思来理解,clear:left应该是"清除左浮动",clear:right应该是"清除右浮动",实际上,这种说法是有问题的,因为浮动一直还在,并没有清除!只能清除浮动带来的影响。

官方对clear属性的解释是:"元素盒子的边不能和前面的浮动元素相邻"。注意这里的"前面的"3个字,也就是clear属性对"后面的"浮动元素是不闻不问的。clear属性只能清除元素的自身,不能影响其他的元素。接着看下面的这个例子:

/* HTML代码 */
/* CSS代码 */
.box1 {
    float: left;
    width: 100px;
    height: 60px;
    padding: 10px;
    border: 3px solid black;
    background: url("../../lib/img/mm1.png") center no-repeat;
}
.box2 {
    border: 3px solid red;
    padding:10px;
    width:100px;
    height: 60px;
    background: url("../../lib/img/mm2.jpg") center no-repeat;
}

如上图所示,box1元素为设置了左浮动,已经脱离了正常的文档流,所以box2能够在box1的底层显示。如果想让box2能够换行排列,则只需要在.box2类中增加clear:left样式即可。如下图所示:

4.2 clear属性的不足

clear属性只对块级元素有效,但是::after等伪元素默认都是内联水平,因此,在实际工作中,我们常常使用下面的代码来清除浮动带来的影响:

.clear::after{
    content: "";
    display: table;/*也可以是"block"或者是"list-item"*/
    clear: both;
}

由于clear:both作用的本质是让自己不和float元素在一行显示,并不是真正意义上的清除浮动,因此float元素有一些不好的特性依然存在,表现在:

如果clear:both元素前面的元素就是float元素,则设置margin-top无效;

/* HTML代码 */
/* CSS代码 */
.box1 {
    float: left;
    width: 100px;
    height: 60px;
    padding: 10px;
    border: 3px solid black;
    background: url("../../lib/img/mm1.png") center no-repeat;
}
.box2 {
    clear: both;
    margin-top: -20px;
    border: 3px solid red;
    padding:10px;
    width:100px;
    height: 60px;
    background: url("../../lib/img/mm2.jpg") center no-repeat;
}

在本例中,设置.box2中的margin-top没有任何的效果,如下图所示:

clear:both后面的元素依旧可能会发生文字环绕现象。

美女1,美女2,美女3,美女4,美女5,美女6,后宫1,后宫2,后宫3,后宫

我要美女1,我还要美女2
/* CSS代码 */
.father{
    border: 1px solid deeppink;
    width: 500px;
    height: 70px;
}
.father:after{
    content: "";
    display: table;
    clear: both;
}
.float{
    float: left;
}
.father img {
    width: 60px;
    height: 70px;
}

在本例中,设置clean:both来阻止浮动对后面元素的影响,但是最后的错位效果依然发生了(可以设置.father的字体大小为0,然后设置p标签的字体大小解决错误的问题)。

由此可见,clear:both只能在一定程度上消除浮动的影响,要想完美去除浮动元素的影响,借助其他的手段——BFC,接着看下文。

5. CSS世界的结界——BFC 5.1 BFC的定义

BFC全称block formatting context,中文为"块级格式化上下文"。BFC的表现原则为:如果一个元素具有BFC,那么它的内部子元素再怎么翻江倒海,都不会影响外部的元素。因此,BFC元素是不可能发生margin重叠的,另外,BFC元素也可以用来清除浮动的影响。

那么满足什么条件才会有BFC呢?只要满足下面任意一个条件就会触发BFC:

html根元素;

float的值不为none;

overflow的值为auto、scroll或者hidden;

display的值为table-cell、table-caption和inline-block中的任何一个;

position的值不为relative和static;

触发BFC后,就不需要使用clear:both属性去清除浮动的影响。

5.2 BFC的作用

清除margin重叠

/* HTML 代码 */

item 1

item 2

item 3

item 4

/* CSS 代码 */
.parent{
    width: 300px;
    background-color: black;
    overflow: hidden;
}
p {
    background-color: white;
    margin: 10px 0;
    text-align: center;
}

在这种情况下,出现了margin重叠的效果。如下图所示:

利用BFC能消除margin重叠,谨记:只有当元素在同一个BFC中时,垂直方向上的margin才会clollpase。如果它们属于不同的BFC,则不会有margin重叠。因此我们可以再建立一个BFC去阻止margin重叠的发生。所以为了让他们的margin变成20px,我们只需要用div,建立一个BFC,令p元素处于不同BFC即可。请看例子:

/* HTML代码 */

item 1

item 2

item 3

item 4

从下图中可以看出,借助BFC消除了margin重叠的问题。

清除高度塌陷的问题

在上面的章节中,如果子元素设置浮动属性,则父元素就会出现高度塌陷的问题。在这里,我们可以借助BFC消除高度塌陷的问题了,请看下面的这个例子:

/* HTML代码 */

从下图中可以看到,设置overflow:hidden样式后就产生了BFC,根据BFC的表现规则,内部元素的样式不会影响外部元素的样式,因此没有出现高度塌陷的问题。

自适应布局(阻止文本换行)

/* HTML代码 */

美女1,美女2,美女3,美女4,美女5,美女6,后宫1,后宫2,后宫3,后宫4,

/* CSS代码 */
.parent{
    border: 1px solid deeppink;
    width: 200px;
    font-size: 0;
}
.parent img{
    border: 1px solid blue;
    float: left;
}
.girl{
    /*overflow: hidden;*/
    font-size: 12px;
    background-color: #cdcdcd;
}

如果我们给.girl元素设置具有BFC特性的属性,如:overflow: hidden就可以实现更健壮、更智能的自适应布局。

这里的.girl元素为了不和浮动元素产生任何交集,顺着浮动边缘形成自己的封闭上下文。

普通元素在设置了overflow:hidden后,会自动填满容器中除了浮动元素意外的剩余空间,形成自适应效果,这种自适应布局和纯流体布局相比:

自适应内容由于封闭而更加健壮,容错性更强;

自适应内容能够填满除浮动元素以外区域,不需要关心浮动元素宽度。

6. 结语

本文是我学习float属性总结文章,可能存在理解准确的地方,欢迎大家在评论区评论,指点迷津,大家互相帮助,互相进步。

最后,希望本文的内容能够对您对float的理解能够有所帮助,感谢阅读。

参考

张鑫旭-《CSS世界》

遇见了,不妨关注下我的微信公众号「前端Talkking」

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/113141.html

相关文章

  • 前端TalkkingCSS系列——CSS深入理解relative定位

    摘要:前言在前面的两篇文章深入理解之浮动和深入理解之定位中,介绍了和的特性和使用方法,如果大家仔细阅读完了这两篇文章,相信你的打怪技能又提高的一大截,那么趁着自己最近状态不错,就多给大家分享点自己平时所学的技能。 1.前言 在前面的两篇文章:CSS深入理解之float浮动和CSS深入理解之absolute定位中,介绍了float和absolute的特性和使用方法,如果大家仔细阅读完了这两篇文...

    魏宪会 评论0 收藏0
  • 前端TalkkingCSS系列——CSS深入理解line-height

    摘要:按照定义来解释,就是两行文字之间基线之间的距离。了解完基线的定义后,我们接着来聊行高。上面我们说过,行高就是两条基线的之间的距离,如下图所示。 1.写在前面 两个多周的时间没有写文章了,手好痒好痒,趁着公司在装修,从上周末到本周都在家办公,同时公司的项目并不紧急,于是抽着时间梳理了一下CSS中关于行高line-height的理解,今天发布出来,大家准备好了吗? 2.基本概念 2.1行高...

    peixn 评论0 收藏0
  • 前端TalkkingCSS系列-css3box-shadow介绍

    摘要:基本上就是将单侧投影中的技巧运用两次,以如下所示在浏览器中的效果如下模拟边框使用属性可以模拟的效果,以如下所示在浏览器中的效果如下我们可以看到利用属性模拟了的效果,但是与不同的是,使用创建的边框效果并不会影响元素的尺寸。 1.写在前面 在CSS3中,可以使用box-shadow属性来创建阴影效果来给二维平面增加深度效果,这个属性在前端开发中使用的非常多,例如segmentfault的首...

    jackzou 评论0 收藏0
  • 前端TalkkingCSS系列-红月亮、蓝月亮、X月亮,还是渐变月亮好

    摘要:写在前面这两天,大家一定是被红月亮刷屏了吧我们都被下面漂亮的月亮迷倒了吧哈哈,大家清醒清醒,那么漂亮的月亮,大家有没有想过我们的可以搞定任意颜色的月亮呢答案是肯定可以的。 1.写在前面 这两天,大家一定是被红月亮刷屏了吧?我们都被下面漂亮的月亮迷倒了吧?showImg(https://segmentfault.com/img/bV21NB?w=102&h=101); 哈哈,大家清醒清醒...

    JinB 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<