css 三栏布局 圣杯布局 双飞翼 flex

来源:互联网 发布:易语言编程视频 编辑:程序博客网 时间:2024/04/29 14:51

前言

三栏布局是常见的布局方式,应用场景:左、右两侧是定宽的导航栏,中间内容自适应。在参考了详解 CSS 七种三栏布局技巧 后,我对三栏布局有了更深刻的认识,本文是我对上文的解读,是自己消化理解的过程,此文是为了加深理解知识而写,希望可以帮到你。
示意图
这里写图片描述

简单的实现方式(流式布局和BFC三栏布局)

实现三栏布局,我们可以采用比较简单的实现方式,也就是详解 CSS 七种三栏布局技巧提到的流式布局BFC 三栏布局,通过左侧向左浮动、右侧向右浮动,最后渲染中间实现;最后渲染中间也就意味着在html中内容div写在最后,在线demo

<div>        <div class="left">这是左侧</div>        <div class="right">这是右侧</div>        <!--内容写在最后-->        <div class="center">这是中间</div>    </div>
   *{        margin:0;        border: 0;    }        .left{            float:left;            width: 100px;            height: 200px;            background-color: green;        }        .right{            float:right;            width: 100px;            height: 200px;            background-color: blue;        }        .center{            height: 200px;            background-color: red;            margin-left: 120px;            margin-right: 120px;        }

效果
这里写图片描述
BFC 三栏布局与流式布局的区别在于,在内容div上应用overflow:hidden产生BFC(block format context),BFC不能与浮动块重叠,如下

*{        margin:0;        border: 0;    }        .left{            float:left;            width: 100px;            height: 200px;            background-color: green;        }        .right{            float:right;            width: 100px;            height: 200px;            background-color: blue;        }        .center{            height: 200px;            background-color: red;            overflow:hidden;        }/*没有间隔,为了产生间隔可以采取在left和right分别添加margin的方式实现*/

这里写图片描述
可以看到,块之间没有间隔,为了产生间隔作者采用了在左、右两块上添加margin来实现,但我在尝试时就想既然内容块与左右不重叠了,直接在内容块加margin:0 10px多好,而且还规整,但是加上后不起作用,后来将数值调为101px才看到margin,关于这个问题是不是可以这样理解?BFC块为了不与浮动块重叠,添加了margin:0 100px,现在明确赋予margin: 0 10px,等于让BFC的margin失效,为了能看到间隔必须将margin调到大于100px。但是BFC 三栏布局又与第一种不一样,因为产生了BFC,所以左、右、中等于在一个文档流,所以在BFC 三栏布局中,将margin加在左右两块能起作用,margin是相对中间块间隔。在第一种流式布局中,即使将margin加在左、右两块中也不起作用,因为,左右两块都浮动,跟中间块不在一个文档流,margin等于是对父元素间隔。

圣杯布局

作为一个初学者,我一直好奇三栏布局为什么叫圣杯布局,援引维基百科

The holy grail refers to a web page layout which has multiple, equal
height columns that are defined with style sheets. It is commonly
desired and implemented, although the ways in which it can be
implemented with current technologies all have drawbacks.[1] Because
of this, finding an optimal implementation has been likened to
searching for the elusive Holy Grail.

圣杯是曾经用来接耶稣的血,所以被基督徒看作圣物,圣杯流传几千年了,好像到现在也没找到圣杯(西班牙疑似发现了,暂且不讨论),毕竟流传几千年了寻找起来比较困难,所以常常用它来比喻难以寻找的事物。三栏布局在web设计中,有很多解决方案但是每种方案都有缺点,所以业界对于完美解决三栏布局的方案称为圣杯布局。不过,目前已经有个哥们给出了一种较好三栏布局解决方案,并得到广泛的认同,所以这个解决方案被为圣杯布局。

前述流式布局和BFC三栏布局虽然解决了三栏布局,但是它有个缺点就是内容最后渲染,为了追求极致体验,内容应该首先渲染,内容只能放到最前边;
圣杯布局的过程是,设置内容、左、右全部往左浮动,父div的margin左右为120px,留出间距来,以放左、右div。

