1. 程式人生 > >css 三欄佈局 聖盃佈局 雙飛翼 flex

css 三欄佈局 聖盃佈局 雙飛翼 flex

前言

三欄佈局是常見的佈局方式,應用場景:左、右兩側是定寬的導航欄,中間內容自適應。在參考了詳解 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控佔據剩餘空間

參考