等高分欄布局小結


上一篇文章《聖杯布局小結》總結了幾種常見的分欄布局方法,這幾個方法都可以實現多欄頁面下,所有欄的高度可動態變化,某一欄寬度自適應的布局效果,能滿足工作中很多布局需求。后來我在搜集更多關於分欄布局的文章時,發現了一個新的問題,這個問題在前面那篇文章中也有朋友在評論里跟我提起,就是如何在實現分欄布局的同時保證每欄的高度相同。我發現這種等高分欄布局的情況,在網站里面其實也很常見,所以本文總結了幾種可用的方法來解決這個新的需求。

1. 方法一:萬能的flex

跟上篇文章不同,這次把flex這種方法放在了第一位,因為相比較起來,它是所有分欄布局方法里面,優點最多的,如果兼容性允許的話,很有必要在任何時候都優先使用它完成頁面布局。如果你打開上篇文章,找到倒數第二部分關於flex實現分欄布局的代碼,或者把上篇文章提供的代碼下載下來,直接預覽flex_layout.html,你會發現上篇文章的那段代碼其實已經做到了等高分欄布局,同一段代碼,可以實現上篇文章中提到的五種分欄布局,還可以實現本文提到的等高布局的情況,這種能力其它方法真的無法比擬。而它之所以能實現等高布局,跟一個flex的css屬性有關系,這個屬性是:align-item。它的默認值是:stretch,在flex item元素比如layout__main或layout__aside的高度未定義或者為auto的情況下,會拉伸flex item元素的高度或寬度,鋪滿flex的交叉軸,詳細的原理可以通過上文提供的flex學習資源去了解,這里只做一個簡單的引用說明。

2. 方法二:使用table或者偽table

上篇文章中還有另外兩種布局方法沒有介紹,第一種就是這里要說的table布局或者偽table布局。table布局用的就是table tr td這些元素去實現,相信絕大部分web開發人員在入門html時,首先接觸到的布局方法肯定就是table布局了,這種方法簡單高效,用它做任何分欄布局都不是問題,只是因為table的嵌套結構太多,html冗雜,又不利於DOM的操作和渲染,用來布局不符合語義,總之缺點較多,所以目前的環境下,用的情況越來越少了。偽table布局其實跟table布局類似,只不過借助於css,可以讓我們不直接使用table tr td這些直接的表格元素,而是通過display: table, display: table-row, display: table-cell,改變元素的顯示特性,讓瀏覽器把這些元素當成table來渲染,這種渲染的表現跟用真實的table沒有啥區別,就連那些table專用的css屬性,比如table-layout,border-collapse和border-spacing,都能產生效果。table布局的方法已經很少被采用了,本文也就沒必要再去介紹,但是偽table布局的方法值得學習一下,經過這兩天的學習,發現偽table的方式相比直接用表格布局,有不少的優點,值得運用到工作中去。不過在說明使用偽table布局的方法之前,得先了解一些偽table相關的知識:

1)可用於偽table表現的display屬性值有:

image

2)當把一個元素的display屬性設置成以上列出的值后,就可以把這個元素看成與該屬性對應的表格元素,比如table-cell對應的就是td;同時,這個元素會擁有跟表格元素一樣的特性,比如display: table或者inline-table的元素可以使用table-layout,border-collapse和border-spacing這三個原本只有table才能生效的屬性;display:table-cell的元素跟td一樣,對寬度高度敏感,對margin值無反應,對padding有效。

3)關於table-cell還有一點要說明的就是,它會被其他一些CSS屬性破壞,例如float, position:absolute,所以這些個屬性不能同時使用。

4)跟直接使用表格元素不同的是,在使用表格元素的時候需要完全遵守表格元素嵌套結構,也就是下面這種:

<table>
    <thead>
        <th></th>
    </thead>
    <tbody>
        <tr>
            <td></td>
        </tr>
    </tbody>
    <tfoot>
        <th></th>
    </tfoot>
</table>

