浅谈css三栏布局(包括双飞翼布局和圣杯布局)

三栏布局

三栏布局的概念

  1. 三栏布局的概念听起来,很简单,就是让三列从左到右,依次排列,左边区域和右边区域固定宽,而中间内容区域宽度自适应,就像下面这样

当然要注意:我们这里所说的中间部分宽度自适应就是随着屏幕大小的改变而自己适应的过程。这也是三栏布局产生的原因所在

三栏布局的具体实现以及原理

第一种:浮动三栏布局

HTML代码


 <div class="werppar">
        <div class="left"></div>
        <div class="right"></div>
        <div class="container"></div>
    </div>

下面是 css 代码部分

 .werppar{
            /* 形成bfc块级作用域上下文 ,目的为了清除浮动*/
            overflow: hidden;
            border: 5px solid red;
        }
        .left{
            float: left;
            width: 200px;
            height: 200px;
            background-color: lawngreen;
        }
        .right{
            float: right;
            width: 200px;
            height: 200px;
            background-color: lightcoral;
        }
        .container{
            margin: 0 200px;
            height: 200px;
            background-color: rebeccapurple;
        }
  1. 效果如下


2. 那么这种方法是很简单的,相信各位瞬间就能看懂,不过也有一些需要注意的细节:

  1. 这种办法中 dom节点中,left,right,container,这三个块是不能换顺序的,也就是说这种方法的缺点很明显:浏览器是自上而下解析代码渲染dom树,那么container内容区域不能被优先渲染出来
  2. 至于为什么不能换顺序,大家也很清楚:因为我们要让他们在一行内展示,那么就必须让左右这两个块漂浮起来不占原来的位置了,才能让container区域跻身而入,
第二种定位三栏布局

html

 <div class="werppar">
        <div class="container"></div>
        <div class="left"></div>
        <div class="right"></div>
    </div>

下面是css

.werppar{
            position: relative;
        }
        .left{
            position: absolute;
            top: 0;
            left: 0;
            width: 200px;
            height: 200px;
            background-color: lawngreen;
        }
        .right{
            position: absolute;
            top: 0;
            right: 0;
            width: 200px;
            height: 200px;
            background-color: lightcoral;
        }
        .container{
            margin: 0 200px;
            height: 200px;
            background-color: rebeccapurple;
        }
  1. 效果如下:


2. 看起来,与上面的效果是一摸一样的,方法也相对来说比较简单,实现原理也和前面的浮动差不多,不过它的盒子高度是靠 container 去撑开的,而它的有点就是 container 这次是可以被优先渲染出来了,因为它排在第一位
3. 唯一的缺点就是这种方法无法实现等高布局

第三种:用bfc原理做三栏布局

  1. bfc特性有一点是触发了bfc的盒子不会和浮动的盒子发生重叠,也就是说触发bfc的盒子不会被浮动的盒子盖住,那么问题就解决一半了。来看一下具体实现
    HTML
<div class="werppar">
        <div class="left"></div>
        <div class="right"></div>
        <div class="container"></div>
   </div>

下面是css代码

         .werppar{
           width: 100%;
        }
        .left{
            float: left;
            width: 200px;
            height: 200px;
            background-color: gold;
        }
        .right{
           float: right;
            width: 200px;
            height: 200px;
            background-color: greenyellow;
        }
        .container{
            /*这里形成bfc区域,不会与浮动的元素发生重叠*/
            overflow: hidden;
            height: 200px;
            background-color: palevioletred;
        }

效果如下:

效果还是一样,此时的container区域就是一个bfc区域了,那么它就不会被浮动元素盖住,container的宽度就是减去left的宽度 + right的宽度,剩下的就是自己的区域,这样不用像margin : 0 200px;左右撑开边距,所以也就形成的宽度自适应,不过它的缺点也是显而易见的,不能优先渲染container区域

圣杯布局(重点)
  1. 所谓圣杯布局只不过比起三栏布局多了一个需求:要求container区域优先渲染,那为啥叫做圣杯布局?因为长得像圣杯啊,看下图:
    圣杯
    圣杯的两只手就像布局的左边蓝和右边栏一样,被子的主体就像container内容区域一样,具体的实现如下
    HTML:
 <div class="werppar">
        <div class="container"></div>
        <div class="left"></div>
        <div class="right"></div>
   </div>

