不懂聖盃佈局?5種方式包教包會

子物發表於2018-09-22

前言

本文針對聖盃佈局(兩邊固定,中間自適應佈局)以五種方式進行講解,話不多說,現在開始

方式一:float佈局

利用float實現聖盃佈局是最原始也是相容性最好的方式,當然相對於其它幾種來說較為複雜。

首先定義一個容器包裹三列盒子

<div class="container">
    <div class="center">
        center
    </div>
    <div class="left">
        left
    </div>
    <div class="right">
        right
    </div>
</div>
複製程式碼

其中有一個需要注意的是盒子的排布順序,其中.center盒子排在最前面,left和right依次排列,這裡主要是用到了float和margin的特性,接下來會講到。

其次是css樣式

.container > div {
    float: left;
    height: 300px;
}
複製程式碼

⬆首先將父容器下的子盒子都定義為float為左的浮動元素,高度統一為300px

.left, .right {
    width: 100px;
    background: #f00;
}

.center {
    width: 100%;
    background: #0f0;
}
複製程式碼

⬆接下來定義子盒子的寬度,可以看見.center盒子的寬度為100%,也就是佔滿父容器,那麼left和right盒子相應的就到下一行了,如下圖所示。

qq 20180922124501

那麼如何讓left和right盒子放置在center盒子的左右側呢,這就要用到margin和float的特性了,先看程式碼示例

.left {
    margin-left: -100%;
}

.right {
    margin-left: -100px;
}
複製程式碼

可以看見,首先給left盒子新增了一個負100%的margin-left值,這個百分數對應的是left盒子的父盒子,也就是.container的寬度之比,那麼left盒子就會向左移動父元素的寬度的距離。

其次因為left盒子和center盒子是浮動排列的,left盒子margin為負,且已經超過自身的寬度,那麼left盒子在文件流中的佔位寬度已然成了一個負值,所以依據浮動的特性。

當盒子成為浮動元素後,在浮動層擁有內聯元素的"特性",當多個浮動元素一排容不下時,就換行。

反之,則不換行。

left盒子就會和center盒子同處一行,且位於container盒子的最左側,同理給right盒子一個負自身寬度的margin值,right盒子就會和center盒子同處一行,且位於右側,如圖所示。

qq 20180922132919

這裡又出現了一個問題,center盒子的內容被left和right盒子覆蓋了,這裡我們用box-sizing和padding屬性解決這個問題

.center {
    box-sizing: border-box;
    padding: 0 100px;
    width: 100%;
    background: #0f0;
}
複製程式碼

qq 20180922133521

在雙飛翼佈局中我們可以看見這樣的dom結構

<div class="container"> 
    <div class="main">
        <div class="content">main</div> 
    </div>
    <div class="left">left</div> 
    <div class="right">right</div> 
</div>
複製程式碼

其實原理是一樣的,都是限制center盒子的寬度來實現通過padding將center盒子的內容“擠”到中間來展示。

完整程式碼可以看這裡

方式二:絕對佈局

相信很多新人同學經常使用絕對佈局,之前帶過的徒弟就是這樣,對於一些複雜的佈局,不懂得拆分結構,用絕對定位來實現需求,總是被我敲腦袋。

但是這裡還是提一下這種佈局,不是說它不好,而是標題的牛逼都吹出去了,總得拿出些“乾貨”來。

先看dom結構,循規蹈矩

<div class="container">
    <div class="left">
        left
    </div>
    <div class="center">
        center
    </div>
    <div class="right">
        right
    </div>
</div>
複製程式碼

絕對定位的特性想必大家都知道,所以直接講解步驟。

首先給父容器定義position為relative,讓absolute的子元素依據這個父元素定位。

.container {
    position: relative;
}
複製程式碼

接下來將子元素的定位方式都設定為absolute,給左右兩邊的盒子設定寬度以及定位的依據

.container > div {
    position: absolute;
    height: 500px;
}

