CSS复习_圣杯布局和双飞翼布局之间的区别,并实现一下

127 阅读5分钟

圣杯布局和双飞翼布局

是什么

首先从我们要实现的需求触发:

  • 现在想要实现一个三列布局,从上到下分为三个区域:header,footer,content;中间内容区域从左网友又分为:left,right,middle;
  • header和footer的高度一直,宽度为浏览器的宽度;
  • 中间content区域中,left和right的宽度一致;
  • middle自适应除掉left和right的宽度,且高度为三栏中的最高高度;
  • 而且需要保证在页面渲染的时候middle主列需要优先渲染;

其实无论是圣杯布局还是双飞翼布局,只是实现这个布局需求的方式。而且实现上都是利用浮动,然后调整margin来实现,不同的地方是对于中间middle的处理方式;

在看到这个需求的时候,可能会疑惑,为什么不用flex布局,很简单就可以实现了;这个点就在【先加载中间内容 再加载左右】,使用flex布局加载的顺序是左中右,如果左边加载很慢,页面就会空掉;

这两种布局刚开始的准备代码是一样的,如下所示:(可以根据实现思路一步步添加,然后体会)

html代码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="style.css" />
    <title>Good, Cheap, Fast</title>
  </head>
  <body>
    <h2>双飞翼布局</h2>
    <div class="header">header</div>
    <div class="content">
      <!-- 为了保证中间区域优先加载 -->
      <div class="middle col-common">middle</div>
      <div class="left col-common">left</div>
      <div class="right col-common">right</div>
    </div>
    <div class="footer">footer</div>
  </body>
</html>

CSS代码:

.body {
  min-width: 600px;
}
.header, .footer {
  width: 100%;
  height: 100px;
  background-color: aquamarine;
}
.content {
  background-color: bisque;
  /* 浮动脱离文档流,创建BFC */
  overflow: hidden;
}

/* 三列的公共样式 */
.col-common {
  height: 300px;
  float: left;
}
.left {
  width: 200px;
  background-color: pink;
}

.middle {
  width: 100%;
  background-color: peru;
}
.right {
  width: 200px;
  background-color: salmon;
}

圣杯布局

圣杯布局主要利用content区域的padding,调整三列的margin来实现,具体实现思路如下:

  • 首先给内容区域content加一个左右padding;
  • 然后给left和right设置margin,left区域相对于它左边的middle区域设为-100%,因为middle的宽度就是100%;right区域设置-200px,因为自身的宽度就是200px,这样三栏就在一行上显示了;但是现在显然left和right覆盖了middle的区域,这个效果并不是我们想要的;
  • 所以,我们就要解决这个问题,这里采用的是position: relative,相对于自身进行定位,left需要向左移200px,也就是content区域的padding大小;right需要向右移动200px;看到这也就明白为啥padding的大小需要和left和right的宽度一致了。

但是为什么叫圣杯布局呢?

实现

html代码如下:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="style.css" />
    <title>Good, Cheap, Fast</title>
  </head>
  <body>
    <h2>圣杯布局</h2>
    <div class="header">header</div>
    <div class="content">
      <!-- 为了保证中间区域优先加载 -->
      <div class="middle col-common">圣杯布局主要是利用padding和margin来实现;<br/>首先给内容区域content加一个左右padding;<br/>然后给left和right设置margin,left区域相对于它左边的middle区域设为-100%,因为middle的宽度就是100%;right区域设置-200px,因为自身的宽度就是200px,这样三栏就在一行上显示了;但是现在显然left和right覆盖了middle的区域,这个效果并不是我们想要的;<br/>所以,我们就要解决这个问题,这里采用的是position: relative,相对于自身进行定位,left需要向左移200px,也就是content区域的padding大小;right需要向右移动200px;看到这也就明白为啥padding的大小需要和left和right的宽度一致了。</div>
      <div class="left col-common">left</div>
      <div class="right col-common">right</div>
    </div>
    <div class="footer">footer</div>
  </body>
</html>

css代码如下:

.header, .footer {
  width: 100%;
  height: 100px;
  background-color: aquamarine;
}

.content {
  background-color: bisque;
  /* 浮动脱离文档流,创建BFC */
  overflow: hidden;
  padding: 0 200px;
}
/* 三列的公共样式 */
.col-common {
  height: 300px;
  float: left;
  position: relative;
}
.left {
  width: 200px;
  margin-left: -100%;
  left: -200px;
  background-color: pink;
}
.middle {
  width: 100%;
  background-color: peru;
}
.right {
  width: 200px;
  margin-left: -200px;
  right: -200px;
  background-color: salmon;
}

效果图:

image.png

双飞翼布局

双飞翼布局主要是在middle区域添加一个子元素,middle-inline,然后通过margin来实现;

  • 调整left区域的margin-left为-100%,因为middle的宽度为100%;right区域的margin-left调整为-200px,自己的宽度;
  • 同样出现了覆盖middle区域的情况,这里通过调整子元素middle-inline的margin来实现,左右的间距就是left和right的宽度

实现

HTML代码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="style.css" />
    <title>Good, Cheap, Fast</title>
  </head>
  <body>
    <h2>双飞翼布局</h2>
    <div class="header">header</div>
    <div class="content">
      <!-- 为了保证中间区域优先加载 -->
      <div class="middle col-common">
        <div class="middle-inline">
          双飞翼布局主要是在middle区域添加一个子元素,middle-inline,然后通过margin来实现;<br/>
          调整left区域的margin-left为-100%,因为middle的宽度为100%;right区域的margin-left调整为-200px,自己的宽度;<br/>
          同样出现了覆盖middle区域的情况,这里通过调整子元素middle-inline的margin来实现,左右的间距就是left和right的宽度
        </div>
      </div>
      <div class="left col-common">left</div>
      <div class="right col-common">right</div>
    </div>
    <div class="footer">footer</div>
  </body>
</html>

css代码:

.body {
  min-width: 600px;
}
.header, .footer {
  width: 100%;
  height: 100px;
  background-color: aquamarine;
}
.content {
  background-color: bisque;
  /* 浮动脱离文档流,创建BFC */
  overflow: hidden;
}

/* 三列的公共样式 */
.col-common {
  height: 300px;
  float: left;
}
.left {
  width: 200px;
  margin-left: -100%;
  background-color: pink;
}

.middle {
  width: 100%;
  background-color: peru;
}
.right {
  width: 200px;
  margin-left: -200px;
  background-color: salmon;
}

.middle-inline {
  margin: 0 200px;
  background-color: lightskyblue;
}

效果图:

image.png

总结

了解了圣杯布局和双飞翼布局的基本实现原理,来对比总结一下吧:

相同点:

  • 两种布局方式都是先加载中间部分,利用浮动和调整margin来实现; 不同点:
  • 圣杯是借助父元素的左右内边距padding,然后子元素定位来实现;
  • 双飞翼是通过为middle添加子元素,利用子元素的左右外边距margin来实现;