实现三栏布局的十种方式

本文节选自我的博客:实现三栏布局的十种方式

  • 💖 作者简介:大家好,我是MilesChen,偏前端的全栈开发者。
  • 📝 CSDN主页:爱吃糖的猫🔥
  • 📣 我的博客:爱吃糖的猫
  • 📚 Github主页: MilesChen
  • 🎉 支持我:点赞👍+收藏⭐️+留言📝
  • 💬介绍:The mixture of WEB+DeepLearning+Iot+anything🍁

前言

实现三栏布局也是一道经典的面试题,如果你能侃侃而谈这十种实现三栏布局的方式,一定会令面试官眼前一亮。三栏布局即左右固定中间伸缩,将三栏布局的方式按照中间栏的渲染顺序可以分为三种:float实现的三种(中间栏最后渲染),flex、grid、绝对定位实现的三种(中间栏中间渲染),双飞翼圣杯实现的四种(中间栏最后渲染)

float实现的三种

float实现的方式优点是兼容性好;缺点是需要将中间栏放在最后渲染,网速慢的情况下可能会影响用户体验。

float+BFC

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width" />
		<title>CSS实现三栏布局</title>
		<style type="text/css">
            /* 方法1 浮动+BFC 左右元素固定宽度,向左右浮动 中间元素不设置宽度,会自动撑满,重叠问题可使用构造BFC解决 */
            /* 注意HTML标签中需要将 中间元素放在最后显示,这会导致问题,中间内容后显示 */
            .left{
                float: left;
                width: 100px;
                background-color: aqua;
            }
            .middle{
                overflow: hidden;
                height: 200px;
                background-color: green;
            }
            .right{
                float: right;
                width: 100px;
                background-color: aqua;
            }
		</style>
	</head>
	<body>
		<div class="container">
			<div class="left">左栏</div>
			<div class="right">右栏</div>
            <div class="middle">中间栏</div>
		</div>
	</body>
</html>

float+margin

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width" />
		<title>CSS实现三栏布局</title>
		<style type="text/css">
            /* 方法2 浮动+margin 和两栏比较法二很像,左右元素固定宽度,向左右浮动 中间元素不设置宽度,会自动撑满,重叠问题可使用margin解决 */
            /* 注意HTML标签中需要将 中间元素放在最后显示,这会导致问题,中间内容后显示 */
            .left{
                float: left;
                width: 100px;
                background-color: aqua;
            }
            .middle{
                margin:0 100px;
                height: 200px;
                background-color: green;
            }
            .right{
                float: right;
                width: 100px;
                background-color: aqua;
            }
		</style>
	</head>
	<body>
		<div class="container">
			<div class="left">左栏</div>
			<div class="right">右栏</div>
            <div class="middle">中间栏</div>
		</div>
	</body>
</html>

float+calc()

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width" />
		<title>CSS实现三栏布局</title>
		<style type="text/css">
            /* 方法3 浮动+calc() 先使用浮动将三栏水平排列,然后对中间栏使用calc()函数来计算去除左右两栏固定宽度后剩余的宽度。*/
            div {
                height: 100px;
            }
            .left {
                float: left;
                width: 200px;
                background-color: red;
            }
            .middle {
                float: left;
                width: calc(100% - 400px);
                background-color: green;
            }
            .right {
                float: right;
                width: 200px;
                background-color: blue;
            }
		</style>
	</head>
	<body>
		<div class="container">
			<div class="left">左栏</div>
			<div class="right">右栏</div>
			<div class="middle">中间栏</div>
		</div>
	</body>
</html>

flex、grid、绝对定位实现的三种

这三种方式都是将中间栏放在中间渲染。

flex

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width" />
		<title>CSS实现三栏布局</title>
		<style type="text/css">
            /* 方法4 flex 直接给中间设置flex 1 左右固定宽度 */
            /* 优点是特别简单 缺点是依赖flex的兼容性 */
			.container {
				display: flex;
			}
			.left {
				width: 200px;
				height: 200px;
				background: red;
			}
			.middle {
				height: 200px;
				background: yellow;
				flex: 1;
			}
			.right {
				width: 200px;
				height: 200px;
				background: blue;
			}
		</style>
	</head>
	<body>
		<div class="container">
			<div class="left">左栏</div>
            <div class="middle">中间栏</div>
			<div class="right">右栏</div>
		</div>
	</body>