*{        margin:0;        border: 0;    }    .container{        margin-left: 120px;        margin-right: 120px;    }    .container:after{        content:"";        display: block;        clear: both;    }    .left{        float:left;        width: 100px;        height: 200px;        background-color: green;    }    .right{        float:left;        width: 100px;        height: 200px;        background-color: blue;    }    .center{        float: left;        /*为了占据全部空间,设置宽度100%*/        width: 100%;        height: 200px;        background-color: red;    }

这里写图片描述

为了让左div在最左端,设置margin-left:-100%;

.left{        float:left;        width: 100px;        height: 200px;        background-color: green;       margin-left:-100%;    }

这里写图片描述

可以看到左div已经上来了,但是还没有满足咱们的需求,它应该在最左边,这就要用到相对定位了。

.left{        float:left;        width: 100px;        height: 200px;        background-color: green;       margin-left:-100%;       position:relative;       /*因为container的margin-left是120px,所以这里设置它的相反数*/       left:-120px;    }

这里写图片描述

好了,左div已经达到咱们的需求了,同理右div也是如此,设置margin-left:-100px;因为宽度就是100px,然后再利用相对定位,挪到最右边,为了看的更清楚,你可以拆开,第一步设置margin-left,看看效果,然后再设置相对定位,你就明白了;

.right{        float:left;        width: 100px;        height: 200px;        background-color: blue;        /*因为宽度就是100px*/        margin-left: -100px;        position: relative;        /*因为container的margin-right就是120px*/        left: 120px;    }

双飞翼布局

提到圣杯布局,我们常拿他跟双飞翼布局对比,双飞翼布局也是三栏布局的解决方案,出自淘宝前端UED团队,它将内容比作鸟的身体,左右比作双翼,所以叫作双飞翼,其实就是为了解决三栏布局。我们来看一下它的实现方法。它与圣杯布局很像,也是全部往左浮动,但是在内容div里再嵌套一个div,设置子div的margin为左右div预留位置,左右div只设置margin负值即可实现。与圣杯布局相比,少了position:relative,多了一个div。

*{        margin:0;        border: 0;    }    .left{        float: left;        width: 100px;        height: 200px;        background-color: green;    }    .right{        float: left;        width: 100px;        height: 200px;        background-color: blue;    }    .sub{        height: 200px;        background-color: red;        margin-left: 120px;        margin-right: 120px;    }    .center{        width: 100%;        float: left;    }
<div class="center">            <div class="sub">                这是中间            </div>        </div>        <div class="left">这是左侧</div>        <div class="right">这是右侧</div>

这里写图片描述

这是初步效果,接下来,设置左右div的margin为负值即可

.left{        float: left;        width: 100px;        height: 200px;        background-color: green;        /*注意这里*/        margin-left: -100%;    }    .right{        float: left;        width: 100px;        height: 200px;        background-color: blue;        /*注意这里*/        margin-left:-100px;    }

flex布局

flex布局是css3力推的布局方案,为了这个课题,我还专门去研究了一下flex布局,简单来说就是顺着主轴依次放3列,内容在最前,通过order控制显示顺序,通过flex-grow让中间占据全部剩余空间,通过flex-basis设置左、右div的宽度。

*{        margin:0;        border: 0;    }    .left{        flex:0 1 100px;        background-color: blue;        margin-right: 20px;        order: -1;    }    .right{        flex:0 1 100px;        background-color: green;        order: 1;    }    .center{        background-color: red;        flex-grow: 1;        margin-right: 20px;    }    .container{        display: flex;    }
<div class="container">            <div class="center">                这是中间            </div>              <div class="left">这是左侧</div>            <div class="right">这是右侧</div>        </div>

这里写图片描述

总结

实现三栏布局的基本方式
- 比较简单的实现方式,左div,往左浮动,右div,往右浮动,中间最后渲染
- 圣杯布局、双飞翼,首先渲染内容,然后再渲染左、右div
- flex布局方式,order控制内容显示顺序,flex-grow控占据剩余空间

参考

CSS布局中圣杯布局与双飞翼布局的实现思路差异在哪里?
详解 CSS 七种三栏布局技巧
10 分钟理解 BFC 原理
Flex 布局教程:语法篇
Flex 布局教程:实例篇