(4k字)css佈局篇——雙欄佈局與三欄佈局

近些年,隨着前端技術的不斷髮展,前端所扮演的角色愈來愈重要,職責也愈來愈大。前端早已不只僅作簡單的內容展現頁面,也不只僅負責簡單的表單交互了。日益繁雜的前端技術下,JavaScript在咱們心中佔據着日益重要的地位,而相應的,不少人開始忽略了html和css。css

JavaScript當然重要,可是回過頭來想,做爲一名前端工做者,難道咱們能夠避免和頁面打交道嗎?答案是,否!html

那麼,假設給你一個設計稿,咱們又該如何去着手呢?前端

本篇章主講雙欄佈局和三欄佈局的一些較爲古老及實用的原理及實現。說它古老主要也是由於咱們不會涉及flex這一類魔法通常的佈局方式,雖然我也知道用flex就能輕鬆實現不少佈局。瀏覽器

作這個文章,一方面也是本身作個學習記錄,當作溫習一番。另外一方面,也但願可以幫助看到這篇文章的新手一些啓發,開啓更加深刻的探索之路。架構

雙欄佈局

雙欄佈局很是常見,每每是以一個定寬欄和一個自適應的欄並排展現存在。好比:佈局

雙欄佈局

實現雙欄佈局也很簡單,接下來介紹簡單的 float + margin 實現方法。學習

假設左邊欄固定,右邊欄自適應。flex

思路

  • 使用float 左浮左邊欄
  • 右邊模塊使用margin-left 撐出內容塊作內容展現

實現

html內容結構spa

<body>
    <div class="box">
        <div class="left">左邊</div>
        <div class="right">右邊</div>
    </div>
    內容內容內容
</body>
複製代碼

css規則設計

.left {
    float: left;
    width: 200px;
    background-color: gray;
    height: 400px;
}
.right {
    margin-left: 210px;
    background-color: lightgray;
    height: 200px;
}
複製代碼

效果

雙欄佈局

Emmm...雙欄實現了,可是下面的其餘內容怎麼跑上去了?答案是咱們使用了浮動。

浮動

浮動會致使元素脫離原來普通的文檔流。元素能夠向左或者向右浮動,直到接觸到包含框或者其餘框爲止。在原來文檔流中,體現的就是好像在原來位置被刪除了似的。

所以,以上浮動致使了父元素高度塌陷,其餘內容塊會自動排版上去。解決的辦法有:

  1. 增長清除浮動元素或者僞元素清除浮動,相關元素添加清除樣式:

    clear:both;
    複製代碼
  2. BFC(Block Formatting Context),塊級格式化上下文。BFC規定了內部的塊級元素的佈局方式。使用BFC能夠用來包含浮動元素。常見的作法是爲父元素添加:

    overflow:hidden;
    複製代碼

建立一個BFC

消除浮動的其中一個方式就是建立BFC。然而,建立BFC不只僅只有**「overflow:hidden;」**一種方式,事實上,咱們能夠經過這幾種方法顯示觸發BFC:

  • float的值不爲none。
  • overflow的值不爲visible。
  • position的值不爲relative和static。
  • display的值爲table-cell, table-caption, inline-block中的任何一個。

迴歸正題,咱們的雙欄佈局(事實上其餘涉及浮動的佈局也同樣)父元素高度塌陷的問題的得以解決,好比,咱們只須要爲 .box 元素添加樣式:

overflow: hidden;
複製代碼

建立BFC後的雙欄效果

消除了浮動的雙欄佈局

三欄佈局

三欄佈局也是咱們經常會使用到的佈局之一。它的特色主要是:兩邊定寬,中間自適應。

經過position + margin實現三欄佈局

思路

  1. 父元素相對定位,經過絕對定位將左右兩欄固定
  2. 經過margin設置左右邊距,留出內容塊

實現

html內容結構

<div class="box">
    <div class="left">左邊</div>
    <div class="middle">中間</div>
    <div class="right">右邊</div>
</div>
複製代碼

設置css規則

.box {
    position: relative;
}
.left {
    position: absolute;
    top: 0;
    left: 0;
    width: 200px;
    height: 200px;
    background-color: gray;
}
.right {
    position: absolute;
    top: 0;
    right: 0;
    width: 200px;
    height: 200px;
    background-color: gray;
}
.middle {
    margin-left: 210px;
    margin-right: 210px;
    background-color: lightgray;
    height: 200px;
}
複製代碼

