如何实现一个三列布局? 双飞翼和圣杯

268 阅读2分钟

如何实现一个三列布局

  • 首先我想到, 使用flex不就可以快速实现了吗?
<div class="container">
  <div class="column">left</div>
  <div class="column">main</div>
  <div class="column">right</div>
</div>

.container {
  display: flex;
  .column {
    felx: 1;
  }
}

三列会自动适应平分区域, 按照从左到右的顺序排列, 如果需要中间内容比两边宽可以设置 flex: 2

  • 问题产生了:当我们需要加载页面的时候, 会按照从左到右的顺序进行加载, 主页面的内容得不到优先显示, 在内容过多, 特别是侧边栏有过多内容时就会加载很久。

  • 这里我们需要了解下浏览器的工作原理, 可以看一下这一个 juejin.cn/post/736841…

好了,可以让中间的主内容优先加载吗?

  • 先把 main 放到前面,这样构建的时候会先被挂载
    <div class="container">
        <div class="main">main</div>
        <div class="left">left</div>
        <div class="right">right</div>
    </div>

但是这样不对了,main 的内容是先加载了,但是位置变成了,main,left,right。

  • 调整一下吧,利用 margin-left,可以设置负宽度,把左右两边固定一下。
    .main{
        float: left;
        width: 100%;
        height: 200px;
    }
    .left{
        float: left;
        height: 200px;
        width: 200px;
        margin-left: -100%;
    }
    .right{
        float: left;
        height: 200px;
        width: 200px;
        margin-left: -200px; // 注意这里的宽度需要和 width 一致
    }
  • 两边的内容把中间的覆盖了,给container添加内边距,让 main 内容居中,为左右两边留出空位。
.container {
    padding-left: 220px;
    padding-right: 220px;
}
  • 两边出现空白了,都被 padding 给挤到中间去了。设置一下相对定位
.left {
  position: relative;
  left: -220px;
}
.right {
  position: relative;
  right: -220px;
}

现在,圣杯布局实现了

  1. 主内容优先加载
  2. DOM 树结构较简单
  3. CSS 比较复杂

那么什么是双飞翼布局?

  • 在 main 的外面包裹一层 wrap
<div class="wrap">
    <div class="main"></div>
</div>
    <div class="left"></div>
    <div class="right"></div>
  • 思路其实和圣杯布局很像,依然需要为两边留出空间。

这一次有了 wrap 包裹,在 main 中设置 margin 即可。

.wrap {
  float: left;
  width: 100%;
}
.main {
  height: 200px;
  margin-left: 220px;
  margin-right: 220px;
}

左右其实还是使用 margin-left 的方式固定。

区别在于

  • 双飞翼的 DOM 结构要更复杂一些,但是不用使用 relative 进行相对定位。