三栏布局常见方案

三栏布局(两边固定,中间自适应) 常用方案及演变过程

1. 浮动方式:

实现关键点: 要把中间放在左右块的后面,然后左右设置左右浮动即可。

优点: 简单
缺点: 中间 main 不能清除浮动,宽度较小布局混乱

代码

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>浮动实现三栏布局</title>
    <style>
      .header {
        width: 100%;
        height: 200px;
        background-color: black;
      }
      .footer {
        width: 100%;
        height: 200px;
        background-color: black;
      }
      .left {
        float: left;
        width: 300px;
        height: 300px;
        background-color: aqua;
      }
      .right {
        float: right;
        width: 300px;
        height: 300px;
        background-color: blue;
      }
      .center {
        background-color: blueviolet;
        margin: 0 310px;
        height: 300px;
      }
    </style>
  </head>
  <body>
    <div class="header"></div>
    <div class="wrapper">
      <div class="left"></div>
      <div class="right"></div>
      <div class="center"></div>
    </div>
    <div class="footer"></div>
  </body>
</html>

2. 绝对定位方式:

实现关键点: 左右绝对定位 中间用 margin 撑开

优点:容易理解和上手
缺点:浏览器宽度较小会出现重叠


代码

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>绝对定位实现三栏布局</title>
    <style>
      .header {
        width: 100%;
        height: 200px;
        background-color: black;
      }
      .footer {
        width: 100%;
        height: 200px;
        background-color: black;
      }
      /* 变化部分 */
      .left {
        position: absolute;
        left: 0;
        top: 0;
        width: 300px;
        height: 300px;
        background-color: aqua;
      }
      .right {
        position: absolute;
        right: 0;
        top: 0;
        width: 300px;
        height: 300px;
        background-color: blue;
      }
      .center {
        background-color: blueviolet;
        margin: 0 310px;
        height: 300px;
      }
      .wrapper {
        position: relative;
      }
    </style>
  </head>
  <body>
    <div class="header"></div>
    <div class="wrapper">
      <div class="left"></div>
      <div class="right"></div>
      <div class="center"></div>
    </div>
    <div class="footer"></div>
  </body>
</html>

停,要开始讲道理了

生产改进要求

中间栏优先渲染运行任意列高度最高

陷入沉思

中间栏优先,浮动是挂了,绝对定位还能抢救下,先看看国外提出的圣杯布局和淘宝玉伯的双飞翼布局

圣杯布局

初版

实现要点:

1.子元素都左浮动,
2.设置主体部分宽度为 100%
3.设置左边 margin-left 为-100%让其换到上一行,右边 margin-left 为负本身宽度
4.主容器设置左右 padding
5.设置三部分都为相对定位,将两部分移动到两侧留白,left 和 right 设置为-宽度

缺点:圣杯破碎 当中间块宽度小于左边块时,布局错乱

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>圣杯布局</title>
    <style>
      .header {
        width: 100%;
        height: 200px;
        background-color: black;
      }
      .footer {
        width: 100%;
        height: 200px;
        background-color: black;
      }
      /* 变化部分 */
      .left {
        position: relative;
        left: -310px;
        float: left;
        margin-left: -100%;
        width: 300px;
        height: 300px;
        background-color: aqua;
      }
      .right {
        position: relative;
        right: -310px;
        float: left;
        margin-left: -300px;
        width: 300px;
        height: 300px;
        background-color: blue;
      }
      .center {
        float: left;
        background-color: blueviolet;
        height: 300px;
        width: 100%;
      }
      .wrapper {
        padding: 0 320px;
      }
      .clearfix::after {
        display: block;
        content: ' ';
        height: 0;
        visibility: hidden;
        clear: both;
      }
    </style>
  </head>
  <body>
    <div class="header"></div>
    <div class="wrapper clearfix">
      <div class="center"></div>
      <div class="left"></div>
      <div class="right"></div>
    </div>
    <div class="footer"></div>
  </body>