效果

position+margin實現三欄佈局

經過浮動實現三欄佈局

思路

  1. 左右兩欄使用float浮動到相應位置
  2. 中間欄經過margin屬性進行撐開

實現

html內容結構

<div class="box">
    <div class="left">左邊</div>
    <div class="right">右邊</div>
    <div class="middle">中間</div>
</div>
複製代碼

設置css規則

.box {
    overflow: hidden;
}
.left {
    float: left;
    background-color: gray;
    width: 200px;
    height: 200px;
}
.right {
    float: right;
    background-color: gray;
    width: 200px;
    height: 200px;
}
.middle {
    height: 200px;
    background-color: lightgray;
    margin-left: 210px;
    margin-right: 210px;
}
複製代碼

效果

經過浮動實現三欄架構

缺點

固然,經過浮動實現的三欄佈局有一個很明顯的缺點,就是咱們的代碼層面上來說html內容結構不正確,咱們必須把.middle元素放在最下面而不是中間位置,這是float所產生的的佈局影響所致使的。

聖盃佈局和雙飛翼佈局

聖盃佈局最先源於發表於2006年的In Search of the Holy Grail · An A List Apart Article,而雙飛翼佈局則是源自淘寶UED。

聖盃佈局和雙飛翼佈局也是兩邊定寬,中間自適應的三欄佈局。而且中間欄要放在父元素的第一兒子位置,以優先渲染。所以,有些人會說這帶來了代碼層面上html內容結構的不正確。然而,這麼作的好處就是可讓更爲重要的中間部分優先渲染,從這個角度來說,這或許是更加好的結構。

聖盃佈局和雙飛翼佈局二者既有類似的地方,也有不一樣的地方,接下來來比較一下。

在此以前,先來看看可愛的負邊距。

負邊距

爲何要講到負邊距呢?

一方面負邊距是咱們經常忽略的很是好用的技巧,在咱們的佈局方面具備很是重要的意義;另外一方面這玩意兒兼容性賊好,咱們也不用怕兼容性方面的問題。

提及負邊距,咱們能夠想到的就是margin在正邊距時候的反方向。咱們能夠來看看。

普通文檔流的負邊距

實現

html內容結構

<div class="box">
    <div class="content">
        我是內容我是內容我是內容我是內容我是內容我是內容我是內容我是內容
        我是內容我是內容我是內容我是內容
        <span class="span red">哈哈哈哈哈</span>我是內容我是內容我是內容我是內容
        我是內容我是內容我是內容我是內容我是內容我是內容我是內容我是內容
        我是內容我是內容我是內容我是內容我是內容我是內容我是內容我是內容
    </div>
    <div class="other-content">
        我是另外一塊我是另外一塊我是另外一塊我是另外一塊我是另外一塊我是另外一塊我是另外一塊
        我是另外一塊我是另外一塊我是另外一塊我是另外一塊我是另外一塊我是另外一塊我是另外一塊
        我是另外一塊我是另外一塊我是另外一塊我是另外一塊我是另外一塊我是另外一塊我是另外一塊
    </div>
    哈哈哈哈哈哈
    </div>
複製代碼

css規則

.box {
    margin: auto;
    width: 600px;
}
.content {
    margin: -20px;
    background-color: lightgray;
}
.span {
    margin: -10px;
}
.red {
    background-color: red;
}
複製代碼

效果

負邊距

總結

正如上面所示,咱們爲.content和.span這兩個分別表明塊級元素和行輩元素的東西設置了margin爲-20px和-10px。佈局也相應產生了變化。

  • 灰色的框子,內容向左上角拉了過去。.content下方的.other-content文字也來到了它上面。
  • 紅色行內元素,也向左邊偏移,右邊的元素被拉了過來。
  • 最後面沒有任何設置的"哈哈哈哈哈哈"內容也依然緊跟着.other-content元素顯示。

咱們不難看出,負值狀況下

  • margin-top和margin-left會影響自身向指定方向偏移
  • margin-right和margin-bottom會影響相鄰元素向指定方向偏移
  • 經過margin偏移後,原先空出來的位置也會由後面元素填不上。
  • 固然,塊級元素和行內元素在表現上稍有不一樣。

