兩欄布局

兩欄布局

左邊固定,右邊自適應的兩欄布局

首先創(chuàng)建基本的HTML布局和最基本的樣式。

左邊固定寬度,高度不固定

<div class="wrapper"id="wrapper">

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

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

</div>

基本的樣式是,兩個盒子相距20px, 左側(cè)盒子寬120px,右側(cè)盒子寬度自適應。基本的CSS樣式如下:

.wrapper{padding:15px20px;border:1pxdashed#ff6c60;}

.left{width:120px;border:5pxsolid#ddd;}

.right{margin-left:20px;border:5pxsolid#ddd;}

1.雙inline-block方案

.wrapper-inline-block { box-sizing: content-box; font-size: 0; // 消除空格的影響}

.wrapper-inline-block .left,.wrapper-inline-block .right { display: inline-block; vertical-align: top; // 頂端對齊 font-size: 14px; box-sizing: border-box;}

.wrapper-inline-block .right { width: calc(100% - 140px);}

這種方法是通過width: calc(100% - 140px)來動態(tài)計算右側(cè)盒子的寬度。需要知道右側(cè)盒子距離左邊的距離,以及左側(cè)盒子具體的寬度(content+padding+border),以此計算父容器寬度的100%需要減去的數(shù)值。同時,還需要知道右側(cè)盒子的寬度是否包含border的寬度。

在這里,為了簡單的計算右側(cè)盒子準確的寬度,設置了子元素的box-sizing:border-box;以及父元素的box-sizing: content-box;。

同時,作為兩個inline-block的盒子,必須設置vertical-align來使其頂端對齊。

另外,為了準確地應用計算出來的寬度,需要消除div之間的空格,需要通過設置父容器的font-size: 0;,或者用注釋消除html中的空格等方法。

缺點:

需要知道左側(cè)盒子的寬度,兩個盒子的距離,還要設置各個元素的box-sizing

需要消除空格字符的影響

需要設置vertical-align: top滿足頂端對齊

2.雙float方案

.wrapper-double-float { overflow: auto; // 清除浮動 box-sizing: content-box;}

.wrapper-double-float .left,.wrapper-double-float .right { float: left; box-sizing: border-box;}

.wrapper-double-float .right { width: calc(100% - 140px);}

缺點:

需要知道左側(cè)盒子的寬度,兩個盒子的距離,還要設置各個元素的box-sizing。

父元素需要清除浮動。

3.float+margin-left方案

.wrapper-float { overflow: hidden; // 清除浮動}

.wrapper-float .left { float: left;}

.wrapper-float .right { margin-left: 150px;}

上面兩種方案都是利用了CSS的calc()函數(shù)來計算寬度值。下面兩種方案則是利用了block級別的元素盒子的寬度具有填滿父容器,并隨著父容器的寬度自適應流動特性。

但是block級別的元素都是獨占一行的,所以要想辦法讓兩個block排列到一起。

我們知道,block級別的元素會認為浮動的元素不存在,但是inline級別的元素能識別到浮動的元素。這樣,block級別的元素就可以和浮動的元素同處一行了。

為了讓右側(cè)盒子和左側(cè)盒子保持距離,需要為左側(cè)盒子留出足夠的距離。這個距離的大小為左側(cè)盒子的寬度以及兩個盒子之間的距離之和。然后將該值設置為右側(cè)盒子的margin-left。

缺點:

需要清除浮動

需要計算右側(cè)盒子的margin-left

4.使用absolute+margin-left方法

.wrapper-absolute .left { position: absolute;}

.wrapper-absolute .right { margin-left: 150px;}

缺點:

使用了絕對定位,若是用在某個div中,需要更改父容器的position。

沒有清除浮動的方法,若左側(cè)盒子高于右側(cè)盒子,就會超出父容器的高度。因此只能通過設置父容器的min-height來放置這種情況。

5.使用float+BFC方法

.wrapper-float-bfc { overflow: auto;}

.wrapper-float-bfc .left { float: left; margin-right: 20px;}

.wrapper-float-bfc .right { margin-left: 0; overflow: auto;}

這個方案同樣是利用了左側(cè)浮動,但是右側(cè)盒子通過overflow: auto;形成了BFC,因此右側(cè)盒子不會與浮動的元素重疊

這種情況下,只需要為左側(cè)的浮動盒子設置margin-right,就可以實現(xiàn)兩個盒子的距離了。而右側(cè)盒子是block級別的,所以寬度能實現(xiàn)自適應。

缺點:

父元素需要清除浮動

6.flex方案

.wrapper-flex { display: flex; align-items: flex-start;}

.wrapper-flex .left { flex: 0 0 auto;}

.wrapper-flex .right { flex: 1 1 auto;}

flex可以說是最好的方案了,代碼少,使用簡單。有朝一日,大家都改用現(xiàn)代瀏覽器,就可以使用了。

需要注意的是,flex容器的一個默認屬性值:align-items: stretch;。這個屬性導致了列等高的效果。

為了讓兩個盒子高度自動,需要設置:align-items: flex-start;

7.grid方案

.wrapper-grid { display: grid; grid-template-columns: 120px 1fr; align-items: start;}

.wrapper-grid .left,.wrapper-grid .right { box-sizing: border-box;}

.wrapper-grid .left { grid-column: 1;}

.wrapper-grid .right { grid-column: 2;}

grid布局也有列等高的默認效果。需要設置: align-items: start;。

grid布局還有一個值得注意的小地方和flex不同:在使用margin-left的時候,grid布局默認是box-sizing設置的盒寬度之間的位置。而flex則是使用兩個div的border或者padding外側(cè)之間的距離。

極限情況

最后可以再看一下在父容器極限小的情況下,不同方案的表現(xiàn)。主要分成四種情況:

動態(tài)計算寬度的情況

兩種方案: 雙inline-block方案和雙float方案。寬度極限小時,右側(cè)的div寬度會非常小,由于遵循流動布局,所以右側(cè)div會移動到下一行。

動態(tài)計算右側(cè)margin-left的情況

兩種方案: float+margin-left方案和absolute+margin-left方案。寬度極限小時,由于右側(cè)的div忽略了文檔流中左側(cè)div的存在,所以其依舊會存在于這一行,并被隱藏。

float+BFC方案的情況

這種情況下,由于BFC與float的特殊關(guān)系,右側(cè)div在寬度減小到最小后,也會掉落到下一行。

flex和grid的情況

這種情況下,默認兩種布局方式都不會放不下的div移動到下一行。不過 flex布局可以通過 flex-flow: wrap;來設置多余的div移動到下一行。 grid布局暫不支持。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容