CSS布局

本文深入解析CSS中的浮动布局,涵盖浮动的基本概念、破坏性和包裹性特点,以及多种两栏和三栏布局技巧,如双inline-block、双float、float+margin-left、float+BFC、flex布局、圣杯布局和双飞翼布局。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    布局中会涉及到两个CSS知识:浮动、定位。这里详细说说关于浮动方面的知识。

    首先要知道,浮动设计的初衷是为了实现文字环绕图片的效果。所以元素浮动后表现出的一些特性与这个实现目的是有密切关系的。

1.浮动的一些特性

1.1 破坏性

    看看下面的Demo:

<div style="border:1px solid;">
		<img src="./tb_index/images/1.png" alt="" style="width: 100px; height:100px; float:left">	
	</div>

当img设置为浮动后,父标签div发生了“坍塌”。这是因为当某一元素发生浮动时,它就脱离了文档流。普通文本流中的父标签就看不到它。此时div没被任何元素撑起来,所以就发生了“坍塌”。当然,它并非是完全脱离文档流(像绝对定位这种的就是完全脱离了文档流),因为文字是能够看到浮动元素的。

    为什么float被设计成具有破坏性?比较下面的图片就能明白了:

  

让父元素塌陷就是为了实现文字环绕图片的效果。

1.2 包裹性

    如下Demo:

<div style="border:1px solid; float:left;">
		娃哈哈哈哈哈哈哈哈哈哈哈哈哈哈	
	</div>

块级元素默认会占满整个屏幕宽度。当把一个块级元素设置为浮动时,他就变得紧凑了起来了,把内容紧紧地包裹起来,这个就是浮动元素的包裹性。是不是很像inline-block?注意!!!仅仅是表现上像inline-block而已,其实在DOM中它的display仍然为block.

    为什么设计成这样?还是那句话--为了实现文字环绕。上面说的是文字环绕文字,如果是文字环绕div呢?此时如果div不包裹起来,外面的文字怎么实现环绕呢?

2.CSS布局之两栏布局

2.1 双inline-block

<div class="main">
	<div class="left">left</div>
	<div class="right">right</div>
</div>
.main{
	border:1px solid;
	width: 100%;
	font-size: 0; /*去掉两个inline-block之间的空格 */
}
.left{
	display:inline-block;
	box-sizing: border-box;
	width: 100px;
	height: 100px;
	font-size:14px;
	vertical-align: top; /*顶端对齐*/
	background-color:blue;
}
.right{
	display:inline-block;
	box-sizing: border-box;
	width: calc(100% - 100px);
	height: 100px;
	font-size: 14px;
	vertical-align: top;
	background-color:green;
}

缺点:

  • 需要计算左栏的高度,如果栏与栏之间有距离,还要算上间隔,且需要设置box-sizing。
  • 需要设置顶端对齐。
  • 需要消除空格的影响。

2.2 双float

    相对于双inline-block方法,双float方法不需要消除空格的影响,也不需要设置顶端对齐。

.main{
	width: 100%;
	overflow: hidden;
	border: 1px solid;
}

.left{
	float: left;
	box-sizing: border-box;
	width: 100px;
	height: 100px;
	background-color:blue;
}
.right{
	float: left;
	box-sizing: border-box;
	width: calc(100% - 100px);
	height: 100px;
	background-color:green;
}

缺点:

  • 还是得需要计算左栏和两栏距离的大小。
  • 父元素需要包含浮动,否则会发生“坍塌”。

2.3 float+margin-left

    上面的两种方法中,右栏是通过css的calc的函数来指定宽度从而实现流动特性的。之所以需要借助calc,是因为浮动元素和inline-block元素是具有包裹性的,在不指定width的情况下,它们会紧紧地包裹住内容。这里的实现是通过block元素默认填充满父元素的特点来实现流动特性的。如下:

.main{
	width: 100%;
	overflow: hidden;
	border: 1px solid;
}

