目录
三栏布局一般指的是页面一共有三栏,左右两栏宽度固定,中间宽度自适应的布局。同时,优秀的三栏布局其中一栏高度变化,其余两栏应该跟随变化。
构建和渲染渲染树是异步的,谁先构建好就先显示谁,我们只需要将 center 部分往前放置即可让中间部分优先显示,圣杯布局和双飞翼的中间部分优先显示就是用的这个思想
1、float
原理:浮动元素脱离文档流
缺点:
- 不支持 center 部分前置,无法实现中间部分优先加载。
- left、right 的高度无法伴随 center 高度的变化而变化
HTML 结构
<div class="outer">
<div class="sider left"></div>
<div class="center"></div>
<div class="sider right"></div>
</div>
CSS 样式
.sider {
width: 200px;
height: 500px;
background-color: lightskyblue;
}
.left {
float: left;
}
.right {
float: right;
}
.center {
/* 方案一:
margin: 0 200px 0 200px;
*/
/* 方案二: */
float: left;
width: calc(100% - 400px);
height: 500px;
background-color: pink;
}
2、position
原理:绝对定位元素脱离文档流
优点:支持center部分前置,可以实现中间部分优先加载
缺点:left、right 的高度无法伴随 center 高度的变化而变化
HTML 结构
<div class="outer">
<div class="center"></div>
<div class="sider left"></div>
<div class="sider right"></div>
</div>
CSS 样式
.outer {
position: relative;
}
.sider {
position: absolute;
top: 0;
height: 500px;
width: 200px;
background-color: lightskyblue;
}
.left {
left: 0;
}
.right {
right: 0;
}
.center {
/* 方案一:
margin: 0 200px 0 200px;
*/
/* 方案二:
position: absolute;
left: 300px;
width: cala(100% - 400px);
*/
/* 方案三: */
position: absolute;
left: 200px;
right: 200px;
height: 500px;
background-color: pink;
}
3、⭐ flex 布局
原理:利用了容器项目 order 属性
优点:
- 支持 center 部分前置,可以实现中间部分优先加载
- left、right 的高度可以伴随 center 高度的变化而变化
HTML 结构
<div class="outer">
<div class="center"></div>
<div class="sider left"></div>
<div class="sider right"></div>
</div>
CSS 样式
.outer {
display: flex;
}
.sider {
width: 200px;
height: 500px;
background-color: lightskyblue;
}
.center {
order: 2; /* 默认值为0,order越小位置越靠前,越靠上,此时就不用考虑覆盖的问题了*/
flex-grow: 1;
/* flex-grow : 默认值为0,为0时有剩余空间也不放大,子元素该属性均为1时,剩余空间被所有为1的子元素均分,有一个子元素该属性为2时,该元素将分得或者努力分得其他为1的子元素所分得空间2倍大小的空间 */
/* flex-shrink : 默认值为1,当子元素中存在某个元素该属性为0时,若空间不足,则为1的缩小,为0的不变,因此可以猜测,为2的弱小的应该是更多,应该是缩小了为1缩小的空间的两倍 */
height: 500px;
background-color: pink;
}
.left {
order: 1;
}
.right {
order: 3;
}
4、table 布局(很少用)
缺点:
- 不支持center部分前置
- left、right 的高度无法伴随 center 高度的变化而变化
HTML 结构
<div class="outer">
<div class="sider left"></div>
<div class="center"></div>
<div class="sider right"></div>
</div>
CSS 样式
.outer {
display: table;
}
.sider {
width: 200px;
height: 500px;
background-color: lightskyblue;
}
.center {
display: table-cell;
width: 100%;
height: 500px;
background-color: pink;
}
5、grid 布局(存在兼容性问题)
缺点:
- 不支持center部分前置,无法实现中间部分优先加载
- left、right 的高度无法伴随 center 高度的变化而变化
CSS 样式
.outer {
display: grid;
width: 100%;
grid-template-rows: 500px;
grid-template-columns: 200px auto 200px;
}
.sider {
background-color: lightskyblue;
}
.center {
background-color: pink;
}
6、⭐ 圣杯布局
优点:
- 支持 center 部分前置,可以实现中间部分优先加载
- left、right 的高度可以伴随 center 高度的变化而变化
- 结构比较简单,没有多余的 dom 层
主要问题:
当 center 部分小于 left 时,或者是手动调节页面的宽度,在达到某个临界值之后,接着缩小,就会发现圣杯的结构彻底混乱了,center 自己单独占了一行,两侧不再是 left 和 right,而是空白,left 跑到了 center 的下一行的最左边,并且自己单独占了一行,right 跑到了 left 的下一行
实现思路:
1)给父元素 wrapper 设置 padding: 0 200px 0 300px,左右两个 padding 用于放置 left 和 right
2)给 wrapper 中内的 center、left 和 rigth 都设置左浮动和相对定位。left 和 right 的宽分别为 300px 和 200px,center 宽度为 100%
center的宽度是100%,表示等于父元素的container的宽度。
3)因为设置了浮动和width:100%,center 会独占一行,left 和 right 会被挤到它下面
4)对 left 设置 margin-left:-100%,让其回到上一行的左侧
margin-left 为负值表示:当前元素左边框距离父元素 container 最右侧的宽度。百分比的参照物是父元素的cantainer,-100%的效果就是让left移动到container的最左侧,也就是left的左边框和父元素container的最左边相邻
5)对left设置 left:-300px 将其移到 wrapper 的 padding-left 的位置
6)同样的道理,对 right 也设置 margin-left:-200px,将 right 也拉回第一行
7)再对其设置 right:-200px;
HTML 结构
<div class="wrapper">
<div class="center"></div>
<div class="left"></div>
<div class="right"></div>
</div>
CSS 样式
.wrapper {
height: 500px;
padding: 0 200px 0 300px; /* wrapper的container两侧空出来left和right的宽度 */
}
.center, .left, .right {
position: relative;
float: left;
height: 500px;
}
.center {
width: 100%; /* 宽度=wrapper的container的宽度,两侧已空出left和right */
background-color: tomato;
}
.left {
width: 300px;
margin-left: -100%; /* 左侧紧邻container左侧 */
left: -300px;
background-color: lightgreen;
}
.right {
width: 200px;
margin-left: -200px; /* 右侧紧邻container右侧 */
right: -200px;
background-color: lightskyblue;
}
7、⭐ 双飞翼布局
双飞翼布局其实和圣杯布局类似
圣杯布局利用 wrapper 的 padding 来保留左右位置的,而双飞翼布局利用 center 的 margin 来实现的。
center 外边距的宽度只要恰好等于 left 和 right,这样在视觉上看起来 center 和 left、right 就是三个独立的板块。
优点:
- 支持 center 部分前置,可以实现中间部分优先加载
- left、right 的高度可以伴随 center 高度的变化而变化
- 兼容性比较强
缺点:
由于对 center 部分添加了一个中间父元素,多了一个 dom 结构层,就会增加渲染树的生成计算量
HTML 结构
<div class="wrapper">
<div class="center-wrapper">
<div class="center">1111111</div>
</div>
<div class="left"></div>
<div class="right"></div>
</div>
CSS 样式
.wrapper {
height: 500px;
}
.center-wrapper,
.left,
.right {
float: left;
height: 500px;
}
.center-wrapper {
width: 100%;
background-color: tomato;
}
.center {
margin: 0 200px 0 300px;
height: 500px;
}
.left {
width: 300px;
margin-left: -100%;
background-color: lightgreen;
}
.right {
width: 200px;
margin-left: -200px;
background-color: lightskyblue;
}