</html>

绝对定位版

实现要点: 把前面普通版的 main 移到主容器最前即可

缺点:高度不可控,会无法支撑起 wrapper, 宽度较小出现覆盖

双飞翼布局

实现要点:

与圣杯处理不同之处在于中间被遮挡内容的处理,在 main 中包裹一个 div 设置左右 margin 来处理

优点: 比原始圣杯布局写法要简单,解决了圣杯破碎和绝对定位高度支撑问题
缺点: 增加了一个 div,增加了渲染成本
允许任意列最高


代码

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>双飞翼布局</title>
    <style>
      .header {
        width: 100%;
        height: 200px;
        background-color: black;
      }
      .footer {
        width: 100%;
        height: 200px;
        background-color: black;
      }
      /* 变化部分 */
      .left {
        float: left;
        margin-left: -100%;
        width: 300px;
        height: 300px;
        background-color: aqua;
      }
      .right {
        float: left;
        margin-left: -300px;
        width: 300px;
        height: 300px;
        background-color: blue;
      }
      .center {
        float: left;
        background-color: blueviolet;
        height: 300px;
        width: 100%;
      }
      .content {
        margin: 0 310px;
        height: 300px;
        background-color: brown;
      }
      .wrapper {
      }
      .clearfix::after {
        display: block;
        content: ' ';
        height: 0;
        visibility: hidden;
        clear: both;
      }
    </style>
  </head>
  <body>
    <div class="header"></div>
    <div class="wrapper clearfix">
      <div class="center">
        <div class="content">

        </div>
      </div>
      <div class="left"></div>
      <div class="right"></div>
    </div>
    <div class="footer"></div>
  </body>
</html>

flex 版

实现要点:利用 flex 的 order 属性移动

优点: 集双飞翼的优点一身,还要简单的多
缺点:兼容性! 兼容性! 兼容性!

代码

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>flex终极版</title>
    <style>
      .header {
        width: 100%;
        height: 200px;
        background-color: black;
      }
      .footer {
        width: 100%;
        height: 200px;
        background-color: black;
      }
      /* 变化部分 */
      .left {
        order: -1;
        width: 300px;
        height: 300px;
        background-color: aqua;
      }
      .right {
        width: 300px;
        height: 300px;
        background-color: blue;
      }
      .center {
        background-color: blueviolet;
        height: 300px;
        flex: 1;
      }
      .wrapper {
        display: flex;
      }
    </style>
  </head>
  <body>
    <div class="header"></div>
    <div class="wrapper">
      <div class="center">
      </div>
      <div class="left"></div>
      <div class="right"></div>
    </div>
    <div class="footer"></div>
  </body>
</html>

总结

我习惯了对一个问题的发展过程进行了解,发掘每部分解决方案的优点和缺点,当然,文章是有意编排了顺序,是想大家有了一个从不完善的版本到完善版本过渡,也不能说拿到最大的锤子,就是干,程序员要做的就是在当前状况选择一个合适的方案。

想要点小星星

学习前端已经半年有余了,css方面能够认识到张鑫旭大佬,js方面有<<你不知道的JavaScript>>这位良师,还有阮一峰大佬的ES6,让我了解到前端的宿命就是精通html、css、js三门语言,任重而道远,在读了张大大的文章后有感,平时遇到问题,自己去尝试,主动犯错,了解不一样的深度,然后把知识点通过自己的脑子转换一下,重组为自己的东西,更重要的是,我不是一个无私的利他主义者,我还是需要一些鼓励,更有动力输出文章,希望能有一颗小星星呀。

参考文章

聊聊为什么淘宝要提出「双飞翼」布局
我熟知的三种三栏网页宽度自适应布局方法 张大大
浪里白条 三栏布局

posted @ 2019-04-12 15:49  兴趣使然的Geek  阅读(219)  评论(0编辑  收藏  举报