兩列自適應佈局方案整理

前提

本文討論的是兩列自適應佈局:左列定寬/不定寬,右列自適應。css

雖然分這兩種狀況,但實際上不定寬的方案一樣適用於定寬的場景,所以不定寬的方案泛用度更高。html

左列定寬,右列自適應

margin + float

<div class="parent">
	<div class="left"><p>left</p></div>
	<div class="right-fix">
		<div class="right">
			<p>right</p><p>right</p>
		</div>
	</div>
</div>
複製代碼
.left{
		float: left;     //向左浮動
        width: 100px;    //固定寬度
		position: relative;//因爲.left與.right-fix重合,且.right-fix在DOM樹上的位置比.left要後,所以.right-fix會遮擋住.left,設置.left爲relative可讓其冒出來。
	}
	.right-fix{
		float: right;     //向右浮動
        width: 100%;    //爲了自適應設爲100%
		margin-left: -100px;//因爲寬度設爲100%,.right-fix遭到瀏覽器換行處理;所以經過設置負的margin值,在左側製造出100px的空白,使.right-fix與.left重合(即處於同一行)
	}
	.right{
		margin-left: 120px;    //因爲.left和.right-fix重合了,所以給.right設置一個margin-left,避免內容區(.right)與.left重合。另外,120px - 100px = 多出來的20px實際上就至關於.left和.right之間的間隔了。
	}
複製代碼

這個方法其實已是兼顧到低版本IE的完善版本了,缺點是代碼冗長,並且有兩個關鍵知識點比較難理解:前端

  1. 給.left加上position:relative;怎麼就能讓.left冒出來而不受.right-fix的遮擋了呢?
  2. .right-fix設置負的margin-left,怎麼就能使.left與.right-fix重合了呢?

再者,這個方案因爲.right-fix的margin-left和.left的width高度耦合,所以沒法實現自適應,只能應用在左列(固然右列也成)固定寬度的場景。瀏覽器

absolute

<div class="parent">
	<div class="left">
		<p>left</p>
	</div>
	<div class="right">
		<p>right</p>
		<p>right</p>
	</div>
</div>
複製代碼
.parent{
	position: relative;
}
.left{
	position: absolute;
	left: 0;
	width: 100px;
}
.right{
	position: absolute;
	left: 120px;    //比.left的left多出20px,至關於間隔
	right: 0;
}
複製代碼

這種方法是經過absolute配合left/right進行佈局:ide

  1. 設置display: absolute後,經過top/right/bottom/left能夠實現對元素的位置進行像素級的任意控制。所以,使用left屬性便可控制各元素的起始位置,避免重疊。
  2. 自適應的關鍵在於leftright屬性,在對元素同時設置這兩個屬性後,元素的寬度便會遭到拉伸,實現自適應。
  3. 須要注意的是父級元素須要設置display: relative

這種方案很容易理解,但缺點就是不能作到**「不定寬」**,由於.left和.right的left屬性的值高度相關。佈局

左列不定寬,右列自適應

float + BFC

<div class="parent">
	<div class="left">
		<p>left</p>
	</div>
	<div class="right">
		<p>right</p>
		<p>right</p>
	</div>
</div>
複製代碼
.left{
	float: left;
	width: 100px;
	margin-right: 20px;    //造成20px的間隔
}
.right{
	overflow: hidden; //經過設置overflow: hidden來觸發BFC特性
}
複製代碼

這個方法主要是應用到BFC的一個特性:flex

  1. 浮動元素的塊狀兄弟元素會無視浮動元素的位置,儘可能佔滿一整行,這樣該兄弟元素就會被浮動元素覆蓋。
  2. 若浮動元素的塊狀兄弟元素爲BFC,則不會佔滿一整行,而是根據浮動元素的寬度,佔據該行剩下的寬度,避免與浮動元素重疊。
  3. 浮動元素與其塊狀BFC兄弟元素之間的margin能夠生效,這將繼續減小兄弟元素的寬度。

並非必定要在.right上用overflow: hidden;,只要能觸發BFC就行了,另外在IE6上也能夠觸發haslayout特性(推薦用*zoom: 1;)。 因爲.right的寬度是自動計算的,不須要設置任何與.left寬度相關的css,所以.left的寬度能夠不固定(由內容盒子決定)。ui

table佈局

<div class="parent">
	<div class="left">
		<p>left</p>
	</div>
	<div class="right">
		<p>right</p>
		<p>right</p>
	</div>
</div>
複製代碼
.parent{
	display: table; width: 100%;
	table-layout: fixed;
}
.left,.right{
	display: table-cell;
}
.left{
	width: 100px;
	padding-right: 20px;
}
複製代碼

這個方法是表格佈局的典型運用。說真的,我也很迷惘要不要使用表格佈局,畢竟已是上個時代的產物了,雖然已經再也不用<table>的HTML結構了,但用上相應的CSS其實思路跟之前是變化不大的。 這個方法主要是利用了表格(table)的寬度必然等於其全部單元格(table-cell)加起來的總寬度,那麼只要表格的寬度必定,其中一個(或幾個)單元格的寬度也必定,那麼另一個未設置寬度的單元格則會默認佔滿剩下的寬度,即實現自適應。spa

flex

<div class="parent">
	<div class="left">
		<p>left</p>
	</div>
	<div class="right">
		<p>right</p>
		<p>right</p>
	</div>
</div>
複製代碼
.parent{
	display: flex;
}
.left{
	margin-right: 20px;
}
.right{
	flex: 1;
}
.left p{width: 200px;}
複製代碼

flex佈局的自適應我就很少說了,原本就是設計來自適應的,只須要用上flex: 1;,就能讓.right分到.parent的寬度減去.left的寬度。設計

推薦使用

我我的是比較推薦用float + BFC方案,瀏覽器兼容性很好,代碼量也少,另外也很好理解;移動端上也能夠考慮用上flex方案,不過仍是那一句,注意用舊版的flex,兼容性會好一點。

擴展

說是說**「兩列自適應佈局」**,實際上,只要知足「只有一列是自適應」這一條件,多少列布局都行。

參考文章

相關文章
相關標籤/搜索