面試官問:你有多少種方式實現三欄佈局?

爐火糖粥、發表於2020-07-05

一、什麼是三欄佈局

  三欄佈局即左右元素固定寬度,中間元素自適應。代表佈局有聖盃佈局和雙飛翼佈局,當然還有其他方式可以實現,下面是詳細介紹。

二、實現方式

  1.自身浮動  

    元素順序:中間盒子必須放在最後,左右元素任意排列
    原理:左邊元素左浮動 右邊元素右浮動
    缺點:當瀏覽器寬度不足以容納三個元素時,中間元素不消失,最右側的元素會被擠到第二排。浮動對後續元素影響較大(使用時一定要清除浮動)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style>
			*{
				margin: 0;
				padding: 0;
			}
			.main{
				height: 600px;
				width: 100%;
			}
			.left{
				width: 160px;
				height: 100px;
				background-color: #000;
				float: left;
			}
			.right{
				width: 480px;
				height: 100px;
				background-color: red;
				float: right;
			}
			.middle{
				width: 100%;
				height: 100px;
				background-color: blue;
			}
		</style>
	</head>
	<body>
		<div class="main">
			<div class="left"></div>
			<div class="right"></div>
			<div class="middle"></div>	
		</div>
	</body>
</html>

  2.絕對定位

    元素順序:任意擺放即可
    原理:將左右兩邊使用absolute定位,中間元素使用margin預留左右元素的寬度
    缺點:當瀏覽器頁面不足以容納三個元素時,中間元素會寬度減小(最小到0),右側元素會覆蓋到左側元素上。兩側高度無法支撐總高度

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style>
			*{
				margin: 0;
				padding: 0;
			}
			.main{
				height: 600px;
				width: 100%;
				position: relative;
				margin: 0;
			}
			.left{
				width: 260px;
				height: 100px;
				background-color: #000;
				position: absolute;
				top: 0;
				left: 0;
			}
			.right{
				width: 280px;
				height: 100px;
				background-color: red;
				position: absolute;
				top: 0;
				right: 0;
			}
			.middle{
				height: 100px;
				background-color: blue;
				margin: 0 280px 0 260px;
			}
		</style>
	</head>
	<body>
		<div class="main">
			<div class="left"></div>
			<div class="right"></div>
			<div class="middle"></div>	

		</div>
	</body>
</html>

  3.函式計算    

    元素順序:無要求
    原理:使用calc函式,計算父元素的寬度減去左右元素的寬度
    缺點:存在相容性問題,需要IE9+才可以正常使用。元素採用了浮動,對後續元素有影響

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<style type="text/css">
			*{
				margin: 0;
				padding: 0;
			}
			.container{
				overflow: hidden;
			}
			.left,.right{
				float: left;
				height: 100px;
				width: 100px;
				background:red;
			}
			.center{
				float: left; 
				height: 100px;
				width:calc(100% - 200px);
				background:yellow;
			}
		</style>
	</head>
	<body>
		<div class="container">
			<div class="left">left</div>
	        <div class="center">center</div>
	        <div class="right">right</div>
	    </div>
	</body>
</html>

  4.表格佈局

    元素順序:中間元素必須在兩個div之間
    原理:父元素設定display:table,子元素設定display:table-cell
    缺點:相容性IE8+,不利於SEO

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8">
		<title>表格佈局</title>
		<style>
			*{
				margin:0;
				padding:0;
			}
			.main{
				width:100%;
				display:table;
			}
			.main> div{
				height:200px;
				display:table-cell;
			}
			.left{
				width:100px;
				background-color: black;
			}
			.middle{
				background-color:red;
			}
			.right{
				width: 200px;
				background-color: blue;

			}
		</style>
	</head>
	<body>
		<div class="main">
			<div class="left"></div>
			<div class="middle"></div>
			<div class="right"></div>
			
				
		</div>
		
	</body>
