定义
在前端面试中,面试官让面试者手写圣杯布局的概率较高,因为它能有效检验面试者对CSS布局原理和实践技巧的掌握程度,尤其体现了浮动、负边距、定位等核心知识的理解和应用能力。
定义:三栏布局,等高,左右两栏left
,right
两边固定宽度,中间栏center
随窗口的宽度变化而变化,左右两栏固定宽高不会随之变化
1. float实现
复杂版
float实现圣杯布局挺难理解的,不过理解之后我相信你对float,margin,相对定位这些概念会有新的认识
实现:,将left
,right
,content
,三个容器全部浮动,这样三个容器就在一行了
html中三个容器的渲染位置是这样的:
html
<div class="container">
<div class="content"></div>
<div class="left"></div>
<div class="right"></div>
</div>
css
* {
padding: 0;
margin: 0;
}
.container div {
float: left;
}
.container {
/* box-sizing: border-box; */
height: 100px;
padding-left: 200px;
padding-right: 200px;
background-color: #975656;
}
.content {
height: 100%;
width: 100%;
background-color: #b8b513;
}
.left {
margin-left: -100%;
left: -200px;
position: relative;
height: 100px;
width: 200px;
background-color: #e13939;
}
.right {
position: relative;
height: 100px;
width: 200px;
background-color: #39e151;
margin-left: -200px;
left: 200px;
}
最为关键的两个移动左右两边的属性margin-left
和left
是该布局的关键:
1.当三个容器设置浮动,左右两个容器没有平移的时候:
因为父容器设置了padding-right
,padding-left
,第一行没有剩余的空间,所以left
和right
容器会在第二行显示,又因为,content
和left
,right
三个容器其实是在同一行(left实际上是贴着content后面,因为没有空间才掉到后面)所以,left
容器并没有贴着最左边虽然设置的属性是float:left
2. 使用margin-left将容器移动到content容器内之后再使用相对定位校正位置
接下来就是过程难点了
a.left
容器的移动过程:
left
容器使用margin-left:-100%
因为padding
的原因,浮动元素并不能显示在父容器padding
的区域,所以通过相对定位校正位置
b. right
容器的移动过程:
也是因为padding
的原因首先要将,right
容器移动到content
容器中才能到第一行显示,之后再通过相对定位校正
最后通过相对定位实现效果:
简易版
这里也有种更加简单的浮动实现圣杯布局:直接通过先渲染两个左右left
和right
浮动的容器,再将content
容器的左右外边距设置为左右容器的宽度
css
* {
padding: 0;
margin: 0;
}
.container {
width: 100%;
}
.left,
.right {
width: 200px;
height: 100px;
}
.content {
height: 100px;
background-color: #eae723;
margin-left: 200px;
margin-right: 200px;
}
.left {
float: left;
background-color: #e13939;
}
.right {
float: right;
background-color: #39e151;
}
css
<div class="container">
<div class="left"></div>
<div class="right"></div>
<div class="content"></div>
</div>
效果:
2. flex实现
使用flex布局将三个容器在排列在一行,left
,right
设置固定的宽度,center
设置为flex:1
html
<div class="container">
<div class="left"></div>
<div class="content"></div>
<div class="right"></div>
</div>
css
.container {
display: flex;
height: 100px;
background-color: #975656;
}
.content {
height: 100%;
flex: 1;
background-color: #b8b513;
}
.left {
height: 100px;
flex:0 0 200px;
background-color: #e13939;
}
.right {
height: 100px;
flex: 0 0 200px;
background-color: #39e151;
}
效果:
3. grid实现
通过grid布局实现也非常简单,将通过属性grid-template-columns
来设置两边left
,right
固定宽度,中间content
响应式变化宽度:grid-template-columns: 150px auto 150px;
html
<div class="container">
<div class="left">左侧栏</div>
<div class="content">中间内容区</div>
<div class="right">右侧栏</div>
</div>
css
.container {
display: grid;
grid-template-columns: 150px auto 150px; /* 左侧栏、中间内容区、右侧栏 */
gap: 20px; /* 可选,设置列间距 */
width: 100%;
min-height: 100vh;
}
.left { background: #f00; }
.right { background: #0f0; }
.content { background: #ff0; }
效果:
4. 绝对定位实现
将left
和right
定位贴在左右两边,中间的content
使用定位左右两边的间距为left
和right
的宽度
html
<div class="container">
<div class="left"></div>
<div class="content"></div>
<div class="right"></div>
</div>
css
.container {
display: grid;
grid-template-columns: 150px auto 150px; /* 左侧栏、中间内容区、右侧栏 */
gap: 20px; /* 可选,设置列间距 */
width: 100%;
min-height: 100vh;
}
.left { background: #f00; }
.right { background: #0f0; }
.content { background: #ff0; }
总结
四种方式实现圣杯布局:
- float实现:左右浮动+外边;三个容器一起浮动+margin+相对定位
- flex:左右设置为固定值
flex:0,0,固定值
,中间容器设置为flex:1
- grid:父容器设置属性值:
grid-template-columns:固定值,auto,固定值
- 绝对定位:将左右
left
,right
两个容器定位贴在左右两边,content
左右两边的距离设置为左右容器宽