Bootstrap

双飞翼布局和圣杯布局

目录

前言

双飞翼布局

圣杯布局

总结


前言

双飞翼布局和圣杯布局都是面试中常考的三栏布局,其共同特点是,内容区分为左中右三部分,其中左右两部分的宽度固定,中间部分的宽度随视口变化。这里简单记录一下这两种布局的实现方式。

双飞翼布局

话不多说,直接写代码,先从较简单的双飞翼布局开始。

注意,下面所说的写代码顺序只是思路顺序,并不是真的反映在代码上的顺序,完整代码后面附上了

给出基本的结构:

  <div class="header"></div>
  <div class="wrapper">
    <div class="center"></div>
  </div>
  <div class="left"></div>
  <div class="right"></div>
  <div class="footer"></div>

注意,页面从上到下,分为了header、内容区、footer三部分,其中header和footer的高度固定,宽度随视口变化。内容区就是我们要操作的三栏布局,需要将center放在最前面,并且加一层wrapper包裹着,然后left和right跟在后面。

那么先把header和footer的样式写好:

    * {
      margin: 0;
      padding: 0;
    }

    .header,
    .footer {
      width: 100vw;
      height: 100px;
    }

    .header {
      background-color: antiquewhite;
    }

    .footer {
      background-color: gold;
    }

最前面的*选择器是清除浏览器默认的padding和margin的,然后就设置了header和footer的宽高、颜色。

接下来要考虑,如何实现三栏布局?

首先需要把wrapper、left、right水平排列,这里采用浮动的办法,让它们三个向左浮动,并顺手设置其高度:

    .wrapper,
    .left,
    .right {
      float: left;
      height: 500px;
    }

这样一来,在内容区下面的footer就需要清除浮动,于是修改footer的样式,在下面添加一行清除浮动即可:

    .footer {
      background-color: gold;
      clear: both;
    }

我们注意到,wrapper包裹了center,并且排在left和right的前面,我们需要把left和right调整到center的两侧。为此,需要在center左右留出固定宽度的部分,用来放置left和right。因此,设置wrapper和center的样式:

    .wrapper {
      width: 100vw;
    }
    .center {
      margin: 0 300px;
      height: 100%;
      background-color: aquamarine;
    }

wrapper的宽度设置为100%,这样就可以铺满屏幕。作为wrapper的子元素,center设置了左右的margin均为300px,可作为left和right放置的地方。接下来就可以设置left和right了:

    .left {
      margin-left: -100vw;
      width: 300px;
      background-color: pink;
    }

    .right {
      margin-left: -300px;
      width: 300px;
      background-color: azure;
    }

逻辑是这样的:如果不设置margin-left, 由于wrapper的宽度是100vw,left和right将会出现在下一行,left紧靠左边,right紧靠left。left距离wrapper的最左侧,就是100vw,因此要想将left移到wrapper最左侧,覆盖掉center左边的margin,就需要给left设置margin-left为-100vw。一旦left设置了左外边距,right就将顶替left的位置,紧靠左侧,这样就需要给right设置margin-left为-300px,让它覆盖掉center右边的margin。

这部分说着逻辑很清楚,但可能不是很好理解,需要动手操作一下试试看。

至此,双飞翼布局已经实现,效果:

附上源码:

<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='UTF-8'>
  <meta http-equiv='X-UA-Compatible' content='IE=edge'>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    .header,
    .footer {
      width: 100vw;
      height: 100px;
    }

    .header {
      background-color: antiquewhite;
    }

    .footer {
      background-color: gold;
      clear: both;
    }

    .wrapper {
      width: 100vw;
    }

    .wrapper,
    .left,
    .right {
      float: left;
      height: 500px;
    }

    .center {
      margin: 0 300px;
      height: 100%;
      background-color: aquamarine;
    }

    .left {
      margin-left: -100vw;
      width: 300px;
      background-color: pink;
    }

    .right {
      margin-left: -300px;
      width: 300px;
      background-color: azure;
    }
  </style>
</head>
<body>
  <div class="header"></div>
  <div class="wrapper">
    <div class="center"></div>
  </div>
  <div class="left"></div>
  <div class="right"></div>
  <div class="footer"></div>
