整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

CSS 浮动布局实例

实文章原名叫做 “碰到不支持 flex 的项目怎么办?”

现在差不多已经是 flex 的天下了,简单灵活,但有时还是不可避免地会接触到 IE 浏览器,比如我最近接触的 阅文作家专区 (qq.com)[1],这个就是需要兼容 IE9, 也自然不能使用 flex 布局了。不能使用 flex 怎么办(这个项目怎么这么XX,都 2021 年了还要兼容 IE)?那只能回归传统布局方式了,也就是浮动布局。

浮动 float 可以说是 CSS 布局里最为灵活的布局之一了,千万不要小瞧了浮动,有些布局只有浮动才能实现呢。下面将介绍几种常见的布局,一起看看吧

一、文本环绕布局

这类布局应该就是浮动最初的用意了,比如这样的

设置一个左浮动就可以了,实现如下

<div>
  <strong class="float">浮</strong>
  <p>动属性指定一个元素应沿其容器的左侧或右侧放置,允许文本和内联元素环绕它。该元素从网页的正常流动(文档流)中移除,尽管仍然保持部分的流动性。</p>
</div>
.float{
  float: left;
  /*其他样式*/
}

完整代码可访问 float-layout (codepen.io)[2]

需要注意的是,浮动元素必须放在文本的前面( HTML 结构),如果放在文本后面

<div>
  <p>动属性指定一个元素应沿其容器的左侧或右侧放置,允许文本和内联元素环绕它。该元素从网页的正常流动(文档流)中移除,尽管仍然保持部分的流动性。</p>
  <strong class="float">浮</strong>
</div>

那么就会变成这样

也就是说,浮动的影响范围是由浮动元素在 HTML 中的结构决定的,这一点非常重要

不过,现在很少会见到这种环绕布局了,但有些时候这种思路还是挺有用的,比如在这篇文章 CSS 实现多行文本“展开收起” (juejin.cn)[3],里面就用到了浮动的特性,实现了右下角文本环绕的效果,有兴趣的可以看看

二、两栏布局

两栏布局的特点是左边是固定尺寸,右边自动撑满剩余空间,例如

结构如下

<div class="crad">
  <img class="head" src="xxx.jpg">
  <p class="info">浮动属性指定一个元素应沿其容器的左侧或右侧放置,允许文本和内联元素环绕它。该元素从网页的正常流动(文档流)中移除,尽管仍然保持部分的流动性。</p>
</div>

浮动实现如下,主要是文本需要设置 overflow: hidden 。这里就不谈实现原理(BFC)了,有兴趣深究的可以查看这篇文章 CSS深入理解流体特性和BFC特性下多栏自适应布局[4]

.head{
  float: left;
}
.info{
  overflow: hidden;
}

如果右边是固定尺寸,比如这样的

这种情况如何处理呢?很多人可能会想到右浮动,没错,但是要注意,HTML 结构不需要改动,也就是浮动元素仍然在文本的前面

.head{
  float: right;
}

值得注意的是,如果需要设置两栏的间距 margin,需要设置在浮动元素

.head{
  float: left;
  margin-right: 8px;
}

完整代码可访问 float-2-cols[5]

三、三栏布局

三栏布局的特点是左右是固定尺寸,中间自动撑满剩余空间,例如

结构如下

<div>
  <img class="head" src="xxx.jpg">
  <div class="right">编辑</div><!--注意是在文本的前面-->
  <p class="info">浮动属性指定一个元素应沿其容器的左侧或右侧放置,允许文本和内联元素环绕它。该元素从网页的正常流动(文档流)中移除,尽管仍然保持部分的流动性。</p>
</div>

注意,这里位于右侧的按钮在 HTML 结构中仍然是在文本的前方,只需要设置右浮动就行了

.head{  
  float: left;
}
.info{  
  overflow: hidden;
}
.right{  
  float: right;  
  margin-left: 8px;  /*其他样式*/
}

完整代码可访问 float-3-cols (codepen.io)[6]

四、文本省略跟随布局

还有一类比较常见但是有些棘手的布局,是这样的

1.当文本比较多时,超出隐藏,标签文本在最右边2.当文本比较少时,标签文本跟随文本

示意如下

这里如何使用浮动实现呢?仔细观察,其实就是一个两栏布局

<div class="card">    
  <div class="right">编辑</div>  
	<p class="info">浮动属性指定一个元素应沿其容器的左侧或右侧放置,允许文本和内联元素环绕它。该元素从网页的正常流动(文档流)中移除,尽管仍然保持部分的流动性。一直平移直到碰到了所处的容器的边框,或者碰到另外一个浮动的元素。</p>
</div>
.info{  
  overflow: hidden;  
  white-space: nowrap;  
  text-overflow: ellipsis;
}

