前言
本文针对圣杯布局(两边固定,中间自适应布局)以五种方式进行讲解,话不多说,现在开始
方式一:float布局
利用float实现圣杯布局是最原始也是兼容性最好的方式,当然相对于其它几种来说较为复杂。
首先定义一个容器包裹三列盒子
<div class="container">
<div class="center">
center
</div>
<div class="left">
left
</div>
<div class="right">
right
</div>
</div>
复制代码
其中有一个需要注意的是盒子的排布顺序,其中.center盒子排在最前面,left和right依次排列,这里主要是用到了float和margin的特性,接下来会讲到。
其次是css样式
.container > div {
float: left;
height: 300px;
}
复制代码
⬆首先将父容器下的子盒子都定义为float为左的浮动元素,高度统一为300px
.left, .right {
width: 100px;
background: #f00;
}
.center {
width: 100%;
background: #0f0;
}
复制代码
⬆接下来定义子盒子的宽度,可以看见.center盒子的宽度为100%,也就是占满父容器,那么left和right盒子相应的就到下一行了,如下图所示。
那么如何让left和right盒子放置在center盒子的左右侧呢,这就要用到margin和float的特性了,先看代码示例
.left {
margin-left: -100%;
}
.right {
margin-left: -100px;
}
复制代码
可以看见,首先给left盒子添加了一个负100%的margin-left值,这个百分数对应的是left盒子的父盒子,也就是.container的宽度之比,那么left盒子就会向左移动父元素的宽度的距离。
其次因为left盒子和center盒子是浮动排列的,left盒子margin为负,且已经超过自身的宽度,那么left盒子在文档流中的占位宽度已然成了一个负值,所以依据浮动的特性。
当盒子成为浮动元素后,在浮动层拥有内联元素的"特性",当多个浮动元素一排容不下时,就换行。
反之,则不换行。
left盒子就会和center盒子同处一行,且位于container盒子的最左侧,同理给right盒子一个负自身宽度的margin值,right盒子就会和center盒子同处一行,且位于右侧,如图所示。
这里又出现了一个问题,center盒子的内容被left和right盒子覆盖了,这里我们用box-sizing和padding属性解决这个问题
.center {
box-sizing: border-box;
padding: 0 100px;
width: 100%;
background: #0f0;
}
复制代码
在双飞翼布局中我们可以看见这样的dom结构
<div class="container">
<div class="main">
<div class="content">main</div>
</div>
<div class="left">left</div>
<div class="right">right</div>
</div>
复制代码
其实原理是一样的,都是限制center盒子的宽度来实现通过padding将center盒子的内容“挤”到中间来展示。
完整代码可以看这里
方式二:绝对布局
相信很多新人同学经常使用绝对布局,之前带过的徒弟就是这样,对于一些复杂的布局,不懂得拆分结构,用绝对定位来实现需求,总是被我敲脑袋。
但是这里还是提一下这种布局,不是说它不好,而是标题的牛逼都吹出去了,总得拿出些“干货”来。
先看dom结构,循规蹈矩
<div class="container">
<div class="left">
left
</div>
<div class="center">
center
</div>
<div class="right">
right
</div>
</div>
复制代码
绝对定位的特性想必大家都知道,所以直接讲解步骤。
首先给父容器定义position为relative,让absolute的子元素依据这个父元素定位。
.container {
position: relative;
}
复制代码
接下来将子元素的定位方式都设置为absolute,给左右两边的盒子设定宽度以及定位的依据
.container > div {
position: absolute;
height: 500px;
}
.right, .left {
width: 100px;
background: #f00;
}
.left {
left: 0;
}
.right {
right: 0;
}
复制代码
需要理解的就是中间盒子的定位依据了
.center {
left: 100px;
right: 100px;
background: #0f0;
}
复制代码
设定left和right为左右盒子的宽度就行,这样既不会覆盖左右盒子,也因为没有定宽,所以就能实现自身的宽度依据父元素的宽度自适应。
完整代码看这里
方式三:table布局
table标签本是一个自适应的标签,所以使用table很容易实现这样的布局,但是我们这里讲解的是使用display属性,而不用table标签,因为使用table标签会带来一些副作用。
先看dom结构, 循规蹈矩的结构
<div class="container">
<div class="left">
left
</div>
<div class="center">
center
</div>
<div class="right">
right
</div>
</div>
复制代码
再看看css样式。
首先给父容器container定义display属性为table,并且将宽度设为100%。
.container {
display: table;
width: 100%;
}
复制代码
其次,将父容器下的子标签display设置为table-cell,也就是表格的单元格。
想想看表格的单元格有什么特性,对的,如果一个单元格没有设定宽度值,那么就会填充剩下的宽度,所以我们利用这个特性,将左右两边的盒子设定一个固定的单宽度值,中间的盒子就自动填充剩下的宽度了,css如下所示:
.container > div {
display: table-cell;
height: 500px;
}
.left, .right {
background: #f00;
width: 100px;
}
.center {
background: #0f0;
}
复制代码
就是这么简单,完整代码看这里
方式四:flex布局
用flex方式实现圣杯布局,只需关键的两行代码。
dom结构同上
<div class="container">
<div class="left">
left
</div>
<div class="center">
center
</div>
<div class="right">
right
</div>
</div>
复制代码
首先将父元素display设置为flex,将子元素设定一个固定的高度
.container {
display: flex;
}
.container > div {
height: 500px;
}
复制代码
其次设定left和right盒子的宽度
.left, .right {
background: #f00;
width: 100px;
}
复制代码
最后将center的flex-gorw设定为1,flex-grow属性的作用是,对于父容器剩余空间的分配,因为只有一个center盒子没有定义宽度,所以设置为1,那么就会自动填满剩下的空间。
.center {
flex-grow: 1;
background: #0f0;
}
复制代码
完整代码
看这里
终极大法:grid布局
对于grid布局,我只能用一个字来形容“强强强强强强强强强强~~悍” 因为实现圣杯布局,只需要两行代码。
dom结构同上。
<div class="container">
<div class="left">
left
</div>
<div class="center">
center
</div>
<div class="right">
right
</div>
</div>
复制代码
CSS如下
.container {
display: grid;
grid-template: 500px / 100px 1fr 100px
}、
复制代码
解释一下,display: grid; 声明该盒子是grid布局。
grid-template: 500px / 100px 1fr 100px 中500px指的是行高,100px 1fr 100px 中的100px代表左右两列的宽度,中间的1fr表示,中间的盒子也就是center填满剩下的内容。
至于下面的css,那都是用来修饰的啦。
.left, .right {
background: #f00;
}
.center {
background: #0f0;
}
复制代码
后序
该篇讲解方式的顺序大致可以理解成浏览器布局的进化,所以再不学习,你就跟不上啦。
该篇所有的代码可以在这里查看
码字不易,点个赞吧,嘻嘻