另外一種狀況,負值margin也可以影響元素的寬度,前提是該元素width屬性爲auto的狀況下。這裏也給出詳細例子,比方咱們給一個元素左右邊距爲-200px。

html內容結構

<div class="box">
    <div class="container"></div>
</div>
複製代碼

css規則

.box {
    width: 200px;
    border: 1px solid black;
    margin: auto;
}
.container {
    margin: 0 -200px;
    background-color: lightgray;
    width: auto;
    height: 200px;
}
複製代碼

效果

負邊距

固然,目前爲止咱們都是在普通文檔流裏面。

脫離文檔流的負邊距

絕對定位 + 負邊距

假設咱們對一個元素進行絕對定位,而且給相應的負邊距。

實現

html內容結構

<div class="box">
    <div class="pos">
        絕對定位絕對定位絕對定位絕對定位絕對定位絕對定位絕對定位絕對定位
        絕對定位絕對定位絕對定位絕對定位絕對定位絕對定位絕對定位絕對定位
    </div>
    <div class="pos2">
        內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容
        內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容
        內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容
    </div>
</div>
複製代碼

css規則

.box {
    position: relative;
    height: 200px;
    margin: 200px;
    border: 1px solid black;
}
.pos {
    width: 200px;
    height: 200px;
    position: absolute;
    margin: -20px;
    border: 1px solid gray;
}
.pos2 {
    width: 200px;
    height: 200px;
    position: absolute;
    border: 1px solid red;
}
複製代碼

效果圖

負邊距

總結

從效果上能夠看出來,對於絕對定位而言,負邊距在top和left位置上,會把元素往指定方向拉,而right和bottom方向則沒什麼影響,由於脫離了普通文檔流,不會引發其餘相鄰元素變化。

tips: **「絕對定位+負邊距」**咱們也經常用來實現居中佈局。

浮動 + 負邊距

思考如下三個場景:

  1. 三個左浮動的塊,分別設置負邊距,幾個浮動塊會是怎樣?
  2. 兩個左浮動的塊,左邊的塊左邊距設置爲-100%,右邊的塊會左移嗎?
  3. 兩個左浮動的塊,第一個width佔滿,第二個左邊距設置負值爲自身width大小,會如何?
實現

html內容結構

<!-- demo1 -->
<div class="box">
    <div class="float float1">1</div>
    <div class="float float2">2</div>
    <div class="float float3">3</div>
</div>
<!-- demo2 -->
<div class="box">
    <div class="float4">1</div>
    <div class="float5">2</div>
</div>
<!-- demo3 -->
<div>
    <div class="row">6</div>
    <div class="float6">2</div>
</div>
複製代碼

css規則

.box {
    width: 800px;
    height: 210px;
    margin: 50px auto 10px auto;
    border: 1px solid black;
}
/* 第一個demo */
.float {
    float: left;
    margin: -50px;
    width: 200px;
    height: 200px;
}
.float1 {
    background-color: gray;
}
.float2 {
    background-color: yellow;
}
.float3 {
    background-color: red;
    margin: 0;
}

/* 第二格demo */
.float4 {
    background-color: gray;
    float: left;
    width: 200px;
    height: 200px;
    margin-left: -200px;
}
.float5 {
    background-color: lightgray;
    width: 200px;
    height: 200px;
    float: left;
}

/* 第三個demo */
.row {
    width: 100%;
    height: 200px;
    background-color: lightgray;
    float: left;
}
.float6 {
    background-color: gray;
    float: left;
    width: 200px;
    height: 200px;
    margin-left: -200px;
}
複製代碼

效果

總結

能夠看出:

  1. demo1中,1和2兩個元素設置了全部邊距爲負值,都會往左上方偏移。同時,元素2會在水平方向佔元素1一半。元素3則會被元素2拉向左邊,佔元素2的四分之一。
  2. demo2中,元素1左偏移了自身width的距離,原先位置空着,元素2緊接着補上。
  3. demo3中,兩個元素都是左浮動,元素6的width爲100%,當元素2左偏移自身width的距離之後,徹底到了上一行。

