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

定义

在前端面试中,面试官让面试者手写圣杯布局的概率较高,因为它能有效检验面试者对CSS布局原理和实践技巧的掌握程度,尤其体现了浮动、负边距、定位等核心知识的理解和应用能力。

定义:三栏布局,等高,左右两栏leftright两边固定宽度,中间栏center随窗口的宽度变化而变化,左右两栏固定宽高不会随之变化

1. float实现

复杂版

float实现圣杯布局挺难理解的,不过理解之后我相信你对float,margin,相对定位这些概念会有新的认识

实现:,将leftrightcontent,三个容器全部浮动,这样三个容器就在一行了

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-leftleft是该布局的关键:

1.当三个容器设置浮动,左右两个容器没有平移的时候:

因为父容器设置了padding-rightpadding-left,第一行没有剩余的空间,所以leftright容器会在第二行显示,又因为,contentleftright三个容器其实是在同一行(left实际上是贴着content后面,因为没有空间才掉到后面)所以,left容器并没有贴着最左边虽然设置的属性是float:left

2. 使用margin-left将容器移动到content容器内之后再使用相对定位校正位置

接下来就是过程难点了

a.left容器的移动过程:

left容器使用margin-left:-100%

因为padding的原因,浮动元素并不能显示在父容器padding的区域,所以通过相对定位校正位置

b. right容器的移动过程:

也是因为padding的原因首先要将,right容器移动到content容器中才能到第一行显示,之后再通过相对定位校正

最后通过相对定位实现效果:

简易版

这里也有种更加简单的浮动实现圣杯布局:直接通过先渲染两个左右leftright浮动的容器,再将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布局将三个容器在排列在一行,leftright设置固定的宽度,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. 绝对定位实现

leftright定位贴在左右两边,中间的content使用定位左右两边的间距为leftright的宽度

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. 绝对定位:将左右leftright两个容器定位贴在左右两边,content左右两边的距离设置为左右容器宽
相关推荐
200不是二百几秒前
Vuex详解
前端·javascript·vue.js
滔滔不绝tao5 分钟前
自动化测试常用函数
前端·css·html5
码爸33 分钟前
flink doris批量sink
java·前端·flink
深情废杨杨34 分钟前
前端vue-父传子
前端·javascript·vue.js
J不A秃V头A2 小时前
Vue3:编写一个插件(进阶)
前端·vue.js
司篂篂2 小时前
axios二次封装
前端·javascript·vue.js
姚*鸿的博客2 小时前
pinia在vue3中的使用
前端·javascript·vue.js
宇文仲竹3 小时前
edge 插件 iframe 读取
前端·edge
Kika写代码3 小时前
【基于轻量型架构的WEB开发】【章节作业】
前端·oracle·架构
天下无贼!4 小时前
2024年最新版Vue3学习笔记
前端·vue.js·笔记·学习·vue