</html>

grid

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width" />
		<title>CSS实现三栏布局</title>
		<style type="text/css">
            /* 方法5 网格 利用grid布局的方式,左右两栏设置固定宽度,中间一栏设置为auto*/
            /* 核心代码:grid-template-columns 左栏固定宽度 中间自适应宽度 右栏固定宽度*/
            div {
                height: 100px;
            }
            .container {
                display: grid;
                grid-template-columns: 200px auto 200px;
            }
            .left {
                background: red;
            }
            .middle {
                background: green;
            }
            .right {
                background: blue;
            }
		</style>
	</head>
	<body>
		<div class="container">
			<div class="left">左栏</div>
            <div class="middle">中间栏</div>
			<div class="right">右栏</div>
		</div>
	</body>
</html>

绝对定位

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width" />
		<title>CSS实现三栏布局</title>
		<style type="text/css">
            /* 方法6 子绝父相:三栏全部绝对定位;中间栏left: 200px;right: 200px;保持伸缩居中 */
            .container {
                position: relative;
            }
            .left {
                position: absolute;
                left: 0;
                width: 200px;
                background-color: red;
            }
            .middle {
                position: absolute;
                left: 200px;
                right: 200px;
                background-color: green;
            }
            .right {
                position: absolute;
                right: 0;
                width: 200px;
                background-color: blue;
            }
		</style>
	</head>
	<body>
		<div class="container">
			<div class="left">左栏</div>
            <div class="middle">中间栏</div>
			<div class="right">右栏</div>
		</div>
	</body>
</html>

双飞翼圣杯实现的四种

这四种方式都是将中间栏放在最前面渲染,保证中间栏最先渲染。

felx实现圣杯双飞翼效果

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width" />
		<title>CSS实现三栏布局</title>
		<style type="text/css">
            /* 方法7:使用flex实现圣杯、双飞翼的效果, 使用 order 调整flex顺序  使中间块最先加载*/
            .container {
                display: flex;
            }
            .middle {
                flex: 1;
                background-color: red;
            }
            .left {
                width: 200px;
                order: -1;
                background-color: aqua;
            }
            .right {
                width: 200px;
                order: 1;
                background-color: bisque;
            }
		</style>
	</head>
	<body>
		<div class="container">
			<div class="left">左栏</div>
			<div class="right">右栏</div>
            <div class="middle">中间栏</div>
		</div>
	</body>
</html>

