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

定义

在前端面试中,面试官让面试者手写圣杯布局的概率较高,因为它能有效检验面试者对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左右两边的距离设置为左右容器宽
相关推荐
web1828548251211 分钟前
ctfshow-web 151-170-文件上传
前端·状态模式
轻口味16 分钟前
【每日学点鸿蒙知识】Web请求支持Http、PDF展示、APP上架应用搜索问题、APP备案不通过问题、滚动列表问题
前端·http·harmonyos
一棵开花的树,枝芽无限靠近你25 分钟前
【PPTist】表格功能
前端·笔记·学习·编辑器·ppt·pptist
马船长1 小时前
RCE-PLUS (学习记录)
java·linux·前端
学前端的小朱1 小时前
修改输出资源的名称和路径、自动清空上次打包资源
前端·webpack·打包工具
嘤嘤怪呆呆狗1 小时前
【开发问题记录】执行 git cz 报require() of ES Module…… 错误
前端·javascript·vue.js·git·vue
夜斗(dou)2 小时前
谷歌开发者工具 - 网络篇
前端·网络·chrome devtools
常常不爱学习2 小时前
CSS盒子模型(溢出隐藏,块级元素和行级元素的居中对齐,元素样式重置)
前端·css
风抽过的烟头2 小时前
Python提取字符串中的json,时间,特定字符
前端·python·json
SomeB1oody3 小时前
【Rust自学】6.3. 控制流运算符-match
开发语言·前端·rust