“圣杯布局”是啥?我们来手撕一下

定义

在前端面试中,面试官让面试者手写圣杯布局的概率较高,因为它能有效检验面试者对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;  }

总结

四种方式实现圣杯布局:

  1. float实现:左右浮动+外边;三个容器一起浮动+margin+相对定位
  2. flex:左右设置为固定值flex:0,0,固定值,中间容器设置为flex:1
  3. grid:父容器设置属性值:grid-template-columns:固定值,auto,固定值
  4. 绝对定位:将左右left,right两个容器定位贴在左右两边,content左右两边的距离设置为左右容器宽
相关推荐
Csvn1 小时前
WASM
前端
利威尔xu2 小时前
Go IM 源码实战(14):本地缓存快 3000 倍,失效却难 10 倍
后端·缓存·微服务·面试·golang
修己xj2 小时前
我用 AI 给自己写了一个 Markdown 编辑器,然后把它开源了
前端
FRing033 小时前
vue2干货总结2(v-bind、v-for、v-model、指令修饰符、v-bind操作class和style)
开发语言·前端·vue.js·vue2
幸运小猿3 小时前
模拟慢上传-处理超时重试image 丢失线上问题
前端·javascript·html
利威尔xu3 小时前
Go IM 源码实战(13):30 个会话只有 2 个红点,未读数错在三条路径
redis·后端·微服务·面试·golang
moshuying5 小时前
网购能买Token了!
前端
h_65432105 小时前
echarts实现柱状图加一条横线
前端·echarts
风骏时光牛马5 小时前
生成一个后端标题,只需要一个标题,不需要其他的任何文本。
前端
子非鱼@Itfuture5 小时前
关于前后端联调中登录状态/登录信息失效?
java·前端