而使用偽table的那些屬性時,可以僅單獨使用某一個屬性,瀏覽器會在這些元素的外層包裹缺失的來保證偽table元素框嵌套結構的完整性,這些框跟常提到的行框一樣都是不可見的,網上有的文章里也把這種做法叫做匿名表格。下面的這個代碼中,tb-cell元素的外層沒有加display: table-row和display: table的元素:

.tb-cell {
    display: table-cell;
    padding: 10px;
    border: 1px solid #ccc;
}

<div class="tb-cell">這是第1個display: table-cell;的元素。</div>
<div class="tb-cell">這是第2個display: table-cell;的元素。</div>

但是看到的效果是(藍色背景是它們父層的一個包裹元素: width: 800px;margin-left: auto;margin-right: auto):

image

因為瀏覽器自動在這兩個元素的外層,加了跟能夠跟tr和table起相同作用的框,來包含這兩個元素形成的框,所以這兩個元素看起來就跟實際的表格效果一樣。假如瀏覽器沒有做這個處理,這兩個元素之間是不可能沒有間隙的,中間會有一個因為換行符顯示出來的空格。這種自動添加的框都是行內框,不是塊級框。

接下來看看如何通過這些偽table的屬性來完成上文的分欄布局以及本文要求的等高分欄布局,玩法有很多:(本文相關源碼下載

玩法一:模擬直接用表格布局(對應源碼中table_layout1.html)

這種方法的思路是布局時完全按照表格的嵌套層次來處理,把display: table, display: table-row, display: table-cell都用上,相當於就是利用完整的table來做,比如說要實現上文的布局三(3欄布局,2個側邊欄分別固定在左邊和右邊,中間是主體內容欄),就可以這么干:

<div class="layout">
    <div class="layout__row">
        <aside class="layout__col layout__aside layout__aside--left">左側邊欄寬度固定</aside>
        <div class="layout__col layout__main">內容欄寬度自適應<br>高度增加一點,旁邊的高度都會自動增加</div>
        <aside class="layout__col layout__aside layout__aside--right">右側邊欄寬度固定</aside>
    </div>
</div>
<style type="text/css">
    .layout {
        display: table;
        width: 100%;
    }
    .layout__row {
        display: table-row;
    }
    .layout__col {
        text-align: center;
        display: table-cell;
    }
    .layout__col + .layout__col {
        border-left: 10px solid #fff;
    }
    .layout__main {
        background-color: #4DBCB0;
    }
    .layout__aside {
        width: 200px;
        background-color: #daf1ef;
    }
</style>

效果還是那個效果,而且天生支持等高布局:

image

這個布局原理跟使用table是完全一樣的,所以使用起來非常容易(以上提供的是針對上文布局三的實現,其它四個布局的實現不會再一一介紹了,源碼里面也不會提供,因為相對比較簡單)。

這種偽table布局有什么特點呢:

1)相比直接用表格元素,這種做法不需要考慮語義,表格元素是有語義的,主要是用來顯示網頁上列表型的數據內容,雖然可以完成布局,但是布局結構都是沒有語義的,所以直接用表格不合適,而這種偽table布局的特點就是:它沒有語義,但是可以像表格那樣布局;

2)html的層次結構相比直接用table元素也要簡單一些,我們這里只用到了3層,直接用table元素的話可能還有tbody這一層;

3)相比上文提到的那些布局方法,如聖杯布局和雙飛翼布局,這個做法在css方面相對簡單,在html方面也只多了一層嵌套;

4)缺點是分欄之間的間隔不能用margin和padding來做,如果用margin,這個屬性在display: table-cell的元素上根本不會生效;如果用padding,那像demo里面各欄的背景色就都會連到一塊,做不出間隔的效果,如果在layout__col里面再嵌套一層,在這一層設置背景色的話,又會增加html的層次,也不是很好。我這里是投了個巧,用border處理了一下。

玩法二:去掉display: table-row(對應源碼中的table_layout2.html)