圣杯布局

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS实现三栏布局</title>
    <style>
         * {
            margin: 0;
            padding: 0;
        }
        /* 给container栏添加padding,左右栏使用相对定位移上去。利用浮动,外边距负值和相对定位来实现。 */
        .container {
            height: 100px;
            padding: 0 200px;
        }
        .middle,.left,.right{
            float: left;
            height: 100%;
        }
        .middle {
            width: 100%;
            background: rgb(100, 105, 100);
        }
        .left {
            position: relative;
            width: 200px;
            background: pink;
            left: -200px;
            /* float后的元素可以使用 margin-left: -100%; 切换到上一行起始位置*/
            margin-left: -100%;
        }
        .right {
            position: relative;
            width: 200px;
            background: pink;
            /* 第一种写法 */
            margin-left: -200px;
            left:200px;
            /* 第二中写法 */
            /* margin-right: -200px; */
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="middle">middle</div>
        <div class="left">left</div>
        <div class="right">right</div>
    </div>
</body>
</html>

注意:圣杯布局中间列的宽度不能小于两边任意列的宽度,而双飞翼布局则不存在这个问题。
父级padding+子绝父相+负边距:三栏都使用float:left;父级标签padding: 0 200px; ,结合下面这张图理解

将left和right使用子绝父相,再调整定位的方式弄上去
左边:margin-left: -100%;(切换到上一行起始位置)left: -200px;(相对定位,向左移动200px)
右边:margin-left: -200px;(向左移动一个身位,移动到middle的右侧)left:200px; (向右移动200px)
还有种方法也能挤上去:margin-right: -200px;

双飞翼布局

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS实现三栏布局</title>
    <style>
        .container {
            overflow: hidden;
            height: 200px;
        }
        /* 中间栏的子标签margin+左右负边距 */
        .middle,.left,.right {
            float: left;
            height: 100px;
        }
        .middle {
            width: 100%;
            background-color: aqua;
        }
        .inner {
            margin: 0 200px;
            height: 100px;
            background-color: green;
        }
        .left {
            width: 200px;
            margin-left: -100%;
            background-color: red;
        }
        .right {
            width: 200px;
            margin-left: -200px;
            background-color: blue;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="middle">
            <div class="inner">中间</div>
        </div>
        <div class="left">左边</div>
        <div class="right">右边</div>
    </div>
</body>
</html>

中间栏的子标签margin+左右负边距:三栏都使用float:left;中间栏子标签margin: 0 200px; HTML中将中间栏放前面;结合下面这张图去理解

双飞翼圣杯复合写法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS实现三栏布局</title>
    <style>
        /* 双飞翼与圣杯布局的结合写法,这一种直接在中间栏加padding,然后将左右栏 添加margin-left移动上去 */
        /* middle要使用内减模式 不然会多出一块区域 */
        .container {
            height: 100px;
        }
        .middle,.left,.right{
            float: left;
            height: 100%;
        }
        .middle {
            box-sizing: border-box;
            width: 100%;
            background: rgb(100, 105, 100);
            padding: 0 200px;
        }
        .left {
            width: 200px;
            background: pink;
            margin-left: -100%;
        }
        .right {
            width: 200px;
            background: pink;
            margin-left: -200px;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="middle">middle</div>
        <div class="left">left</div>
        <div class="right">right</div>
    </div>
</body>
</html>

中间标签内减模式padding+负数边距:三栏都使用float:left;中间栏标签padding: 0 200px; 且要设置box-sizing: border-box;左边:margin-left: -100%;右边:margin-left: -200px;

总结

  1. float+BFC:左右两栏float到左右;中间 overflow: hidden; 清除浮动显示第二栏 ;注意:HTML需要将中间块放在right之后;
  2. float+margin:左右两栏float到左右;中间设置margin-leftmargin-right;注意:HTML需要将中间块放在right之后;
  3. float+calc() :先使用浮动将三栏水平排列,然后对中间栏使用calc(100% - 400px);来计算去除左右两栏宽度后剩余的宽度;
  4. flex;将中间设定值为1,最简单的方式;
  5. grid:display: grid;grid-template-columns: 200px auto 200px;左右两栏固定宽度,中间自适应宽度;
  6. 子绝父相:三栏全部绝对定位;中间栏left: 200px;right: 200px;保持伸缩居中
  7. felx实现圣杯双飞翼效果:left {order: -1;} right{order: 1;} 中间块默认为0;所以显示顺序了-1、0、1;
  8. 圣杯布局:父级padding+子绝父相+负边距
  9. 双飞翼布局:中间栏的子标签margin+左右负边距
  10. 双飞翼圣杯复合写法:中间标签内减模式padding+负数边距

感谢小伙伴们的耐心观看,本文为笔者个人学习记录,如有谬误,还请告知,万分感谢!如果本文对你有所帮助,还请点个关注点个赞~,您的支持是笔者不断更新的动力!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现flex实现三栏布局,可以按照以下步骤进行操作: 1. 首先,创建一个外层容器,可以使用`<div>`元素,并为其设置`display: flex;`来启用flex布局。[2] 2. 在外层容器中创建三个子元素,代表三栏布局的左、中、右栏。 3. 对左、右栏设置一个固定的宽度,例如`width: 300px;`。对中间栏不设置特定的宽度。 4. 对三个子元素设置`flex: 1 1 auto;`,这将使它们平分剩余空间。这意味着中间栏的宽度将自适应。 5. 可以根据需要为三个子元素添加其他样式,比如背景色、边框等。 以下是一个使用flex实现三栏布局的示例代码: ``` <div class="container"> <div class="left"></div> <div class="middle"></div> <div class="right"></div> </div> ``` ``` .container { display: flex; } .left, .right { width: 300px; } .middle { flex: 1 1 auto; } ``` 通过设置外层容器的`display: flex;`和子元素的相应样式,就可以实现使用flex布局三栏等分布局。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [flex实现三栏等分布局](https://blog.csdn.net/az44yao/article/details/117676640)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [css3弹性盒子flex实现三栏布局实现](https://download.csdn.net/download/weixin_38726441/14919543)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值