很明显现在标签文本一直位于右边,那如何实现标签文本跟随的效果呢?其实可以嵌套一个最大宽度为 100% 的容器

<div class="card">  
  <div class="wrap"> <!--添加一个最大宽度为100%的容器-->        
    <div class="right">标签</div>        
		<p class="info">浮动属性指定一个元素应沿其容器的左侧或右侧放置,允许文本和内联元素环绕它。该元素从网页的正常流动(文档流)中移除,尽管仍然保持部分的流动性。一直平移直到碰到了所处的容器的边框,或者碰到另外一个浮动的元素。</p>  
	</div>
</div>
.wrap{  
  display: inline-block;  
  max-width: 100%;
}

完整代码可访问 float-auto-text (codepen.io)[7]

如果不考虑兼容的话,width: fit-content 会是更好的选择,可以使容器保持 block 的特性,并且宽度由文本内容决定,详细可以参考这篇文章: 理解CSS3 max/min-content及fit-content等width值 [8]

.wrap{  
  /*display: inline-block;*/  
  max-width: 100%;  
  width: fit-content;
}

另外,如果多行文本就不适用了,可以用另一种方式实现,详细原理可以查看这篇文章 CSS 实现多行文本“展开收起” (juejin.cn)[9]

完整代码可访问float-mul-tags (codepen.io)[10]

五、其他扩展布局

这一部分相当于以上的扩展了,下面来看一个案例。

有时候标签的后面会有日期,会一直位于最右边,效果如下

有人可能会想到绝对定位,但是这里的日期可能不是固定的,需要自适应宽度,那如何实现呢?其实就是就是两种布局的结合

因此需要再添加一层容器,实现如下

<div class="card">    
  <span class="date">6-14</span>    
	<div class="outer-wrap"> 
  	<!--新加一层容器-->        
  	<div class="wrap">            
    	<div class="right">                
      	<button class="btn">标签</button>            
			</div>            
			<p class="info">浮动属性指定一个元素应沿其容器的左侧或右侧放置,允许文本和内联元素环绕它。该元素从网页的正常流动(文档流)中移除,尽管仍然保持部分的流动性。一直平移直到碰到了所处的容器的边框,或者碰到另外一个浮动的元素。</p>    
		</div>  
	</div>
</div>

下面就是两栏布局的写法

.date{  
  float: right;
}
.outer-wrap{ 
  overflow: hidden;
}

提示:如果采用 fit-content 方式,可以省去 .outer-wrap 这一层容器

实时效果如下

完整代码可访问 float-auto-text-fixed (codepen.io)[11]

六、总结和说明

上面介绍了浮动布局的几个常用案例,相信能适用于绝大部分布局,当然并不是推荐大家一定要使用浮动布局,甚至有时候布局混乱(HTML结构与视觉不一致)、实现啰嗦(嵌套层级多)等情况,但是在不兼容 flex 布局的浏览器中还是挺有用的(低于IE10),甚至还有仅仅只能使用浮动才能实现的布局(文本环绕)。这里总结如下

1.通过 BFC 实现自适应弹性布局,float + overflow2.浮动的影响范围是由浮动元素在 HTML 中的结构决定的3.通过设置最大宽度实现文本跟随效果(fit-content也可以)4.其他布局可相互组合实现5.另外这些 float 实现方式全兼容(IE6+),可以放心使用

随着 IE 地逐渐退去,有些布局也会慢慢地淡出,就像早年的 table 布局一样。但浮动布局一直在往新特性上发展,比如 Shapes 布局[12]就需要浮动做支持,另外,浮动布局也在慢慢支持逻辑属性,比如 float: inline-start 。最后,CSS 最重要的是灵活性,多一种思路总是没错的。如果觉得还不错,对你有帮助的话,欢迎点赞、收藏、转发❤❤❤

References

[1] 阅文作家专区 (qq.com): https://write.qq.com/
[2] float-layout (codepen.io):
https://codepen.io/xboxyan/pen/RwpqWvJ
[3] CSS 实现多行文本“展开收起” (juejin.cn):
https://juejin.cn/post/6963904955262435336
[4] CSS深入理解流体特性和BFC特性下多栏自适应布局:
https://www.zhangxinxu.com/wordpress/2015/02/css-deep-understand-flow-bfc-column-two-auto-layout/
[5] float-2-cols:
https://codepen.io/xboxyan/pen/WNpYQLB
[6] float-3-cols (codepen.io):
https://codepen.io/xboxyan/pen/oNZQLWB
[7] float-auto-text (codepen.io):
https://codepen.io/xboxyan/pen/poeQbYo
[8] 理解CSS3 max/min-content及fit-content等width值 :
https://www.zhangxinxu.com/wordpress/2016/05/css3-width-max-contnet-min-content-fit-content/
[9] CSS 实现多行文本“展开收起” (juejin.cn):
https://juejin.cn/post/6963904955262435336
[10] float-mul-tags (codepen.io):
https://codepen.io/xboxyan/pen/PopWVNX
[11] float-auto-text-fixed (codepen.io):
https://codepen.io/xboxyan/pen/WNpYJpN
[12] Shapes 布局:
https://www.zhangxinxu.com/wordpress/2019/02/css-css3-shapes