前面說過,瀏覽器會用匿名表格的方式,添加缺失的框,所以玩法一中的代碼,把layout-row完全去掉,一點都不影響布局效果:

<div class="layout">
    <aside class="layout__col layout__aside layout__aside--left">左側邊欄寬度固定</aside>
    <div class="layout__col layout__main">內容欄寬度自適應<br>高度增加一點,旁邊的高度都會自動增加</div>
    <aside class="layout__col layout__aside layout__aside--right">右側邊欄寬度固定</aside>
</div>
<style type="text/css">
    .layout {
        display: table;
        width: 100%;
    }
    .layout__col {
        text-align: center;
        display: table-cell;
    }
    .layout__col + .layout__col {
        border-left: 10px solid #fff;
    }
    .layout__main {
        background-color: #4DBCB0;
    }
    .layout__aside {
        width: 200px;
        background-color: #daf1ef;
    }
</style>

玩法三:去掉display: table(對應源碼中的table_layout3.html)

根據玩法二,可以試想一下是否能再把display: table這一個屬性給去掉,反正瀏覽器還會再添加框來包裹:

<div class="layout">
    <aside class="layout__col layout__aside layout__aside--left">左側邊欄寬度固定</aside>
    <div class="layout__col layout__main">內容欄寬度自適應<br>高度增加一點,旁邊的高度都會自動增加</div>
    <aside class="layout__col layout__aside layout__aside--right">右側邊欄寬度固定</aside>
</div>
<style type="text/css">
    .layout__col {
        text-align: center;
        display: table-cell;
    }
    .layout__col + .layout__col {
        border-left: 10px solid #fff;
    }
    .layout__main {
        background-color: #4DBCB0;
    }
    .layout__aside {
        width: 200px;
        min-width: 200px;
        background-color: #daf1ef;
    }
</style>

效果是:

image

這個並沒有達到我們的效果,因為我需要主體內容欄能夠自適應寬度。產生這個效果的原因是什么,就是因為沒有加顯示display: table這一層,瀏覽器自動加了一個框,不過這個框是行內框,導致主體內容欄顯示的寬度就跟內容的寬度一致了。為了解決這個問題,可以這么干,html結構不變,css稍加改動:

.layout__main {
    width: 3000px;
    background-color: #4DBCB0;
}

.layout__aside {
    width: 200px;
    min-width: 200px;
    background-color: #daf1ef;
}

關鍵的代碼就是紅色新增的那兩行,首先給主體內容欄設置一個很長的寬度,而且只能用具體的長度設置,不能用百分比,然后給側邊欄設置一個最小寬度,免得主體內容欄把側邊欄的寬度給擠掉了。這個原理就是因為display: table-cell的作用,導致layout__main跟layout__aside表現出跟td元素一樣的特性,td默認的寬度就是可自動調整的,即使寬度設置的很大,也不會撐破table的寬度,這里雖然那個自動添加的框看不到,但是這個框的最大寬度也就是瀏覽器的寬度,layout__main不會打破這個寬度的,所以可以放心使用。

玩法四:去掉layout這一層包裹元素(對應源碼:table_layout4.html)

如果網站比較簡單,去掉layout這一層包裹元素也是可以的:

<header>頂部</header>
<aside class="layout__col layout__aside layout__aside--left">左側邊欄寬度固定</aside>
<div class="layout__col layout__main">內容欄寬度自適應<br>高度增加一點,旁邊的高度都會自動增加</div>
<aside class="layout__col layout__aside layout__aside--right">右側邊欄寬度固定</aside>
<footer>底部</footer>
<style type="text/css">
    .layout__col {
        text-align: center;
        display: table-cell;
        line-height: 50px;
    }
    .layout__col + .layout__col {
        border-left: 10px solid #fff;
    }
    .layout__main {
        width: 3000px;
        background-color: #4DBCB0;
    }
    .layout__aside {
        width: 200px;
        min-width: 200px;
        background-color: #daf1ef;
    }
</style>