</body>
</html>

圣杯布局

有了双飞翼布局的基础,圣杯布局就容易理解了。其实,圣杯布局和双飞翼布局是一样的,只是实现方式不同而已。

首先给出基本的架构:

  <div class="header"></div>
  <div class="clearfix">
    <div class="center">123456</div>
    <div class="left">45</div>
    <div class="right">545</div>
  </div>
  <div class="footer"></div>

与双飞翼相同的是,center在left和right的前面;不同的是,center外面不需要包裹一层wrapper,而是在center、left、right这三个元素的外层包裹一层clearfix父元素。看这个类名,大概就能猜到,这个父元素起到了清除浮动的作用。

接下来一点点实现。

首先,一样的,给header和footer设置样式:

    * {
      margin: 0;
      padding: 0;
    }

    .header,
    .footer {
      width: 100vw;
      height: 100px;
    }

    .header {
      background-color: rgb(246, 208, 158);
    }

    .footer {
      background-color: salmon;
    }

同样,需要给中间三个元素开启浮动,并顺手设置一下高度:

    .center,
    .left,
    .right {
      float: left;
      height: 500px;
    }

紧接着,设置cleafrfix清除浮动:

    .clearfix::after {
      content: '';
      display: table;
      clear: both;
    }

继续需要想,刚才在双飞翼布局,是让center在左右放出了margin,供left和right显示,那么在这里同样需要这个放置的地方。我们可以给clearfix添加左右padding,这样更容易理解:

    .clearfix {
      padding: 0 300px;
    }

然后,既然是通过clearfix设置了左右padding,center就要填满内容区,来让左右padding部分放置left和right。所以设置center:

    .center {
      width: 100%;
      background-color: pink;
    }

然后就可以设置left和right了,先设置宽度:

    .left,
    .right {
      width: 300px;
    }

考虑,clearfix中的三个元素浮动,而且center的宽度是100%,那么left和right就被挤到下一行了。所以,要给left设置margin-left为-100%,让它跨过center,到达clearfix的左侧padding:

    .left {
      background-color: blanchedalmond;
      margin-left: -100%;
    }

同样,right需要设置margin-left为-300px,放置在clearfix的右侧padding上:

    .right {
      background-color: aquamarine;
      margin-left: -300px;
    }

这样得到的效果如图:

这显然还没有达到目的。回顾一下,给left设置margin-left为-100%,的确跨过了与父元素宽度相等的长度左移,于是从center最右侧移到了center最左侧,right也是同理。所以还需要进一步移动一下,办法就是,给left和right再开启相对定位,分别左移和右移:

    .left,
    .right {
      width: 300px;
      position: relative;
    }

    .left {
      background-color: blanchedalmond;
      margin-left: -100%;
      left: -300px;
    }

    .right {
      background-color: aquamarine;
      margin-left: -300px;
      right: -300px;
    }

 移动好了之后看效果:

成功!

附上源码:

<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='UTF-8'>
  <meta http-equiv='X-UA-Compatible' content='IE=edge'>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    .header,
    .footer {
      width: 100vw;
      height: 100px;
    }

    .header {
      background-color: rgb(246, 208, 158);
    }

    .footer {
      background-color: salmon;
    }

    .clearfix {
      padding: 0 300px;
    }

    .clearfix::after {
      content: '';
      display: table;
      clear: both;
    }

    .center,
    .left,
    .right {
      float: left;
      height: 500px;
    }

    .center {
      width: 100%;
      background-color: pink;
    }

    .left,
    .right {
      width: 300px;
      position: relative;
    }

    .left {
      background-color: blanchedalmond;
      margin-left: -100%;
      left: -300px;
    }

    .right {
      background-color: aquamarine;
      margin-left: -300px;
      right: -300px;
    }
  </style>
</head>
<body>
  <div class="header"></div>
  <div class="clearfix">
    <div class="center">center</div>
    <div class="left">left</div>
    <div class="right">right</div>
  </div>
  <div class="footer"></div>
</body>
</html>

总结

本文使用简单的方法实现了两种常见的三栏布局。由于水平有限,其中难免存在谬误,希望大家轻喷,不吝赐教!

;