</html>

  5.聖盃佈局(重點,面試常問)

    元素順序:中間元素位於開頭,左右元素無要求
    原理:父元素使用padding預留左右元素的位置,三個元素浮動,左元素使用margin負值和相對定位調整位置,右元素用margin負值調整位置
    缺點:中間部分寬度小於左側時,佈局混亂

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<style type="text/css"> 
		*{
			margin: 0;
			padding: 0;
		}
		.main {
			height: 600px;
			padding: 0 100px;/* 左右元素的寬度決定 */
			
		}

		.middle {
			width: 100%;
			height: 100px;
			background-color: blue;
			float: left;
		}

		.left{
			width: 100px;
			height: 100px;
			background-color: #000;
			margin-left: -100%;
			position: relative;
			float: left;
			right: 100px;/* 自身寬度 */
			
		}
		.right {
			width: 100px;
			height: 100px;
			background-color: red;
			margin-right: -100px;/* 自身寬度 */
			float: left;
		}
		
		</style>
	</head>
	<body>
		<div class="main">
		    <div class="middle">main</div>
		    <div class="left">left</div>
		    <dvi class="right">right</div>
		</div>
	</body>
</html>

  6.雙飛翼佈局(重點,面試常問)

    元素順序:中間元素位於開頭,左右元素無要求
    原理:在中間元素內部建立子元素,子元素設定margin(值是左右元素的寬),用來預留左右元素的位置。左中右元素都設定浮動,左右元素設定margin負值
    缺點:增加了DOM節點,加大了渲染樹生成的計算量

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>雙飛翼佈局</title>
		<style type="text/css">
			*{
				margin: 0;
				padding: 0;
			}
			.col{
				float: left;
			}			
			#main {
				width: 100%;
				height: 200px;
				background-color: #ccc;
			}			
			#main-wrap {
				margin: 0 190px;/*這是聖盃和雙飛翼最明顯的區別,在main內部使用的是margin,而聖盃是直接在container部分使用padding*/		
			}	
			#left{
				width: 190px;
				height: 200px;
				margin-left: -100%;
				background-color: #0000FF;
			}		
			#right {
				width: 190px;
				height: 200px;
				margin-left: -190px;
				background-color: #0000FF;
			}
		</style>
	</head>
	<body>
		<div id="container">
		    <div id="main" class="col">
		        <div id="main-wrap"> #main </div>
		    </div>
		    <div id="left" class="col">#left</div>
		    <div id="right" class="col">#right</div>
		</div>
	</body>
</html>

  7.flex佈局(重點,面試常問)

    元素順序:無要求
    原理:父元素設定flex,中心元素設定flex:1
    缺點:flex有相容性問題,IE11+支援較好

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<style type="text/css">
		   *{
			   margin: 0;
			   padding: 0;
		   }
			#box{
				width:100%;
				height:100px;
				display:flex;
			}
			#left,#right{
				width:200px;
				height:100px;
				background-color:blue;
			}
			#center{
				flex:1;
				height:100px;
				background-color:#f00;
			}

		</style>
	</head>
	<body>
		<div id="box">
			<div id="left">left</div>
			<div id="center">center</div>
			<div id="right">right</div>
		</div>
	</body>
</html>

  8.網格佈局

    元素順序:中間元素必須在兩個div之間
    原理:父元素設定display:grid,使用grid-template-rows定義行高,使用grid-template-columns定義列寬即可
    缺點:相容性IE10+

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8">
		<title>表格佈局</title>
		<style>
			*{
				margin:0;
				padding:0;
			}
			.main{
				width:100%;
				display:grid;
				grid-template-rows: 100px;
				grid-template-columns: 300px auto 300px;
			}
			.left{
				background-color: black;
			}
			.middle{
				background-color:red;
			}
			.right{
				background-color: blue;
			}
		</style>
	</head>
	<body>
		<div class="main">
			<div class="left"></div>
			<div class="middle"></div>
			<div class="right"></div>
			
				
		</div>
		
	</body>
</html>

三、總結

  上面一共列舉了8中方式去實現三欄佈局,也列出了他們各自的缺點,效果圖我就不放了,cv程式碼自己執行一下就可以了。博主個人覺得,如果在不考慮相容性的情況下,肯定選擇後四種是比較好的,當然還可能有其他實現方法,歡迎大家評論、留言

  ps:面試可能會問你如果中間元素需要優先載入,最好是選擇方式5、6、7。因為他們的中間元素都是在左右元素的前面的

  

相關文章