以上四種做法都能實現我們想要的分欄等高布局,兼容性方面,不考慮IE8及以下,其它瀏覽器幾乎沒有問題。

由於匿名表格的作用,導致采用偽table布局的方法變得非常簡潔,上文之所以沒提到這個做法,是因為完全不知道有匿名表格這回事,我也是寫這篇文章才學習到的,學完之后,發現又找到了一個做分欄布局的好辦法,希望前面的這些介紹能幫助你掌握好這個用法。實際上偽table的這些屬性,尤其是table-cell,用途非常多,本文沒有辦法一一介紹,但是能提供一個思路,將來工作中也許有很多其它布局場景,我們都可以想想用table-cell來處理。

3. 方法三:使用絕對定位

上文沒有介紹的另外一種分欄布局方法就是這里要介紹的絕對定位。之所以沒介紹這個方法,是因為上文介紹的都是分欄自適應布局的方法,而絕對定位的做法,不能完全做到我們想要的分欄自適應布局,分欄自適應有兩個原則:第一是主體內容欄寬度自適應,這點絕對定位是可以做到的;第二點是所有欄的高度都能動態變化,並且不能導致父容器高度塌陷,不能在各欄內部出現滾動或溢出的情況,這點絕對定位不容易做到適用所有場景。而本文又把這種布局方法拿出來介紹,是因為絕對定位做等高布局很容易,所以用絕對定位做等高分欄布局是一種可行的辦法,只是這種方法適用的場景有一些限制,需要根據實際情況考慮是否要采用。

做法一:所有欄都采用絕對定位(對應源碼中absolute_layout1.html)

<header>頂部</header>
<div class="layout">
    <aside class="layout__aside layout__aside--left">左側邊欄寬度固定</aside>
    <div class="layout__main">內容欄寬度自適應</div>
    <aside class="layout__aside layout__aside--right">右側邊欄寬度固定</aside>
</div>
<footer>底部</footer>
<style type="text/css">
    .layout {
        height: 300px;
        position: relative;
    }
    .layout__aside, .layout__main {
        position: absolute;
        top: 0;
        bottom: 0;
    }
    .layout__main {
        left: 210px;
        right: 210px;
    }
    .layout__aside {
        width: 200px;
    }
    .layout__aside--left {
        left: 0;
    }
    .layout__aside--right {
        right: 0;
    }
</style>

效果:

image

這種布局方法的特點是:

1)主體內容欄是自適應的;

2)所有欄完全等高,效果跟flex布局和偽table布局的效果一樣;

從這兩點來看,這種絕對定位的方法還是比較好用的,不過它有一個非常大的使用限制,就是父元素的高度沒有辦法通過它的內部元素給撐起來,要用的話,必須想辦法讓父元素有高度,適合做父元素高度可知或者全屏布局。比如以下這個代碼就是全屏布局的一個例子(對應源碼中absolute_layout2.html):

<header>頂部</header>
<div class="layout">
    <aside class="layout__aside layout__aside--left">左側邊欄寬度固定</aside>
    <div class="layout__main">內容欄寬度自適應</div>
    <aside class="layout__aside layout__aside--right">右側邊欄寬度固定</aside>
</div>
<footer>底部</footer>
<style type="text/css">
    html,body {
        margin: 0;
        height: 100%;
    }
    footer {
        position: absolute;
        bottom: 0;
        width: 100%;
    }
    .layout {
        width: 100%;
        position: absolute;
        top: 50px;
        bottom: 50px;
    }
    .layout__aside, .layout__main {
        position: absolute;
        top: 0;
        bottom: 0;
    }
    .layout__main {
        left: 210px;
        right: 210px;
    }
    .layout__aside {
        width: 200px;
    }
    .layout__aside--left {
        left: 0;
    }
    .layout__aside--right {
        right: 0;
    }
</style>

效果:

image

做法二:側邊欄絕對定位,主體內容欄保持流式布局(對應源碼中absolute_layout3.html)