准流的默认特性

1、分行、块级元素,并且能够dispay转换。

2、块级元素(block):默认独占一行,不能并列显示,能够设置宽、高,宽度为父盒子的100%。例如:div、p、标题元素(h1-h6)、列表元素(ul li、dl dt dd)

3、行内元素(inline):默认并排显示,不能设置宽、高,宽度为内容的宽度。例如:span、a、b、i

4、margin-bottom 和margin-top 塌陷,以最大值为准。

脱标的元素的特性

只要是脱离了标准流,元素都是不区分行、块的,体现在任何元素都可以设置宽、高了。都有了收缩的 性质,就是不设置宽度,就自动缩减为里面内容的宽度。

浮动的元素有贴边的性质,绝对定位的元素可以自由定位。

1.盒子的浮动(float 属性):

在标准流中,一个块级元素在水平方向会自动伸展,直到包含它的元素的边界;在竖直方向和兄弟元素一次排列。不能并排。

CSS的float属性默认为none,将float属性设置为left或者right后,元素会向其父元素的左侧或右侧紧靠,同时默认情况下,盒子的宽度不再伸展,而是根据盒子里面的内容的宽度来确定。 脱离了标准文件流。(但是,本显示会占据一定的空间)。

这样未填满的部分就会进行填充。 为了消除影响,不让后面的元素因为浮动产生的这些空间进行填充,使用clear属性进行消除浮动对后面的元素造成的影响:

clear 属性:

clear属性除了可以设置right、left 也可以设置为both,表示同时消除左右两边的影响。

clear属性设置要放到 float 之后的 要消除float影响的兄弟div里面,而不是float本身所在的div。

设置上clear之后,该div会把前面设置float的div 当做块级div来看待。

使用示例:

因为浮动的元素都不在标准流里,如果盒子内部元素都是浮动元素,父级div 缩成一条。

解决方法,在后面加一个空div 并清除 浮动影响.

高度消失后,父级将只保留margin和border的高度,与父级平行的div 将会紧挨着父级显示,显示漂浮的内容 会占据空间,后面div内容 会依次紧挨着漂浮的内容显示。

脱离了标准流,但内容显示上 会被其他元素包围。(其他元素可以“趁空而入”)

浮动可以使块级元素并排显示,用于页面布局。

2.盒子的定位(position):

static (标准流中默认)

盒子按照标准流(包括浮动方式)进行布局。

relative (位于标准流中):

以标准流的排版方式为基础,然后使盒子相对于它在原本的的标准位置偏移指定的距离。相对定位的盒子,仍在标准流中,它后面的盒子仍以标准流方式对待它。

只要标识该div position:relative ;使用 top left 等属性 可以设置偏移量,与父级元素的定位方式无关。

总结:

1.使用相对定位的盒子仍在标准流中,它对付款和兄弟盒子没有任何影响。

2.使用相对定位的菏泽仍在标准流中,它对父块和兄弟盒子没有任何影响。

对浮动的盒子使用相对于定位 也是一样的

absolute (非标准流)

绝对定位,盒子位置以它的包含框为基准进行偏移,绝对定位的盒子从标准流中脱离,其他盒子就当这个盒子不存在一样。

设置position后:div 脱离标准流,宽度自动按内容宽度,覆盖在后面的元素之上。

设置top,left等属性:

top:5px;

跑出了父级的div ,

把father div块 设置成相对定位:

1.使用绝对定位的盒子 以它的”最近“的一个”已经定位“的祖先元素 为基准进行偏移,如果没有定位定位的祖先元素, 那会以浏览器窗口进行定位。

已经定位:position 属性被设置,且被设置的不是 static的任意一种方式。

最近,离该节点最近的一个已经定位的节点。

2.绝对定位的框从标准流中脱离,这意味着对其后兄弟盒子的定位没有影响,其他盒子就好像这个盒子不存在一样。

通过实验可知道:

如果设置了绝对定位,而没有设置偏移属性,那么它仍将保持原来的位置,这个性质可以用于需要使某个元素脱离标准流,而仍然希望保持原来的位置的情况。

fixed (以窗口为基准)

固定定位,基准不是祖先元素 而是浏览器窗口 或者其他县市设备的窗口。

z-index:

当块被设置了position属性时,该值便可设置各块之间的重叠高低关系,默认z-index值为0

盒子的display属性:

none :此元素不会被显示。

block:显示为块级元素,前后会带有换行符。

inline:默认 此元素被显示为内联元素,元素前后没有换行符。

list-item:作为列表显示

图书推荐:大家可以参考《CSS彻底研究》来进行学习,如需相关资料请留言!

动的目的:把多个盒子放在一行上

清除浮动的目的:解决父盒子高度为0的问题

清除浮动,也称闭合浮动

注:本文不兼容IE6

未清除浮动实现情况:

图1

清除后:

图2

原代码:

复制代码

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>清除浮动</title>

<style type="text/css">

.content{

width:960px;

margin:100px auto;

border: 1px solid #ccc;

}

.left{

width:400px;

height: 200px;

background-color: green;

float: left;

}

.right{

width: 400px;

height: 200px;

background-color: red;

float: right;

}

</style>

</head>

<body>

<div class="content">

<div class="left"></div>

<div class="right"></div>

</div>

</body>

</html>

复制代码

具体方法:

1.额外标签法

在含浮动标签后加兄弟盒子清除浮动

例:

复制代码

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>清除浮动</title>

<style type="text/css">

.content{

width:960px;

margin:100px auto;

border: 1px solid #ccc;

}

.left{

width:400px;

height: 200px;

background-color: green;

float: left;

}

.right{

width: 400px;

height: 200px;

background-color: red;

float: right;

}

.clearbox{

clear:both;

}

</style>

</head>

<body>

<div class="content">

<div class="left"></div>

<div class="right"></div>

<div class="clearbox"></div>

</div>

</body>

</html>

复制代码

缺点:添加了许多空div

2.给父盒子overflow:hidden

触发bfc模式(该名词不懂请谷歌/百度,初学者可暂时略过),直接清除浮动

复制代码

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>清除浮动</title>

<style type="text/css">

.content{

width:960px;

margin:100px auto;

border: 1px solid #ccc;

overflow: hidden;

}

.left{

width:400px;

height: 200px;

background-color: green;

float: left;

}

.right{

width: 400px;

height: 200px;

background-color: red;

float: right;

}

.clearbox{

clear:both;

}

</style>

</head>

<body>

<div class="content">

<div class="left"></div>

<div class="right"></div>

</div>

</body>

</html>

复制代码

缺点:不可与position属性配合使用

3.伪元素法

给父元素定义伪类:after(此处使用的是公共类clearfix)

复制代码

.clearfix:after{

content:"";/*内容为空*/

visibility:hidden;/*将元素隐藏,但是在网页中该占的位置还是占着*/

display:block;/*变成块级元素*/

height:0;

clear:both;/*清除浮动*/

}

复制代码

具体代码:

复制代码

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>清除浮动</title>

<style type="text/css">

.clearfix:after{

content:"";/*内容为空*/

visibility:hidden;/*将元素隐藏,但是在网页中该占的位置还是占着*/

display:block;/*变成块级元素*/

height:0;

clear:both;/*清除浮动*/

}

.content{

width:960px;

margin:100px auto;

border: 1px solid #ccc;

}

.left{

width:400px;

height: 200px;

background-color: green;

float: left;

}

.right{

width: 400px;

height: 200px;

background-color: red;

float: right;

}

.clearbox{

clear:both;

}

</style>

</head>

<body>

<div class="content clearfix">

<div class="left"></div>

<div class="right"></div>

</div>

</body>

</html>

复制代码

缺点:IE8以上和非IE浏览器才支持

4.双伪元素法

给父类加上伪类:before和:after

复制代码

.clearfix:before,.clearfix:after{

content:"";

display:table;

}

.clearfix:after{

clear:both;

}

复制代码

具体代码:

复制代码

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>清除浮动</title>

<style type="text/css">

.clearfix:before,.clearfix:after{

content:"";

display:table;

}

.clearfix:after{

clear:both;

}

.content{

width:960px;

margin:100px auto;

border: 1px solid #ccc;

}

.left{

width:400px;

height: 200px;

background-color: green;

float: left;

}

.right{

width: 400px;

height: 200px;

background-color: red;

float: right;

}

.clearbox{

clear:both;

}

</style>

</head>

<body>

<div class="content clearfix">

<div class="left"></div>

<div class="right"></div>

</div>

</body>

</html>

复制代码

附:

对于上述4种方法,优先推荐方法3和4,当然1和2也可,可根据具体情况使用。

还有几种乱七八糟的清除浮动方法,但是缺点多,故不提起.

最后你觉得我们的文章对你有帮助,欢迎关注我,可以私信我:久伴,领取学习资料,在评论下方可以关注我的学习群,你可以随时在上面向我们提问,把你在学习前端过程中所遇到的问题发给我们。我们每天都会按时回复大家的每一个问题,希望久伴可以伴随你从入门到专家。