.right, .left {
    width: 100px;
    background: #f00;
}
.left {
    left: 0;
}

.right {
    right: 0;
}
複製程式碼

需要理解的就是中間盒子的定位依據了

.center {
    left: 100px;
    right: 100px;
    background: #0f0;
}
複製程式碼

設定left和right為左右盒子的寬度就行,這樣既不會覆蓋左右盒子,也因為沒有定寬,所以就能實現自身的寬度依據父元素的寬度自適應。

qq 20180922133521

完整程式碼看這裡

方式三:table佈局

table標籤本是一個自適應的標籤,所以使用table很容易實現這樣的佈局,但是我們這裡講解的是使用display屬性,而不用table標籤,因為使用table標籤會帶來一些副作用。

先看dom結構, 循規蹈矩的結構

<div class="container">
    <div class="left">
        left
    </div>
    <div class="center">
        center
    </div>
    <div class="right">
        right
    </div>
</div>
複製程式碼

再看看css樣式。

首先給父容器container定義display屬性為table,並且將寬度設為100%。

.container {
    display: table;
    width: 100%;
}
複製程式碼

其次,將父容器下的子標籤display設定為table-cell,也就是表格的單元格。

想想看錶格的單元格有什麼特性,對的,如果一個單元格沒有設定寬度值,那麼就會填充剩下的寬度,所以我們利用這個特性,將左右兩邊的盒子設定一個固定的單寬度值,中間的盒子就自動填充剩下的寬度了,css如下所示:

.container > div {
    display: table-cell;
    height: 500px;
}

.left, .right {
    background: #f00;
    width: 100px;
}

.center {
    background: #0f0;
}
複製程式碼

qq 20180922133521

就是這麼簡單,完整程式碼看這裡

方式四:flex佈局

用flex方式實現聖盃佈局,只需關鍵的兩行程式碼。

dom結構同上

<div class="container">
    <div class="left">
        left
    </div>
    <div class="center">
        center
    </div>
    <div class="right">
        right
    </div>
</div>
複製程式碼

首先將父元素display設定為flex,將子元素設定一個固定的高度

.container {
    display: flex;
}

.container > div {
    height: 500px;
}
複製程式碼

其次設定left和right盒子的寬度

.left, .right {
    background: #f00;
    width: 100px;
}
複製程式碼

最後將center的flex-gorw設定為1,flex-grow屬性的作用是,對於父容器剩餘空間的分配,因為只有一個center盒子沒有定義寬度,所以設定為1,那麼就會自動填滿剩下的空間。

.center {
    flex-grow: 1;
    background: #0f0;
}
複製程式碼

qq 20180922133521
完整程式碼看這裡

終極大法:grid佈局

對於grid佈局,我只能用一個字來形容“強強強強強強強強強強~~悍” 因為實現聖盃佈局,只需要兩行程式碼。

dom結構同上。

<div class="container">
    <div class="left">
        left
    </div>
    <div class="center">
        center
    </div>
    <div class="right">
        right
    </div>
</div>
複製程式碼

CSS如下

.container {
    display: grid;
    grid-template: 500px / 100px 1fr 100px
}、
複製程式碼

解釋一下,display: grid; 宣告該盒子是grid佈局。

grid-template: 500px / 100px 1fr 100px500px指的是行高,100px 1fr 100px 中的100px代表左右兩列的寬度,中間的1fr表示,中間的盒子也就是center填滿剩下的內容。

至於下面的css,那都是用來修飾的啦。

.left, .right {
    background: #f00;
}
.center {
    background: #0f0;
}
複製程式碼

qq 20180922133521

後序

該篇講解方式的順序大致可以理解成瀏覽器佈局的進化,所以再不學習,你就跟不上啦。

該篇所有的程式碼可以在這裡檢視

github.com/Richard-Cho…

碼字不易,點個贊吧,嘻嘻

相關文章