<div class="layout">
    <aside class="layout__aside layout__aside--left">左側邊欄寬度固定</aside>
    <div class="layout__main">內容欄寬度自適應<br>高度增加一點,旁邊的高度都會自動增加</div>
    <aside class="layout__aside layout__aside--right">右側邊欄寬度固定</aside>
</div>
<style type="text/css">
    .layout {
        position: relative;
    }
    .layout__aside {
        position: absolute;
        top: 0;
        bottom: 0;
    }
    .layout__main {
        margin: 0 210px;
    }
    .layout__aside {
        width: 200px;
    }
    .layout__aside--left {
        left: 0;
    }
    .layout__aside--right {
        right: 0;
    }
</style>

效果:

image

這個方法的特點是:

1)主體內容欄是寬度自適應的;

2)所有欄也是完全等高的;

上面的代碼中,layout__main通過magin來給側邊欄留出空間,其實也可以在layout元素上添加padding來處理,作用是一樣的。這個方法相比前一個方法好一點的是,父元素的高度可以通過主體內容欄給撐起來,不過由此也帶來了一個新問題,就是內容欄高度不夠的時候,側邊欄就會出現溢出或者滾動,解決這個新問題的辦法有2個:第一,如果側邊欄的內容都是已知的,並且沒有折疊展開這種會改變側邊欄內容高度的功能,那么可以給layout設置一個min-height來處理;第二,如果側邊欄的內容是動態的,除了給layout加min-height之外,還得在每次改變側邊欄內容的時候,主動去調整主體內容欄的高度,如果主體內容欄的高度小於側邊欄的高度,就要更新主體內容欄的高度。不過如果你的內容欄的內容很多,側邊欄內容較少的話,就不用考慮這個新問題了。

絕對定位的做法就是這樣,第一種限制較高;第二種稍微強一些,在一些場景下,可能還得借助JS來處理,所以綜合起來不算是一個非常好的方式。只有你的布局需求恰好滿足它的條件時,可能才會考慮使用它,就像上文中我提出的項目一的需求,就一定要用絕對定位的布局來做。

4. 方法四:借助邊框,背景實現假等高

前面介紹了幾種分欄等高布局,有table布局,偽table布局,絕對定位布局,flex布局,這四種布局方法在實現等高布局時,屬於完全等高的情況,就是說他們布局出來的頁面,各欄的真實高度都是相同的,並且在任意欄的內容動態變化時,其它欄的高度都能相應地自動調整,如果布局的時候用的是這幾個布局方法,那么等高的問題就不存在了。不過回看一下上文內容的話,上文提到的3種布局方式:聖杯布局,雙飛翼布局,float布局,不用JS的話,就無法做到這種完全等高的效果。這三種布局,只能考慮借助邊框和背景實現視覺上的等高,也就是假等高的做法。畢竟從效果上來說,如果沒有設置背景和邊框的話,即使是完全等高,視覺上也看不出來,所以假等高的做法是值得采用的。

做法一:利用背景圖片

以布局容器寬度固定的左中右三欄布局說明這個做法的步驟,首先制作一張高度較小,寬度跟布局容器寬度相同的背景圖片,把這張圖片作為布局容器的背景圖垂直平鋪。這張背景圖要求跟頁面一樣也是分欄,而且每欄的寬度和欄之間的間隔都跟頁面布局里面的欄位寬度和欄位間隔相同,這樣才能保證,背景圖片的每個欄位與頁面里面的每個欄位重合。因為頁面里面的每個欄位底下,都有一個背景圖片的欄位跟它對應,所以即使某一欄高度不夠,但是視覺上這個欄位的高度跟布局容器的高度是相同的,這就是借助背景圖來達到視覺等高的原理。這個做法的經典例子就是http://www.w3school.com.cn/,它的布局效果是這樣的:

image

看起來這是一個三欄等高布局,分欄是通過float實現的,等高卻不是完全等高,而是通過背景圖片實現的,它在布局容器上用了下面這張背景圖:

wrapper

image

