圣杯布局的实现

610 阅读3分钟

相信大家在网上冲浪的时候,所看见的大部分网站,都是中间的核心页面先显示出来,左右两边大部分是不怎么重要的广告或者网站介绍。这样的布局模式体现在国内很多网站上,所以这类布局模式也被技术大牛起了个形象的名字——“圣杯布局”,我个人理解呢,是说中间的主体部分最大也最为重要,左右两边就像杯子的把手一样镶在主体内容上,至于为什么和王者荣耀的装备同名,我想大概是为了回蓝更快吧.....

【法师最缺啥?蓝条啊!!!】

【像不像这模样?】

蓝色为主体部分,红色+绿色为把手

就用这篇文章来记录我个人对圣杯布局的理解,仅供参考。

先来个具体的要求:

要求:针对如下DOM结构,编写CSS,实现三栏水平布局,其中left、right分别位于左右两侧,left宽度为200px,right宽度为300px,main处在中间,宽度自适应。允许增加额外的DOM节点,但不能修改现有节点顺序。

<div class="container">
    <div class="main">main</div>
    <div class="left">left</div>
    <div class="right">right</div>
</div>

理解一下意思,main布局在前,在浏览器中优先渲染展示,中间宽度自适应,左右限宽。

那代码写起来吧,还能咋地!

先把基本样式写一下:

.left, .main, .right {
  min-height: 200px;
}
//限制高度,保持一致
.left {
  background: red;
  width: 200px;
}
.main {
  background-color: blue;
}
.right {
  background-color: green;
  width: 300px;
}

圣杯布局是相对的,所以要先把container的位置固定好

.container{
    padding: 0 300px 0 200px;
}

这个时候左右两边的200px 和 300px 的位置就预留出来了。

现在我们要做的,就是让三个模块都向左浮动,在调整左右两边的位置即可 代码奉上:

.main,.left,.right{
    min-height: 200px;
    float: left;
}

咦?怎么层到一起了?莫慌,我们来把它们拉开点!

.left{
    width: 200px;
    background: red;
}
.right{
    width: 300px;
    background: blue;
}
.main{
    width: 100%;
    background: green;
}

这下坏了!怎么还掉下去了呢?别急别急,设置负的外边框把它们拉回上一行去!

.left{
    margin-left: -100%;
    width: 200px;
    background: red;
}
.right{
    margin-left: -300px;
    width: 300px;
    background: green;
}

margin-left会让元素向左流动,要是负值过大就会向上一层浮动。

接下来就会发现,诶!main这单词不见了!其实是被left这胖子挡住了,所以,现在只需要把left和right都移动在之前container给他们预留好的位置即可

.main,.left,.right{
    position: relative;
    min-height: 200px;
    float: left;
}
.main{
    width: 100%;
    background: blue;
}
.left{
    background: red;
    width: 200px;
    margin-left: -100%;
    left: -200px;
}
.right{
    background: green;
    width: 300px;
    margin-left: -300px;
    right: -300px;
}

那么,圣杯布局就完成啦! 最后把完整代码奉上:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>圣杯布局</title>
  <style lang="text/css">
    .container {
      padding: 0 300px 0 200px;
    }

    .left,
    .main,
    .right {
      min-height: 130px;
      float: left;
      position: relative;
    }

    .left {
      background: red;
      margin-left: -100%;
      width: 200px;
      left: -200px;
    }

    .main {
      background-color: blue;
      width: 100%;
    }

    .right {
      background-color: green;
      width: 300px;
      margin-left: -300px;
      right: -300px;
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="main">main</div>
    <div class="left">left</div>
    <div class="right">right</div>
  </div>
</body>

</html>