所以,咱們也能夠看出,負邊距對浮動的元素具備和普通文檔流中一樣相似的效果。而且,在後邊的元素也能夠經過負邊距實現覆蓋前邊元素。

在佈局中,咱們就經常使用到**「float + 負邊距」**的魔力。

聖盃佈局

思路

  1. 左中右三個元素分別左浮動。
  2. 中間元素佔據第一位置優先渲染,設置該元素width爲100%
  3. 左元素設置左邊距爲-100%以使得左元素上升一行而且處於最左位置,右元素設置左邊距爲自身寬度的負值使得右元素上升一行處於最右位置。
  4. 設置父元素的左右padding爲左右兩個元素留出空間,以展現中間元素內容。
  5. 設置左右元素爲相對定位,左元素的left和右元素的right爲內邊距的寬度的負值。

實現

html內容結構

<div class="box">
    <div class="middle">中間</div>
    <div class="left">左邊</div>
    <div class="right">右邊</div>
</div>
複製代碼

css規則

.box {
    overflow: hidden;
    padding: 0 210px;
}
.middle {
    float: left;
    width: 100%;
    height: 200px;
    background-color: lightgray;
}
.left {
    float: left;
    width: 200px;
    height: 200px;
    background-color: gray;
    margin-left: -100%;
    position: relative;
    left: -210px;
}
.right {
    float: left;
    width: 200px;
    height: 200px;
    background-color: gray;
    margin-left: -200px;
    position: relative;
    right: -210px;
}
複製代碼

效果

聖盃佈局

雙飛翼佈局

思路

  1. 左中右三個元素分別左浮動。
  2. 中間元素佔據第一位置優先渲染,設置該元素width爲100%
  3. 左元素設置左邊距爲-100%以使得左元素上升一行而且處於最左位置,右元素設置左邊距爲自身寬度的負值使得右元素上升一行處於最右位置。
  4. 設置中間元素的子元素左右邊距爲左右元素留空位,以展現中間元素內容。

實現

html內容結構

<div class="box">
    <div class="middle">
        <div class="content">中間</div>
    </div>
    <div class="left">左邊</div>
    <div class="right">右邊</div>
</div>
複製代碼

css規則

.box {
    overflow: hidden;
}
.middle {
    float: left;
    width: 100%;
}
.middle .content {
    margin: 0 210px;
    height: 200px;
    background-color: lightgray;
}
.left {
    float: left;
    width: 200px;
    height: 200px;
    background-color: gray;
    margin-left: -100%;
}
.right {
    float: left;
    width: 200px;
    height: 200px;
    background-color: gray;
    margin-left: -200px;
}
複製代碼

效果

雙飛翼佈局

總結

聖盃佈局跟雙飛翼佈局的實現上,在前部分是同樣的。一樣都是左右欄定寬,中間欄自適應。採用浮動和負邊距使左右欄與中間欄並排。不一樣之處大部分在於中間元素的的展現方式上。

聖盃佈局採用父元素設置邊距的方法,左右元素設置相對定位輔助。而雙飛翼佈局在中間採用嵌套子元素方法,經過設置子元素外邊距來展現。

對比看來,雙飛翼比聖盃多了一個嵌套元素,可是少了左右元素的定位。

flex佈局

在flex以前,不管是咱們的單欄佈局也好,雙欄佈局也罷,甚至更爲複雜的三欄佈局、垂直居中等等,咱們通常都會藉助浮動 (float)、定位(position)、邊距(margin)來實現咱們各類各樣的佈局樣式,直到咱們遇到了flex。

flex(彈性佈局)給了咱們在佈局方面更多的可能性,它能夠更加簡便、響應的佈局咱們的頁面。咱們經常能夠利用它魔法通常的屬性來打造咱們想要的佈局樣式。而且,flex如今幾乎獲得了全部的瀏覽器的支持,兼容性方面已經愈來愈不須要太過擔心了。

更多關於flex兼容性的問題能夠查看can I use

然而,本篇章並不打算寫flex,僅僅講解以往實現雙欄和三欄佈局的一些方式。於我而言,我更願意用單獨一個篇章來寫flex這個主題,而不是放在這個主題來說。而且以後我也會專門來寫這個主題。

很少廢話,這一次的分享就到這裏,咱們下期再見!

相關文章
相關標籤/搜索