它的布局html結構是(馬賽克掉的是header,導航欄,footer,跟分欄布局沒有關系,所以注掉了):

image

然后各欄只要都向左浮動,配置好寬度就行:

imageimageimage

前面說明這個做法的步驟包括舉的例子都針對的是布局容器寬度固定的左中右三欄布局,如果是自適應的分欄布局,又該怎么處理?下面以上文聖杯布局的布局三如何借助背景圖片做到等高效果來說明(為了減少篇幅,其它四種布局不會一一說明,但是這五種布局在源碼中都有demo頁面可查看,分別對應grail_bg_layout{1,5}.html)。

布局三:3欄布局,2個側邊欄分別固定在左邊和右邊,中間是主體內容欄:

<div class="layout--wrapper">
    <div class="layout">
        <aside class="layout__aside layout__aside--left">左側邊欄寬度固定</aside>
        <div class="layout__main">內容欄寬度自適應<br>高度增加一點,旁邊的高度看起來都跟內容欄高度一樣</div>
        <aside class="layout__aside layout__aside--right">右側邊欄寬度固定</aside>
    </div>
</div>
<style type="text/css">
    .layout:after {
        content: " ";
        clear: both;
        display: table;
    }
    .layout__aside, .layout__main {
        float: left;
        height: 100%;
    }
    .layout--wrapper {
        background: url(aside_left.png) left top repeat-y #4DBCB0;
    }
    .layout {
        background: url(aside_right.png) right top repeat-y;
        padding:0 210px;
    }
    .layout__main {
        width: 100%;
    }
    .layout__aside {
        width: 200px;
    }
    .layout__aside--left {
        margin-left: -210px;
    }
    .layout__aside--right {
        margin-right: -210px;
        float: right;
    }
</style>

效果:

image

實現這個等高效果的關鍵是:

1)去掉在layout__aside layout__main上設置的背景色;

2)制作2張背景圖片,寬度都是210 * 10,分別用來做兩個側邊欄的背景:

aside_left.png : aside_left

aside_right.png: aside_right

3) html結構稍微調整下,加一層wrapper

4)layout--wrapper的背景如下設置:

background: url(aside_left.png) left top repeat-y #4DBCB0;

這樣左側邊欄和內容欄就都有了背景,左側邊欄與內容欄之間的間隔效果也出來了。

5)layout的背景如下設置:

background: url(aside_right.png) right top repeat-y;

這樣右側邊欄就有了背景,右側邊欄與內容欄之間的間隔效果也出來了。

以上就是利用背景圖做假等高效果的全部內容,這個做法對於要用背景來呈現等高效果的布局是非常好用的一個方法,雖然網上都說它的缺點是用到了圖片,布局一改,圖片就要改,我個人認為這並不是缺點,因為這樣的需求變動,第一是無法避免,第二是變動地次數不一定很多,第三即使變了改起來也是兩三分鍾的事,要是自己會點PS,那弄起來就更簡單了。能解決問題的簡單方法就是最好的辦法。

做法二: 利用邊框重疊

首先得說這個做法,適合要用邊框來呈現等高效果的布局,也就是說各欄不能有背景,否則看起來邊框是等高了,但是背景沒有等高。它的原理要分成兩部分來說,如果是2欄布局,做法比較簡單,比如左右分欄的布局,給側邊欄加一個右邊框,給內容欄加一個左邊框,然后給內容欄加上負的margin-left,讓2個邊框重合,這樣不管哪個欄位內容多,邊框重疊之后的高度就跟整體的高度一致了,也就達到了我們想要的等高效果;如果是多欄布局,這種邊框重疊的方式不能做到所有場景下的視覺等高,比如說左中右三欄布局,現在是按邊框重疊的辦法實現了下等高,當左邊欄的內容動態增加很多時,右邊側邊欄跟內容欄的邊框整體高度,並不會動態增加,然后就會形成錯層的效果,對於這種情況,可以利用絕對定位,用額外的空元素模擬欄與欄之間的邊框效果。