.left{
	float: left;
	box-sizing: border-box;
	width: 100px;
	height: 100px;
	background-color:blue;
}
.right{
	box-sizing: border-box;
	margin-left: 100px;
	height: 100px;
	background-color:green;
}

缺点:

  • 还是得计算做栏的宽度和两栏之间的距离。
  • 外层div需要包含浮动元素。

2.4 float+BFC

    块元素是看不见浮动元素的,上例中如果不给右栏设置margin-left,右栏就会有一部分与浮动元素发生重叠。此例中通过overflow:hidden触发右栏的BFC,具有BFC的元素不会与浮动元素发生重叠。代码如下:

.main{
	width: 100%;
	overflow: hidden;
	border: 1px solid;
}

.left{
	float: left;
	box-sizing: border-box;
	margin-right: 20px;
	width: 100px;
	height: 100px;
	background-color:blue;
}
.right{
	overflow: hidden; /*触发BFC*/
	box-sizing: border-box;
	height: 100px;
	background-color:green;
}

需要注意的是:假如两栏有20px的距离,那么通过给浮动的左栏设置:margin-right:20px即可。通过给右栏设置:margin-left:20px是无法实现效果的(需要设置:margin-left:120px才能生效,也就是说还得计算左栏的宽度)。

缺点:

  • 需要包含浮动元素

2.5 flex

    如果不考虑那些老掉牙的浏览器(IE6等)的兼容性的话,flex布局还是挺好用的。如下:

.main{
	display: flex;
}

.left{
	flex: 0 0 100px;	
	background-color:blue;
}
.right{
	flex: 1 1 auto;
	background-color:green;
}

3.三栏布局

3.1 圣杯布局

    圣杯布局中左右两栏宽度固定,中间宽度自适应,俗称固比固。实现方法是:通过给外层容器container设置左右padding来给左右两栏空出位置,给left、right和main三栏设置浮动,通过负的margin将左右两栏拉到与main栏同一行,最后通过相对定位将左右两栏定位到padding的位置上。

<div class="container">
		<div class="main">main</div>
		<div class="left">left</div>
		<div class="right">right</div>
	</div>
body{
	min-width: 600px;
}

.container {
	padding: 0 200px;
}

.main {
	float: left;
	width: 100%;
	height: 100px;
	background-color: blue;
}

.left {
	position: relative;
	float: left;
	right: 200px;
	margin-left: -100%;
	width: 200px;
	height: 100px;
	background-color: yellow;
}

.right {
        position: relative;
        float: left;
        left: 200px;
        margin-left: -200px;
        width: 200px;
        height: 100px;
        background-color: green;
}

圣杯布局中需要注意的点:

  • 不要给容器.container指定宽度(min-xxx和max-xxx不算)。
  • .left和.main中的100%宽度参考的是.container的宽度,而且是除了padding外的宽度。
  • 当浏览器窗口缩小到600以下时,此时.main栏小于.left栏,会导致布局断行。需要给body指定一个最小宽度min-width:600px(也可以给.container指定最小宽度min-width: 200px)。

3.2 双飞翼布局

    与圣杯布局一样,都是为了实现固比固布局,都是通过负margin将左右两栏拉到与main相同一行。不同之处在于:圣杯是通过三栏的容器.container中的padding来为左右两栏腾出空间,而双飞翼布局中需要给main套一层div,也就是下面代码中的main-wrap,且main-wrap设置浮动。之后通过里层的main设置margin-left和margin-right来为两栏腾出空间。

<body>
	<div class="main-wrap">
		<div class="main">main</div>
	</div>
		<div class="left">left</div>
		<div class="right">right</div>
</body>
.main-wrap {
	float:left;
	width:100%;
}

.main {
	margin-left: 200px;
	margin-right: 200px;
	height: 100px;
	background-color: blue;
}

.left {
	float: left;
	margin-left: -100%;
	width: 200px;
	height: 100px;
	background-color: yellow;
}

.right {
	float: left;
	margin-left: -200px;
	width: 200px;
	height: 100px;
	background-color: green;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值