【经典面试题】圣杯布局以及双飞翼布局原理

什么是圣杯布局以及双飞翼布局


上图就是一个经典的圣杯布局和双飞翼布局的模型,即三列结构,左右两边定宽,中间自适应,能根据屏幕大小做响应。

实现方式

浮动(经典方式)

在介绍这种方式之前要先说一下margin设置负值的作用:

  1. margin-top/margin-left设置负值会将元素拉入对应位置


可以看到,当margin-top负值增大时,元素也跟着上移了,margin-left同理,负值增大会左移,两者都会导致元素溢出视口

  1. margin-right/margin-bottom设置负值会让后续元素拉入


上图看到当margin-right增大时,元素本身不变,后续元素会跟过来并覆盖本元素,margin-bottom同理,负值增大时后续元素会上移并覆盖。

如何实现

  1. 先给出html结构,注意中间自适应的center元素放在最前面:
<body>
  <div id="header">#header</div>
  <div id="container">
    <div id="center" class="column">#center</div>
    <div id="left" class="column">#left</div>
    <div id="right" class="column">#right</div>
  </div>
  <div id="footer">#footer</div>
</body>
  1. 写好header和footer样式,使之横向撑满。

  #header, #footer {
    background: rgba(29, 27, 27, 0.726);
    text-align: center;
    height: 60px;
    line-height: 60px;
  }
  1. 三列的左右两列分别定宽200px和150px,中间部分center设置100%撑满

  .column{
      height: 200px;
  }
  #left{
      width: 200px;
      background-color: aqua;
  }
  #right{
      width: 200px;
      background-color: wheat;
  }
  #center{
      width: 100%;
      background-color: tomato;
  }
  1. 设置全部左浮动,并清除footer浮动

  .column{
      height: 200px;
      float: left;
  }

现在center由于width是100%,所以占据了一整行。

  1. left元素设置margin-left:100%;拉回行头


之前说过,设置margin-left为负值会让元素自身位置发生变化,由于浮动的关系,元素被往左拉了一个center元素的宽度(100%)故回到了开头

  1. right元素设置margin-left: -200px;拉回行尾

  1. 设置padding

现在的问题就是左右两边的元素覆盖了center元素的内容,我们可以给容器main加上两边padding:

  1. 设置定位

在设置了padding后,左右元素都被挤了进来,我们可以设置position:relative解决,因为浮动元素已经脱离了文档流,所以不能设置absolute。
通过设置left和right元素的相对位置,实现定位:

  1. 完整代码
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
</head>
<style>
  body {
    min-width: 550px;  /* 2x leftContent width + rightContent width */
    font-weight: bold;
    font-size: 20px;
  }

  #header, #footer {
    background: rgba(29, 27, 27, 0.726);
    text-align: center;
    height: 60px;
    line-height: 60px;
    clear: both;
  }
  #container{
      padding: 0 200px;
      overflow: hidden;
  }
  .column{
      height: 200px;
      float: left;
      position: relative;
  }
  #left{
      width: 200px;
      margin-left: -100%;
      left: -200px;
      background-color: aqua;
  }
  #right{
      width: 200px;
      margin-left: -200px;
      right: -200px;
      background-color: wheat;
  }
  #center{
      width: 100%;
      background-color: tomato;
  }
</style>

<body>
  <div id="header">#header</div>
  <div id="container">
    <div id="center" class="column">#center</div>
    <div id="left" class="column">#left</div>
    <div id="right" class="column">#right</div>
  </div>
  <div id="footer">#footer</div>
</body>

</html>

flex布局

使用flex布局显得更加简单易懂,原理就是将容器设置为display: flex;

两侧设置固定宽度,并不允许弹性缩放flex: 0; flex-basis: 200px;

中间允许弹性缩放,不设置宽度flex:1;

结语

双飞翼布局其实和圣杯布局的精髓是一样的,都是通过设置负margin来实现元素的排布,不同的就是html结构,双飞翼是在center元素内部又设置了一层inner-center的元素并设置它的左右margin,而非圣杯布局的padding,来排除两边元素的覆盖。所以这两种布局原理基本一样,关键就是在于设置负margin的技巧,和元素浮动的相对定位技巧来实现。

posted @ 2020-01-22 16:17  大地dadi  阅读(794)  评论(0编辑  收藏  举报