对css的关注比较少,疫情期间,最近同事远程面试聊起圣杯布局,我不知道什么叫圣杯布局,表面上对其不屑,当查了相关文档,其实发现自己除了flex 布局来实现对应的逻辑,利用float来布局,我自己是实现不了,当然我也不能落后,那我们来扒一扒圣杯布局的来龙去脉。
说起圣杯布局 ,最初的出处是Matthew Levine 2006年 1月30日 在In Search of the Holy Grail 这片文章中提出来的。圣杯布局就是 一块区域分为 左,中, 右 三个可视区域,左 右的 宽度是固定,但是中间的宽度占据剩余的整个屏幕。
这个该怎么搞,目前已经是2020年了,利用flex进行布局在前端已经大行其道,grid 布局 也开始展露头脚。利用css2.1浮动布局慢慢的要退出历史舞台了。2006年对我来说已经上古时代。flex 弹性布局 实现这种布局其实很简单。
<div class="container">
<div class="left"></div>
<div class="center"></div>
<div class="right"></div>
</div>
圣杯布局的html 的结构如上所示,left 为左边区域,center 为中间区域 ,right 为右边区域。
flex 实现
flex的相关介绍可以查看阮一峰的这篇文章Flex 布局教程:语法篇 我们将 container 设置成flex 的容器 ,那么left ,center ,right 就变成了 容器中flex item ,要使center 能够占领剩余的空间 ,对其使用 flex-grow
属性就能够实现对应的效果
.container {
display:flex;
height:600px;
}
.left {
width:150px;
height:100%;
background:blue;
}
.center{
flex-grow:1;
height:100%;
background:gray;
}
.right{
width:150px;
height:100%;
background:orange;
}
效果如下所示:
flex 可以算目前编写代码最少,也最容易理解的实现方式。
float布局的实现
假如我们回到2006年,在作者所处的那个年代,flex 还没有提出来(2009年才出来),我们该怎么实现了。那么这个时候我们应该结合盒模型和 float布局来实现对应的功能,盒模型 三大件 margin padding width .
首先 我们想到是 上面的三个子元素都是block 元素,默认都占据一行,如下图所示:
为了让三个并排,那么我们需要对三个使用float 进行浮动,但是这个时候会考虑到一个问题,进行浮动的时候,中间的元素宽度是随父元素的宽度进行变换的。这个实现才是其中的难点,怎么去搞呢?(todo)
中间元素的宽度是随父元素的宽度变化的,那么我们可以设置 中间元素的width 为100% ,此外我们知道左右两边元素的宽度,利用 padding-left 和padding-right 设置父元素填充区的宽度。
代码如下所示, 我们将center提为第一个孩子目录
<div class="container">
<div class="center"></div>
<div class="left"></div>
<div class="right"></div>
</div>
.container {
padding:0 150px;
outline: 1px dotted red;
overflow: auto;
}
.center {
float: left;
width: 100%;
height: 400px;
background: gray;
}
.left {
float: left;
width: 150px;
height: 400px;
background:blue;
}
.right {
float: left;
width: 150px;
height: 400px;
background: orange;
}
float布局的时候,我们有个疑问,为什么要把 center 写在第一位,而不是按照 left center right 的顺序写法?
这个时候我怎么让左右元素占据父元素的padding区域空间呢,这个时候我们可以想起定位 ,目前父元素是的定位是static 定位,我们设置left 和 right 为relative定位 这个时候让 left 占据左边,第一步:我们可以设置 margin-right:-100%; 这个时候是向左移动父元素的宽度,从父元素的边框位开始,其实也是中间元素的实际宽度,我们可以看下面的动画。
这个时候再设置right:150px 就将左边的块实现了
<div class="container">
<div class="center"></div>
<div class="left"></div>
<div class="right"></div>
</div>
.container {
padding:0 150px;
outline: 1px dotted red;
overflow: auto;
}
.center {
float: left;
width: 100%;
height: 400px;
background: gray;
}
.left {
position:relative;
margin-left:-100%;
right:150px;
float: left;
width: 150px;
height: 400px;
background:blue;
}
.right {
float: left;
width: 150px;
height: 400px;
background: orange;
}
右边布局的实现 也是利用margin-right 和relative 进行
.right {
position: relative;
float: left;
margin-right: -150px;
width: 150px;
height: 400px;
background: orange;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>css3</title>
<style>
.container {
padding:0 150px;
outline: 1px dotted red;
overflow: auto;
}
.center {
float: left;
width: 100%;
height: 400px;
background: gray;
}
.left {
position: relative;
margin-left: -100%;
right:150px;
transition: all 6s;
float: left;
width: 150px;
height: 400px;
background:blue;
}
.right {
position: relative;
float: left;
margin-right: -150px;
width: 150px;
height: 400px;
background: orange;
}
</style>
</head>
<body>
<div class="container">
<div class="center"></div>
<div class="left"></div>
<div class="right"></div>
</div>
</body>
</html>
绝对定位实现
绝对定位的实现,也很简单,left 和right 相对于父元素进行定位。中间center 设置为100% 代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>css3</title>
<style>
.container {
position: relative;
padding:0 150px;
outline: 1px dotted red;
overflow: auto;
}
.center {
width: 100%;
height: 400px;
background: gray;
}
.left {
position: absolute;
left:0px;
top:0px;
width: 150px;
height: 400px;
background:blue;
}
.right {
position: absolute;
top:0px;
right: 0px;
width: 150px;
height: 400px;
background: orange;
}
</style>
</head>
<body>
<div class="container">
<div class="center"></div>
<div class="left"></div>
<div class="right"></div>
</div>
</body>
</html>
上面使用了 三种方式来实现圣杯布局,其中flex 来实现,个人认为是最简单的实现方式,不需要过多思考,解放大脑
flex布局性能 vs float布局性能 ?
使用flex 布局还是使用float呢?我们其实要考虑的是 float 布局性能更好,还是flex布局更好.flex布局对性能的影响主要体现在哪方面?
发表评论