css

  *{
            margin: 0;
            padding: 0;
        }
        .werppar{
            background-color: pink;
            /*左右栏通过添加负的margin放到正确的位置了,此段代码是为了摆正中间栏的位置*/
            padding:0 200px;
        }

        .container,.left,.right{
            float: left;
            height: 200px;
        }
        .container{
            width:100%;
            height:200px;
            background:blue;
        }
        .left{
            width:200px;
            height:200px;
            /*margin负值,让移动父级容器的宽度*/
            margin-left:-100%;
            background:#f40;
            /*中间栏的位置摆正之后,左栏的位置也相应右移,通过相对定位的left恢复到正确位置*/
            position:relative;
            left:-200px;
        }
        .right{
            width:200px;
            height:200px;
            margin-left:-200px;
            background:#0c9;
            /*中间栏的位置摆正之后,右栏的位置也相应左移,通过相对定位的right恢复到正确位置*/
            position:relative;
            right:-200px;
        }

可以看下效果图:

这就是所谓的圣杯布局,那么这个原理是什么呢? 其实就是基于两条 1.浮动2.margin负值,我来解释解释

  1. 首先给他们的父级元素,padding || margin 留出左右边栏的位置,并且此段代码是为了摆正中间栏的位置
  2. 在给我们的三个元素浮动起来,然后直接给 container 元素宽度100%,宽度全给了container 了,哪left和right自然会掉下去了
  3. 哪怎么把left和right弄到正确的位置呢? 这里就要用到 magin 的负值了,结合浮动使用,那我们知道浮动起来的几个元素会拍成一行内,而宽度不够才会掉下去,这里就是这种情况,但是我给left元素一个margin-left负值到一个界限,它就会贴回到上一行,因为他们是一起浮动的,所以我们需要负一个它父容器的总宽度,这时候它回到的上一行,此时我们还需要,使用定位将这个left元素,位移到正确的位置,这样就很简单left:-自身宽度即可,
  4. right同理,你可以看作是,本来他就应该在上面的,无奈因为宽度不够,被挤下来了,此时我在给margin一个负的自身宽度,在使用定位right:-200px将其回归到正确的位置,🆗这样就搞定了
方法五:双飞翼布局(重点)
  1. 双飞翼布局其实是根据圣杯布局演化出来的一种布局,具体代码实现如下:
    HTML
 <div class="werppar">
        <div class="box">
            <div class="container"></div>
        </div>
        <div class="left"></div>
        <div class="right"></div>
        <p style="clear: both;"></p>
    </div>

css

      .werppar{
           width:100%;
        }

        .box,.left,.right{
            float: left;
            height: 200px;
        }
        .box{
            width:100%;
            height:200px;
        }
        .container{
            margin : 0 200px;
            height: 200px;
            background:blue;
        }
        .left{
            width:200px;
            height:200px;
            margin-left:-100%;
            background:#f40;
        }
        .right{
            width:200px;
            height:200px;
            margin-left:-200px;
            background:#0c9;
        }

效果如下:

这里我们可以看出,这里面和圣杯布局其实差别不是很大,

  1. 在这里我们可以看出结构发生了改变,我们的内容区域使用一个.box的元素包裹起来了,而且浮动的再也不是.container元素了,这也就是说,container元素不会被外面的浮动元素所影响了
  2. 其次我们可以发现,这里的left:-100%就能回到想要的位置?这是为什么呢,需要注意的一点是,在这里。left父级盒子是宽度100%的,不再是圣杯布局中留出来左右padding值的父级自适应宽度的盒子
  3. 那么同理了,right盒子也是因为这样,所以直接margin-left:-200px正好贴到父级盒子最右边,就能得到想要的位置了
方法六:flex三栏布局
  1. 利用flex弹性盒子可以很轻松的完成三栏布局,并且能够达到content优先渲染的要求
    html
 <div class="flex-box">
        <div class="flex-content flex-item">我是内容</div>
        <div class="flex-left flex-item">我是左边栏</div>
        <div class="flex-right flex-item">我是右边栏</div>
   </div>

css

       .flex-box{
           display: flex;
       }
       .flex-left{
           width: 200px;
           height: 200px;
           background-color: lime;
           order: 0;
       }
       .flex-content{
           order: 1;
           width: 100%;
           background-color: aquamarine;
       }
       .flex-right{
           width: 200px;
           height: 200px;
           background-color: gold;
           order: 2;
       }

这里就很简单了,利用弹性盒子的手法,给子元素添加的属性order,这个属性意思为在主轴方向的排列中显示的优先级,值越小,优先级越高,放在最前的container最先渲染

笔记总结
🆗,就到这里了,我还要继续奋战

posted @ 2019-08-26 21:57  林见夕  阅读(544)  评论(0)    收藏  举报