CSS佈局經典問題:兩欄佈局-左側固定,右側自適應

這個問題在開發時碰過很是屢次,是經典佈局問題。不少公司的面試題也會問這類問題,今天就詳細的來談一下這類問題。css


還有一篇相似的文章,關於三欄佈局 詳情請戳html


題意很是明確,左側的塊寬度是固定的,右側的寬度會隨着瀏覽器的寬度變化的,見下圖。
css3

1.BFC

爲了解決這個問題,首先,咱們來理解一下何爲BFC。web

BFC(Block Formatting Context)直譯爲「塊級格式化範圍」。面試

BFC提供了一個環境,HTML元素在這個環境中按照必定規則進行佈局。它不會影響到其它環境中的佈局。能夠把它理解成是一個獨立的容器,而且這個容器的裏box的佈局,與這個容器外的絕不相干。瀏覽器

觸發BFC的條件
  1. float的值不爲none。
  2. overflow的值不爲visible。
  3. display的值爲table-cell, table-caption, inline-block中的任何一個。
  4. position的值不爲relative和static。

爲了加深咱們理解BFC爲什麼物,下面看一個例子,上代碼。app

.wrapper{ border: 5px solid #000; }
    .red { background-color:red; }
    .yellow { background-color:yellow; }
    .orange { background-color:orange; }
    .green { background-color:green; }
    .box{ width:100px; height:100px; float:left; }
<div class="wrapper">
        <div class="container">
            <div class="red box"></div>
            <div class="yellow box"></div>
        </div>
        <div class="container">
            <div class="orange box"></div>
            <div class="green box"></div>
        </div>
    </div>

見效果:
佈局

很明顯,.wrapper中全部的box都是浮動,父級標籤沒有被內容撐開,雖然.red、.yellow和.orange和.green是在兩個不一樣的div中,可是仍不會換行。這是因爲設置了浮動元素的塊會造成一個BFC佈局,前面提到過了:flex

  1. 對於一個BFC來講它不會影響到其餘環境的佈局,反之亦然。
  2. 在BFC中,每個元素左外邊與包含塊的左邊相接觸(對於從右到左的格式化,右外邊接觸右邊),即便存在浮動也是如此。
  3. 當容器有足夠的剩餘空間容納BFC的寬度時,全部瀏覽器都會將BFC放置在浮動元素所在行的剩餘空間內。
  4. 在進行普通流中的塊級非替換元素的高度計算時,浮動子元素不參與計算。
  5. 在計算生成了BFC 的元素的高度時,其浮動子元素應該參與計算。
    故呈現了這樣的效果。

若想要讓每個.container中的元素都單獨佔據一行,可讓.container變成BFC佈局(overflow:hidden)。
flexbox

看到這裏。相信你對BFC也有必定的理解了。如若不理解,能夠看看這篇文章,有可取之處。
關於Block Formatting Context--BFC和IE的hasLayout

關於IE的layout能夠看看這篇文章
IE的layout屬性詳解


2.左側固定,右側自定義佈局實現

回到題目,下面來看看如何實現左側固定,右側自適應佈局

<div class="container">
        <div class="left"></div>
        <div class="right"></div>
    </div>

2.1利用BFC之方法一

因爲在BFC中,每個元素左外邊與包含塊的左邊相接觸(對於從右到左的格式化,右外邊接觸右邊),即便存在浮動也是如此。建立了BFC的元素不能與浮動元素重疊。且當容器有足夠的剩餘空間容納BFC的寬度時,全部瀏覽器都會將BFC放置在浮動元素所在行的剩餘空間內。利用這些特性,就能夠達到效果。

.left{
        float: left;
        width: 200px;
        height: 200px;
        background: green;
    }
    .right{
        overflow: hidden;
        height: 300px;
        background: red;
    }

2.2利用margin-left

首先仍是設置left浮動讓他變爲BFC,由2.1方法可知,在BFC中,每個元素左外邊與包含塊的左邊相接觸(對於從右到左的格式化,右外邊接觸右邊),即便存在浮動也是如此。因此left和right會重疊。而後利用margin-left讓right騰出位置。

.left{
            float: left;
            width: 200px;
            height: 200px;
            background: green;
        }
        .right{
            margin-left: 200px;
            height: 300px;
            background: red;
        }

2.3使用絕對定位

一樣,這個方法和2.2方法相似,也是left的造成BFC方式不一樣,就不過多描述了。

.container{
        position: relative;
    }
    .left{
        position: absolute;
        left: 0;
        top: 0;
        width: 200px;
        height: 200px;
        background: green;
    }
    .right{
        margin-left: 200px;
        height: 200px;
        background: red;
    }

2.4利用flex佈局

flex佈局走天下阿。。可是兼容性問題仍是擺在那裏,有所取捨吧。

.container{
        display: flex;
        display: -webkit-box;
        display: -moz-box;
        display: -ms-flexbox;
        width:100%;
        height: 200px;
    }
    .left{
        width: 200px;
        background: green;
    }
    .right{
        // 若是此處用width:100%會致使左側元素不足固定寬度,由於left+right的寬度大於父級寬度,會進行一個等比縮放
        //width:100%;
        flex:1;
        background: red;
    }

2.5利用grid佈局

.container{
        display: grid;
        grid-template-rows: 200px;
        grid-template-columns: 200px auto;
        width:100%;
    }
    .left{
        background: green;
    }
    .right{
        background: red;
    }

2.6利用table-cell

.container{
        display: table;
        width:100%;
    }
    .left{
        display: table-cell;
        height: 200px;
        width: 200px;
        background: green;
    }
    .right{
        display: table-cell;
        height: 200px;
        background: red;
    }

知識擴展

前面提到了BFC,與之相似的還有IFC,GFC,FFC。。很暈吧,貼上兩個連接,但願你看了能有所收穫。
CSS魔法堂:從新認識Box Model、IFC、BFC和Collapsing margins
css3之BFC、IFC、GFC和FFC


以上內容,若有錯誤請指出,不甚感激。

相關文章
相關標籤/搜索