盘点那些前端程序员必须掌握的网页布局

1,874 阅读4分钟

前言

本文整理了那些普遍用于网页设计中常见布局, 比如双飞翼, 圣杯, 瀑布流等布局结构, 并针对每个步骤做一个解析, 希望我的分析能够对各位的理解有所帮助, 与此同时求👍!

思维导图

image.png

常见三栏布局

我觉得三栏布局是网页布局的核心, 如果掌握了三栏布局的精髓, 其他布局也会迎刃而解。

首先是网页主体的代码:

 <div class="header">Header</div>
  <div class="container">
    <div class="middle">Middle</div>
    <div class="left">Left</div>
    <div class="right">Right</div>
  </div>
 <div class="footer">Footer</div>

注意: Middle 应在 Left 与 Right 之前, 保证浏览器优先解析 Middle 的内容。

1. flex 布局

注意:

  • 使用 order: -1 使 Left 排在最前。
  • 外层 body 的 flex 竖排序, 内层 container 设置 flex: 1 高度最大化, 内部 Middle 宽度最大。

效果:

image.png

代码:

    html, body {
      height: 100%; // 撑满全屏
    }
    body {
      display: flex;
      flex-direction: column;
      justify-content: flex-start;
      align-items: center;
    }
    .container {
      flex: 1;
      width: 100%;
      background-color: #fff;
      display: flex;
      justify-content: flex-start;
      align-items: center;
    }
    .container .middle{
      height: 100%;
      text-align: center;
      width: 100%;
      background-color: green;
    }
    .container .left {
      height: 100%;
      text-align: center;
      width: 200px;
      order: -1;
      background-color: red;
    }
    .container .right {
      height: 100%;
      width: 180px;
      background-color: blue;
    }

2. Grid 布局

效果:

image.png

    html, body {
      height: 100%;
    }
    body {
      display: grid;
      width: 100%;
      grid-template-columns: 200px auto 180px;
      grid-template-rows: 80px auto 80px;
    }
    .header {
      grid-column-start: 1;
      grid-column-end: 4;
      background-color: #eee;
      text-align: center;
      line-height: 80px;
      font-size: 20px;
    }
    .middle {
      grid-row-start: 2;
      grid-row-end: 3;
      grid-column-start: 2;
      grid-column-end: 3;
      text-align: center;
      background-color: green;
    }
    .left {
      grid-column-start: 1;
      grid-column-end: 2;
      grid-row-start: 2;
      grid-row-end: 3;
      text-align: center;
      background-color: red;
    }
    .right {
      grid-row-start: 2;
      grid-row-end: 3;
      grid-column-start: 3;
      grid-column-end: 4;
      text-align: center;
      background-color: blue;
    }
    .footer {
      grid-column-start: 1;
      grid-column-end: 4;
      background-color: #eee;
      text-align: center;
      line-height: 80px;
      font-size: 20px;
    }

3. 圣杯布局

利用浮动实现三栏布局, 其中涉及到几个有意思的知识点值得好好回味一下。

具体步骤:

  1. 需要设置 Container 的内边距 (Padding) 为 Left, Right预留空间, 并使 Middle, Left, Right 浮动。
  2. Middle 占据所有 Container 宽度, 此时 Left 与 Right 由于浮动流会自动换行。
  3. 设置 margin-left: 100% 减少 Left 占用的空间, 预留出 Middle 的部分, Left 就能够与 Middle 同行, 其中 margin-left: 100% 参照的是父元素 Container 的宽度, 也就是 Middle 的宽度。
  4. 此时 Left 的图像会与 Middle 重叠, 所以还需要使用绝对定位 position: relative; left: 200px 将 Left 的图像左移。
  5. Right 同理, 但设置 margin-right 为Right的宽度, 记得最后还要消除浮动喔!

效果:

image.png

代码:

    .container {
      padding: 0 180px 0 200px;
      background-color: #eee;
    }
    .left, .right, .middle {
      float: left;
    }
    .container .middle {
      width: 100%;
      background-color: cadetblue;
    }
    .container .left {
      margin-left: -100%;
      position: relative;
      left: -200px;
      width: 200px;
      background-color: aquamarine;
    }
    .container .right {
      width: 180px;
      margin-right: -180px;
      background-color: coral;
    }

圣杯布局是三栏布局的优化方案之一, 能够兼容许多老版本的浏览器, 但是如果 Middle 的宽度小于 Left 的宽度时, 会导致圣杯布局的坍塌, 原因在于 margin-left 等价于 Middle 的宽度, margin-left 不足以释放出 Left 所占据的位置。

image.png

这时候有两种解决方案, 一种是给 Middle 设置一个最小宽度 min-width, 另一种方案可以采用双飞翼布局。

4. 双飞翼布局

双飞翼布局是圣杯布局的改进版, 原理简单来说就是在 Middle 之上添加一层 DOM 层, 这里叫做Center, 然后让Center, Left, Right 同层, 通过设置 Middle 在 Center 中的位置 (通过外边距 margin ), 使其居中。

双飞翼布局支持任意宽高变化, 但同时也增加了 dom 层数, 提高了生成渲染树的代价。

代码最主要的修改在于:

  1. 用 div 包裹 Middle, 这里取名为 Center, 设置float
  2. Left 与 Right 同圣杯布局设置 margin 负值来避免 float flow 的换行。
  3. 此时 Center, Left, Right 处于同行, 但 Middle 与 Left 与 Right 存在重叠
  4. Middle 设置 margin 来校对 Middle 在 Center 中的位置。

效果:

image.png

代码:

  <div class="header">
    Header
  </div>
  <div class="container">
    <div class="center">
      <div class="middle">Middle</div>
    </div>
    <div class="left">Left</div>
    <div class="right">Right</div>
  </div>
  <div class="footer">
    Footer
  </div>
    .container {
      background-color: #eee;
      width: 100%;
    }
    .left, .right, .center {
      float: left;
    }
    .container .center {
      width: 100%;
    }
    .container .center .middle {
      margin: 0 180px 0 200px;
      background-color: cadetblue;
    }
    .container .left {
      width: 200px;
      margin-left: -100%;
      background-color: aquamarine;
    }
    .container .right {
      width: 180px;
      margin-left: -180px;
      background-color: coral;
    }
    .footer {
      clear: both;
      background-color: #aaa;
      text-align: center;
    }

实用布局

(只涉及布局实现)

1. flex 实现瀑布流

要点:

  1. 图片设置宽度, 高度auto
  2. 怕img标签重复麻烦可以使用img[src="./img/1 ($).jpg"]*9

效果:

image.png

  <div class="container">
    <div class="column">
      <img src="./img/1 (1).jpg" alt=""><img src="./img/1 (2).jpg" alt=""><img src="./img/1 (3).jpg" alt="">
    </div>
    <div class="column">
      <img src="./img/1 (4).jpg" alt=""><img src="./img/1 (5).jpg" alt=""><img src="./img/1 (6).jpg" alt="">
    </div>
    <div class="column">
      <img src="./img/1 (7).jpg" alt=""> 
    </div>
  </div>
    html, body {
      height: 100%;
      width: 100%;
      padding: 0;
      margin: 0;
      background-color: #000;
    }
    .container {
      height: 100%;
      width: 80%;
      margin-left: 10%;
      margin-right: 10%;
      display: flex;
      justify-content: space-around;
      background-color: silver;
    }
    .column {
      width: 200px;
      display: flex;
      flex-direction: column;
      background-color: #fff;
    }
    .element {
      margin-bottom: 20px;
    }
    img {
      width: 100%;
      height: auto;
    }

横向同理, 不过要将高度设为定制, 宽度auto。