多种方式实现 三栏布局
三栏布局的要求,左右固定中间,自动适应
下面整理了四种三栏布局的方式
1. 圣杯布局(grial)padding solution
2. 双分翼布局(double Fly) margin solution
3. 浮动加BFC
4. flex
一、圣杯布局 和 双飞翼布局
圣杯 和 双飞翼布局用的是同一个原型,也就是说是基于一个基本的原理上升成的
下面先开始一步一步的做这个原型
1. 左边Left元素宽度200像素,右边Right元素宽度100像素,中间主体Main元素宽度自适应(Main不设置宽度)
2. Mian元素在上面
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>三栏布局</title>
<style>
*{
margin: 0;
padding: 0;
}
.header, .footer{
height: 100px;
background-color: #ddd;
}
.main{
height: 100px;
background-color: #cfa;
/* Mian元素不设置宽度,宽度自适应 */
}
.left{
width: 100px;
height: 100px;
background-color: #fca;
}
.right{
width: 200px;
height: 100px;
background-color: #acf;
}
</style>
</head>
<body>
<div class="header">Header</div>
<div class="content">
<div class="main">Main</div> <!-- Mian元素在上面 -->
<div class="left">Left</div>
<div class="right">Right</div>
</div>
<div class="footer">Footer</div>
</body>
</html>1、为什么Mian元素放到最上面
Main、Left、Right这三个元素,正常顺序是左中右(Left、Main、Right),但是我们在页面布局中把Mian放到最上面,
目的是元素加载完,最好是先渲染Main,因为它里面还有很多其它元素。
浏览器DOM树的遍历是深度优先遍历,查看Main元素后,继续查看它里面的子元素,它的兄弟元素Left、Right会放到后面,这是关于页面DOM树解析的规则。
所以对于我们页面更好的渲染,让Main元素尽早的加载出来,包括Main对应的资源尽早的去拿取,
对用户的体验是一个非常不错的提升,所以要把Main放到上面来
深度优先是二叉树算法,让Main元素更快的加载、渲染出来
目前的效果是这样的
HeaderMainLeftRightFooter
2、圣杯布局和双飞翼布局的原型
header和footer这两个元素不考虑,只看中间着三个元素,
三栏布局首先要把Main、Left、Right,这三个元素排到一行
设置content元素下面三个div浮动 float: left; 把他们排到一行上去
<style>
*{
margin: 0;
padding: 0;
}
.header, .footer{
height: 100px;
background-color: #ddd;
}
.main{
height: 100px;
background-color: #cfa;
}
.left{
width: 200px;
height: 100px;
background-color: #fca;
}
.right{
width: 100px;
height: 100px;
background-color: #acf;
}
/* 设置浮动 */
.content > div{
float: left;
}
</style>因为设置了浮动,Main、Left、Right、Footer都飘起来了
HeaderMainLeftRightFooter
给Main元素设置宽度 width:100%; ,让它撑开一整行
<style>
*{
margin: 0;
padding: 0;
}
.header, .footer{
height: 100px;
background-color: #ddd;
}
.main{
height: 100px;
background-color: #cfa;
width:100%; /* 设置宽度100% */
}
.left{
width: 200px;
height: 100px;
background-color: #fca;
}
.right{
width: 100px;
height: 100px;
background-color: #acf;
}
.content > div{
float: left;
}
</style>因为浮动后高度塌陷,导致Footer元素也跟着上来了
HeaderMainLeftRightFooter
清除浮动
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>三栏布局</title>
<style>
*{
margin: 0;
padding: 0;
}
/* 清除浮动 */
.clearfix::after{
content: "";
display: block;
clear: both;
}
.header, .footer{
height: 100px;
background-color: #ddd;
}
.main{
height: 100px;
background-color: #cfa;
width:100%;
}
.left{
width: 200px;
height: 100px;
background-color: #fca;
}
.right{
width: 100px;
height: 100px;
background-color: #acf;
}
.content > div{
float: left;
}
</style>
</head>
<body>
<div class="header">Header</div>
<div class="content clearfix"> <!-- 清除浮动 -->
<div class="main">Main</div>
<div class="left">Left</div>
<div class="right">Right</div>
</div>
<div class="footer">Footer</div>
</body>
</html>这样下面Footer元素就摆放到下面去了,而且centent元素把三个子元素都包裹住了,
现在这样和我们想要的三栏布局还差一些
HeaderMainLeftRightFooter
浮动元素本质上是一行,是先排列Main元素,后面跟着排列Left元素 和 Right元素,
浮动元素是从左到右排,如果一行装不下就放到下一行,
或者说说浮动元素本质上是一行,只不过是折行了,这是浮动的特点。
给Lift元素设置 margin-left: -100%; 相当于一个父级的宽度
<style>
*{
margin: 0;
padding: 0;
}
.clearfix::after{
content: "";
display: block;
clear: both;
}
.header, .footer{
height: 100px;
background-color: #DDD;
}
.main{
height: 100px;
background-color: #cfa;
width:100%;
}
.left{
width: 200px;
height: 100px;
background-color: #fca;
margin-left:-100%; /* 设置margin */
}
.right{
width: 100px;
height: 100px;
background-color: #acf;
}
.content > div{
float: left;
}
</style>Left元素就跑到上面一行去了
HeaderMainLeftRightFooter
Right元素也是,设置自身的宽度的负树值 margin-left: -100px; ,就排到右边来了
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>三栏布局的原型</title>
<style>
*{
margin: 0;
padding: 0;
}
.clearfix::after{
content: "";
display: block;
clear: both;
}
.header, .footer{
height: 100px;
background-color: #ddd;
}
.main{
height: 100px;
background-color: #cfa;
width:100%;
}
.left{
width: 200px;
height: 100px;
background-color: #fca;
margin-left:-100%;
}
.right{
width: 100px;
height: 100px;
background-color: #acf;
margin-left:-100px; /* 设置margin */
}
.content > div{
float: left;
}
</style>
</head>
<body>
<div class="header">Header</div>
<div class="content clearfix">
<div class="main">Main</div>
<div class="left">Left</div>
<div class="right">Right</div>
</div>
<div class="footer">Footer</div>
</body>
</html>Right元素就到右边的位置上了
HeaderMainLeftRightFooter
流式布局会从上到下,一行铺满会放到下一行,如果一行能放得下都会放到一行,
所以Left元素设置 margin:-100%; 负的百分之百会往上提一整行,同样Right元素设置负自身宽度会贴右侧自身宽度的位置上
这是浮动的一个特点,从左到右、从上到下的排列方式,
这点一定要理解,如果不理解就会很蒙
接下来开始圣杯布局 和 双飞翼布局,
现在的问题是Main元素是被Left元素和Right元素压住的,
我们希望Main元素是在Left元素和Right元素中间的位置,下面基于这样一个原型,去生成圣杯模式和双飞翼模式。
3、圣杯模式
圣杯模式的意思是,我们希望达到一种理想的模式(布局方式),这是一个隐喻并不是杯子。
圣杯布局的核心思想
1). 父级content元素使用padding属性预留位置,设置 padding: 0 100px 0 200px;
2). 子元素设置相对定位,进行位置调整,
设置Left元素 position:relative; left:-200px;
设置Right元素 position:relative; right:-100px;
把Left、Right两个元素放到对应的位置去
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>grail</title>
<style>
*{
margin: 0;
padding: 0;
}
.clearfix::after{
content: "";
display: block;
clear: both;
}
.header, .footer{
height: 100px;
background-color: #ddd;
}
.main{
height: 100px;
background-color: #cfa;
width:100%;
}
.left{
width: 200px;
height: 100px;
background-color: #fca;
margin-left:-100%;
position:relative;
left:-200px;
}
.right{
width: 100px;
height: 100px;
background-color: #acf;
margin-left:-100px;
position:relative;
right:-100px;
}
.content > div{
float: left;
}
.content{
padding:0 100px 0 200px;
}
</style>
</head>
<body>
<div class="header">Header</div>
<div class="content clearfix">
<div class="main">Main</div>
<div class="left">Left</div>
<div class="right">Right</div>
</div>
<div class="footer">Footer</div>
</body>
</html>4、双飞翼布局
双飞翼布局也是基于这个原型生成,还是中间的Main元素被Left、Rigth元素压住了
双飞翼布局来自淘宝团队,他们是怎么解决这个问题的呢?
1). 改变HTML的结构,给Main套了一个外层(外层是wrapper)
2). 设置外层wrapper元素的宽度 width:100%; ,然后设置Main元素
3). Main元素不需要宽度width:100%,因为设置了它父级(wrapper元素)的宽度,
设置了Main父级的宽度,Main撑满父级的包含块就可以了
4). 通过设置Main的 margin:0 200px 0 100px;
Main元素自己在当前的wrapper父元素内,两边的margin正好是预留Left、right的位置
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>双飞翼布局 doubleFly</title>
<style>
*{
margin: 0;
padding: 0;
}
.clearfix::after{
content: "";
display: block;
clear: both;
}
.header, .footer{
height: 100px;
background-color: #ddd;
}
.main{
height: 100px;
background-color: #cfa;
/* width:100%; */
margin:0 100px 0 200px
}
.left{
width: 200px;
height: 100px;
background-color: #fca;
margin-left:-100%;
}
.right{
width: 100px;
height: 100px;
background-color: #acf;
margin-left:-100px;
}
.content > div{
float: left;
}
.wrapper{
width: 100%;
}
</style>
</head>
<body>
<div class="header">Header</div>
<div class="content clearfix">
<div class="wrapper">
<div class="main">Main</div>
</div>
<div class="left">Left</div>
<div class="right">Right</div>
</div>
<div class="footer">Footer</div>
</body>
</html>圣杯布局和双飞翼,一个是用padding预留,一个是用margin把两边撑开
叫双飞翼是因为有两边两个耳朵,中间是主体部分
二、浮动加BFC布局
本质上是用了浮动元素的一些特点
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>float + BFC</title>
<style>
*{
margin: 0;
padding: 0;
}
.left{
width: 100px;
height: 100px;
background-color: #fac;
}
.right{
width: 200px;
height: 100px;
background-color: #caf;
}
.center{
/* 中间自适应不设置宽度 */
height: 120px;
background-color: #acf;
}
</style>
</head>
<body>
<div class="left"></div>
<div class="right"></div>
<div class="center"></div>
</body>
</html>两边的元素加浮动,中间的元素触发BFC,
触发BFC的元素会避开浮动元素,从而实现三栏布局
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>float + BFC</title>
<style>
*{
margin: 0;
padding: 0;
}
.left{
width: 100px;
height: 100px;
background-color: #fac;
float: left; /* 左浮动 */
}
.right{
width: 200px;
height: 100px;
background-color: #caf;
float: right; /* 右浮动 */
}
.center{
/* 中间自适应不设置宽度 */
height: 120px;
background-color: #acf;
overflow: hidden;/* 触发BFC 或者用 display:flow-root专门触发BFC */
}
</style>
</head>
<body>
<div class="left"></div>
<div class="right"></div>
<div class="center"></div>
</body>
</html>三、flex布局
flex实现三栏布局就比较简单了
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>flex</title>
<style>
*{
margin: 0;
padding: 0;
}
.content > div{
height: 100px;
}
.header, .footer{
height: 100px;
background-color: #ddd;
}
.content{
display: flex;
}
.main{
order: 2;
flex: 1;
background-color: #fac;
}
.left{
order: 1;
width: 200px;
background-color: #afc;
}
.right{
order: 3;
width: 100px;
background-color: #fca;
}
</style>
</head>
<body>
<div class="header">Header</div>
<div class="content">
<div class="main">Main</div>
<div class="left">Left</div>
<div class="right">Right</div>
</div>
<div class="footer">Footer</div>
</body>
</html>收藏记录一篇圣杯双飞翼布局的帖子
三句话总结圣杯,双飞燕布局
https://juejin.cn/post/6844903807936102414
https://blog.csdn.net/weixin_34127717/article/details/91386223
firstTime: 20220207
