• CSS三栏布局的7种方式代码详解 | 圣杯布局 | 双飞翼布局 | 弹性盒子


    CSS三栏布局代码详解

    写在前面:博主最近在转头复习最前面学的CSS,整理一下CSS三栏布局的笔记,正好也捋顺自己的逻辑思路。解析我尽量按照思路详细的写了,代码均可正确运行,留给需要的小伙伴进行参考,如有不足,欢迎在评论区补充。

    三栏布局关键:container盒子和main盒子都不要设置宽度,否则浏览器视口缩小时无法自适应,违背了三栏布局的目的。

    方式一:浮动+margin

    代码思路:在一个container容器中放置三个盒子,(为方便区分和好添加样式,分别添加类名为left、right、main),盒子排列顺序从上到下依次为 left、right、main*。给left、right盒子添加左和右浮动,使其浮动到浏览器窗口的左边缘和右边缘。这时左右盒子会脱离标准流,则main盒子会占有他们原来的位置,将main盒子添加外边距margin-left和margin-right,将他们的值分别设置为为left和right的宽度,这时main盒子的内容区将会显示在左右盒子的中间。三栏布局完成。

    • 将left和right盒子放在main盒子前面的原因:添加浮动的元素会脱离标准流,失去其原来的位置,添加浮动元素的下面的元素会占有它原来的位置。但是添加浮动的元素不会影响它前面元素的标准流。因此如果将 main 写在前面,left 和 right 添加浮动后也无法压在 main 盒子上面。
    • main盒子不设置宽度,给container父级盒子设置宽度100%,则main盒子默认为父盒子container的宽度。

    方式一代码如下(已测试,可直接运行):

    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="utf-8">
    		<title>title>
    		<style>
    			.container{
    				width: 100%;
    				height: 200px;
    				/* background-color: pink; */
    			}
    			.left{
    				float: left;
    				width: 200px;
    				height: 200px;
    				background-color: red;
    			}
    			.right{
    				float: right;
    				width: 200px;
    				height: 200px;
    				background-color: blue;
    			}
    			.main{
    				height: 200px;
    				background-color: aqua;
    				margin-left: 210px;
    				margin-right: 210px;
    				
    			}
    		style>
    	head>
    	<body>
    		<div class="container">
    			<div class="left">div>
    			<div class="right">div>
    			<div class="main">div>
    		div>
    	body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    方式二:浮动+BFC

    代码思路:和方式一类似,只有设置 margin 处有不同,将左右盒子浮动并压在 main 盒子上以后,采用给 main 盒子开启 BFC(Block Formatting Context | 块级格式上下文),以达到main盒子的宽度正好位于左右盒子中间且不被压住的效果。三栏布局完成。

    • BFCBlock Formatting Context | 块级格式上下文): BFC 是 web 页面的一块独立的渲染区域,内部元素的渲染不会影响边界以外的元素。

    • 开启 BFC 以后的元素有以下特点:

      1. 元素不会被浮动的元素所覆盖;
      2. 子元素和父元素的外边距不会重叠;
      3. 父元素可以包含浮动的子元素。

      这里我们就可以利用第一条特点,开启 main 元素的 BFC,以达到三栏布局的效果。

    • 而最常用的开启 BFC 的方式就是给该元素的样式中添加 overflow:hidden

    • 因此方法二和方法一的不同就在于 main 的处理方式由添加 margin 改为开启 BFC 。

    方式二代码如下(已测试,可直接运行):

    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="utf-8">
    		<title>title>
    		<style>
    			.container{
    				width: 100%;
    				height: 200px;
    				/* background-color: pink; */
    			}
    			.left{
    				float: left;
    				width: 200px;
    				height: 200px;
    				background-color: red;
    			}
    			.right{
    				float: right;
    				width: 200px;
    				height: 200px;
    				background-color: blue;
    			}
    			.main{
    				/* 开启主元素的BFC */
    				overflow: hidden;
    				height: 200px;
    			}
    		style>
    	head>
    	<body>
    		<div class="container">
    			<div class="left">div>
    			<div class="right">div>
    			<div class="main">div>
    		div>
    	body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    方式三:flex布局(最方便)

    代码思路:利用flex弹性盒布局,将三个盒子的父元素盒子设置为flex布局。这时利用弹性布局,将main盒子放在左右盒子中间,给左右盒子定宽,然后给mai盒子样式中添加flex:1,即可实现三栏布局。

    flex布局:弹性盒布局

    flex:1 :flex属性表示元素分配设置了弹性布局的父盒子的剩余空间,即在本案例中为给main分配container盒子除去left和right的宽之后的剩余空间;flex::属性值为数字,数字表示占几份,flex:1表示占一份,且只有main盒子在分配这个剩余空间,因此这一份都属于main盒子。

    方式三代码如下(已测试,可直接运行):

    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="utf-8">
    		<title>title>
    		<style>
    			.container{
    				display: flex;
    				width: 100%;
    				height: 200px;
    			}
    			.left{
    				width: 200px;
    				height: 200px;
    				background-color: red;
    			}
    			.right{
    				width: 200px;
    				height: 200px;
    				background-color: blue;
    			}
    			.main{
    				flex: 1;
    				height: 200px;
    				background-color: aqua;		
    			}
    		style>
    	head>
    	<body>
    		<div class="container">
    			<div class="left">div>
                
    			<div class="main">div>
    			<div class="right">div>
    		div>
    	body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    方法四:Table布局

    代码思路:将container容器设置为表格display:table,将左盒子,main盒子,右盒子,依次排列,将这三个子盒子都设置为单元格display:table-cell,给左右盒子设宽,则中间的main盒子设置为单元格后会自适应占中间的宽度。三栏布局完成。

    方式四代码如下(已测试,可直接运行):

    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="utf-8">
    		<title>table布局title>
    		<style>
    			.container{
    				display: table;
    				width: 100%;
    				height: 200px;
    			}
    			.left{
    				display: table-cell;
    				width: 200px;
    				height: 200px;
    				background-color: red;
    			}
    			.right{
    				display: table-cell;
    				width: 200px;
    				height: 200px;
    				background-color: blue;
    			}
    			.main{
    				display: table-cell;
    				height: 200px;
    				background-color: aqua;
    			}
    		style>
    	head>
    	<body>
    		<div class="container">
    			<div class="left">div>
    			<div class="main">div>
    			<div class="right">div>
    		div>
    	body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    方式五:定位+margin

    代码思路:

    1. 初始文档流要将left和right盒子放在main盒子的前面(有坑,后面会解释)
    2. container和main都不设宽,给main添加左右外边距margin空出左右位置;
    3. 子绝父相,container添加相对定位,左右盒子设置绝对定位,分别添加边偏移量为left:0right:0即可
    4. 三栏布局完成

    绝对定位:相对于最近一级的带有定位的祖先元素进行偏移。

    方式五代码如下(已测试,可直接运行):

    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="utf-8">
    		<title>table布局title>
    		<style>
    			.container{
    				position: relative;
    				width: 100%;
    				height: 200px;
    			}
    			.left{
    				position: absolute;
    				/* 表示离container盒子的左边线的偏移量为0 */
    				left: 0;
    				/* 基础宽高颜色 */
    				width: 200px;
    				height: 200px;
    				background-color: red;
    			}
    			.right{
    				position: absolute;
    				/* 表示离container盒子的右边线的偏移量为0 */
    				right: 0;
    				/* 基础宽高颜色 */
    				width: 200px;
    				height: 200px;
    				background-color: blue;
    			}
    			.main{
    				height: 200px;
    				background-color: aqua;
    				margin-left: 200px;
    				margin-right: 200px;
    			}
    		style>
    	head>
    	<body>
    		<div class="container">
    			<div class="left">div>
    			<div class="right">div>
    			<div class="main">div>
    		div>
    	body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    注意:初始文档流要将left和right盒子放在main盒子的前面,不然会出现以下局面

    image-20221103154100127

    • (这里将main放在了left和right的前面),原因是main盒子不需要添加绝对定位,因此它没有脱离文档流,独占一行的位置,按照上面的代码写法,左右盒子无法与其在一行。

    • 若要将main盒子放在左右盒子前面,也可以实现效果:左右盒子的绝对定位的边偏移量加上top:0即可,表示左右盒子与其带相对定位的父盒子container的上边线的距离为0。

    • 这时源代码如下:

    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="utf-8">
    		<title>table布局title>
    		<style>
    			.container{
    				position: relative;
    				width: 100%;
    				/* height: 200px; */
    			}
    			.left{
    				position: absolute;
    				/* 表示离container盒子的左边线的偏移量为0 */
    				left: 0;
    				top: 0;
    				/* 基础宽高颜色 */
    				width: 200px;
    				height: 200px;
    				background-color: red;
    			}
    			.right{
    				position: absolute;
    				/* 表示离container盒子的右边线的偏移量为0 */
    				right: 0;
    				top:  0;
    				/* 基础宽高颜色 */
    				width: 200px;
    				height: 200px;
    				background-color: blue;
    			}
    			.main{
    				height: 200px;
    				background-color: aqua;
    				margin-left: 200px;
    				margin-right: 200px;
    			}
    		style>
    	head>
    	<body>
    		<div class="container">
    			<div class="main">div>
    			<div class="left">div>
    			<div class="right">div>
    			
    		div>
    	body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    方式六:圣杯布局

    代码思路:

    1. 用container容器包住三个盒子,圣杯布局以main盒子为主体,初始标准流方向为:main盒子、左盒子、右盒子。

    2. 给container容器加上左右200px(左右盒子宽度)的margin值,将左右两块空间空出。

    3. 将main盒子的宽度设置为100%,则main的宽度为父盒子宽度的100%。

    4. 同时给main、left、right盒子添加左浮动float:left。此时三个盒子左浮动,变成下图状态:

      image-20221103145447380

    5. 然后首先设置左盒子margin-left:-100%,将左盒子左移(父盒子宽度的)100%,到达:

    6. 然后同理设置右盒子margin-left:-200px,到达:(此时左右盒子都盖住了main的一部分)

      image-20221103151017853

    7. 使用相对布局移动左右盒子的位置到达两侧。

      .left{
          ... ...
          position:relative;
          /*离原来位置的左边线-200px*/
          left:-200px;
          ... ...
      }
      .right{
          ... ...
          position:relative;
       	/*离原来位置的左边线200px*/   
          left:200px;
          ... ...
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
    8. 三栏布局完成。

      image-20221103151553721

      总结:

      1. margin给父盒子空左右
      2. main放前面占100%,浮动三个盒子排成行
      3. margin负值移动盒子压到main两侧
      4. 相对定位移到空白处

    方式六代码如下(已测试,可直接运行):

    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="utf-8">
    		<title>table布局title>
    		<style>
    			.container{
    				margin-left: 200px;
    				margin-right: 200px;
    			}
    			.main{
    				float: left;
    				/* 基础宽高颜色 */
    				width: 100%;
    				height: 200px;
    				background-color: green;
    			}
    			.left{
    				/* 利用浮动将左右盒子 */
    				float: left;
    				margin-left: -100%;
    				/* 左盒子相对定位*/
    				position: relative;
    				left: -200px;
    				/* 基础宽高颜色 */
    				width: 200px;
    				height: 200px;
    				background-color: red;
    			}
    			.right{
    				float: left;
    				margin-left: -200px;
    				/* 右盒子相对定位 */
    				position: relative;
    				left: 200px;
    				/* 基础宽高颜色 */
    				width: 200px;
    				height: 200px;
    				background-color: blue;
    			}
    			
    		style>
    	head>
    	<body>
    		<div class="container">
    			<div class="main">div>
    			<div class="left">div>
    			<div class="right">div>
    		div>
    	body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    注:这里右盒子也可以margin-right:-200px直接移到目标位置而不需要用定位。

    且container不要设置宽,不然浏览器视口缩小中间盒子不会自适应。

    方式七:双飞翼布局

    代码思路:

    1. 和圣杯布局不同的部分是双飞翼布局没有container父盒子

    2. 和圣杯布局相同的部分是相对布局前面的部分,此时main盒子的宽度是浏览器宽度的100%,且左右盒子覆盖main盒子的两端。

    这里不能直接为main添加左右margin,会打乱前面左右盒子通过margin移动的位置。

    image-20221103155759358

    ​ 3. 将main盒子用一个outer盒子包裹起来,将浮动和宽100%添加给outer,则可以给main添加左右margin。三栏布局完成。

    image-20221103160034858

    方式七代码如下(已测试,可直接运行):

    DOCTYPE html>
    <html>
    	<head>
    		<meta charset="utf-8">
    		<title>双飞翼布局title>
    		<style>
    			.outer{
    				float: left;
    				width: 100%;
    			}
    			.main{
    				margin: 0 200px;
    				/* 基础宽高颜色 */
    				height: 200px;
    				background-color: green;
    			}
    			.left{
    				/* 利用浮动将左右盒子 */
    				float: left;
    				margin-left: -100%;
    				
    				/* 基础宽高颜色 */
    				width: 200px;
    				height: 200px;
    				background-color: red;
    			}
    			.right{
    				float: left;
    				margin-left: -200px;
    				
    				/* 基础宽高颜色 */
    				width: 200px;
    				height: 200px;
    				background-color: blue;
    			}
    			
    		style>
    	head>
    	<body>
    		<div class="outer">
    			<div class="main">         		12472937593842759734096739084718237895273845821739847218374819290837239847839275402
                div>
    		div>
    		<div class="left">div>
    		<div class="right">div>
    	body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    总结

    以上就是三栏布局的七种常见CSS实现办法。如有不足可以在评论区指出。

  • 相关阅读:
    Ceph入门到精通-Nginx超时参数分析设置
    wsl ubuntu 安装的正确方式
    CEC2023:基于自适应启动策略的混合交叉动态约束多目标优化算法(MC-DCMOEA)求解CEC2023(提供MATLAB代码及参考文献)
    AngularJS学习的代码仓库地址
    线上多域名实战
    10W字面试小抄,附操作系统、计算机网络面试题
    深入浅出学Verilog--数据类型
    金仓数据库KingbaseES客户端编程接口指南-ado.net(14. 示例)
    音乐播放器APP
    debian11 安装 postgress 数据库 -- chatGPT
  • 原文地址:https://blog.csdn.net/dxy1128/article/details/127672925