下面以上文聖杯布局的布局一和布局三如何借助邊框重疊和模擬做到等高效果來說明(為了減少篇幅,其它布局不會一一說明,但是這幾種布局在源碼中都有demo頁面可查看,分別對應grail_border_layout{1,3}.html)。

1)布局一:2欄布局,側邊欄固定在左邊,右側是主體內容欄:

<div class="layout">
    <aside class="layout__aside">側邊欄寬度固定</aside>
    <div class="layout__main">內容欄寬度自適應<br>高度增加一點,旁邊的高度看起來都跟內容欄高度一樣</div>
</div>
<style type="text/css">
    .layout:after {
        content: " ";
        clear: both;
        display: table;
    }
    .layout__aside, .layout__main {
        float: left;
    }
    .layout {
        padding-left: 201px;
    }
    .layout__main {
        width: 100%;
        margin-left: -1px;
        border-left: 1px solid #ccc;
    }
    .layout__aside {
        width: 200px;
        border-right: 1px solid #ccc;
        margin-left: -201px;
    }
</style>

要點是:

1)要重新調整layout的padding值,和layout__aside的margin值,欄與欄之間不能有間隔;

2)layout__main設置-1px的margin-left和1px的border-left;layout__aside設置1px的border-right

效果:

image

布局三:3欄布局,2個側邊欄分別固定在左邊和右邊,中間是主體內容欄:

<div class="layout">
    <aside class="layout__division layout__division--left"></aside>
    <aside class="layout__division layout__division--right"></aside>
    <aside class="layout__aside layout__aside--left">左側邊欄寬度固定<br>再加點東西<br>再加點東西</aside>
    <div class="layout__main">內容欄寬度自適應<br>高度增加一點</div>
    <aside class="layout__aside layout__aside--right">右側邊欄寬度固定</aside>
</div>
<style type="text/css">
    .layout:after {
        content: " ";
        clear: both;
        display: table;
    }
    .layout__aside, .layout__main {
        float: left;
        height: 100%;
    }
    .layout {
        padding:0 201px;
        position: relative;
    }
    .layout__main {
        width: 100%;
    }
    .layout__aside {
        width: 200px;
    }
    .layout__aside--left {
        margin-left: -201px;
    }
    .layout__aside--right {
        margin-right: -201px;
        float: right;
    }
    .layout__division {
        position: absolute;
        border-left: 1px solid #ccc;
        height: 100%;
    }
    .layout__division--left {
        left:200px;
    }
    .layout__division--right {
        right:200px;
    }
</style>

效果:

image

布局三這個做法的原理比真實的邊框重疊還要簡單些,但是不如那種方法簡潔,畢竟要增加沒有用的html元素,所以不算是一個好方法。

最后綜合比較背景和邊框這兩種假等高做法,更值得推薦的是做法一,邊框這種效果,通過背景圖也是可以做出來的,而且邊框能夠實現的視覺效果有限,利用邊框的多欄等高布局還得增加冗余的HTML元素,缺陷比較明顯。

5. 結束語

本文介紹了4種可以做到完全等高的分欄自適應布局方法,對於上文的幾種分欄布局:聖杯布局,雙飛翼布局,float布局,也提供了一個簡單高效的方法可以做到視覺上的假等高效果,這些方法都是可靠有效的,只要滿足自己的工作需求,喜歡用哪種就用哪種,畢竟工作的目的是完成工作目標,而不是嘗試哪種工具好用。但如果公司的產品不考慮那些陳舊的瀏覽器的話,我覺得所有的布局只需要三個方法:flex,table-cell和position,其它的聖杯布局,雙飛翼布局,float布局就讓它成為經典,留在自己的博客總結中就好。PS: 雖然上文我在推薦聖杯布局,但是我已經打算把我的項目二的布局方式換成table-cell來搞了。

本文內容繁多,相信耽誤您不少時間,謝謝閱讀,提前祝您新年快樂:)

本文相關源碼下載


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM