一、背景 在日常佈局中,無論是兩欄佈局還是三欄佈局,使用的頻率都非常高 兩欄佈局 兩欄佈局實現效果就是將頁面分割成左右寬度不等的兩列,寬度較小的列設置為固定寬度,剩餘寬度由另一列撐滿, 比如 Ant Design 文檔,藍色區域為主要內容佈局容器,側邊欄為次要內容佈局容器 這裡稱寬度較小的列父元素為 ...
一、背景
在日常佈局中,無論是兩欄佈局還是三欄佈局,使用的頻率都非常高
兩欄佈局
兩欄佈局實現效果就是將頁面分割成左右寬度不等的兩列,寬度較小的列設置為固定寬度,剩餘寬度由另一列撐滿,
比如 Ant Design
文檔,藍色區域為主要內容佈局容器,側邊欄為次要內容佈局容器
這裡稱寬度較小的列父元素為次要佈局容器,寬度較大的列父元素為主要佈局容器
這種佈局適用於內容上具有明顯主次關係的網頁
三欄佈局
三欄佈局按照左中右的順序進行排列,通常中間列最寬,左右兩列次之
大家最常見的就是github
:
二、兩欄佈局
兩欄佈局非常常見,往往是以一個定寬欄和一個自適應的欄併排展示存在
實現思路也非常的簡單:
- 使用 float 左浮左邊欄
- 右邊模塊使用 margin-left 撐出內容塊做內容展示
- 為父級元素添加BFC,防止下方元素飛到上方內容
代碼如下:
<style> .box{ overflow: hidden; 添加BFC } .left { float: left; width: 200px; background-color: gray; height: 400px; } .right { margin-left: 210px; background-color: lightgray; height: 200px; } </style> <div class="box"> <div class="left">左邊</div> <div class="right">右邊</div> </div>
還有一種更為簡單的使用則是採取:flex彈性佈局
flex彈性佈局
<style> .box{ display: flex; } .left { width: 100px; } .right { flex: 1; } </style> <div class="box"> <div class="left">左邊</div> <div class="right">右邊</div> </div>
flex
可以說是最好的方案了,代碼少,使用簡單
註意的是,flex
容器的一個預設屬性值:align-items: stretch;
這個屬性導致了列等高的效果。 為了讓兩個盒子高度自動,需要設置: align-items: flex-start
三、三欄佈局
實現三欄佈局中間自適應的佈局方式有:
- 兩邊使用 float,中間使用 margin
- 兩邊使用 absolute,中間使用 margin
- 兩邊使用 float 和負 margin
- display: table 實現
- flex實現
- grid網格佈局
兩邊使用 float,中間使用 margin
需要將中間的內容放在html
結構最後,否則右側會臣在中間內容的下方
實現代碼如下:
<style> .wrap { background: #eee; overflow: hidden; <!-- 生成BFC,計算高度時考慮浮動的元素 --> padding: 20px; height: 200px; } .left { width: 200px; height: 200px; float: left; background: coral; } .right { width: 120px; height: 200px; float: right; background: lightblue; } .middle { margin-left: 220px; height: 200px; background: lightpink; margin-right: 140px; } </style> <div class="wrap"> <div class="left">左側</div> <div class="right">右側</div> <div class="middle">中間</div> </div>
原理如下:
- 兩邊固定寬度,中間寬度自適應。
- 利用中間元素的margin值控制兩邊的間距
- 寬度小於左右部分寬度之和時,右側部分會被擠下去
這種實現方式存在缺陷:
-
主體內容是最後載入的。
-
右邊在主體內容之前,如果是響應式設計,不能簡單的換行展示
兩邊使用 absolute,中間使用 margin
基於絕對定位的三欄佈局:註意絕對定位的元素脫離文檔流,相對於最近的已經定位的祖先元素進行定位。無需考慮HTML中結構的順序
<style> .container { position: relative; } .left, .right, .main { height: 200px; line-height: 200px; text-align: center; } .left { position: absolute; top: 0; left: 0; width: 100px; background: green; } .right { position: absolute; top: 0; right: 0; width: 100px; background: green; } .main { margin: 0 110px; background: black; color: white; } </style> <div class="container"> <div class="left">左邊固定寬度</div> <div class="right">右邊固定寬度</div> <div class="main">中間自適應</div> </div>
實現流程:
- 左右兩邊使用絕對定位,固定在兩側。
- 中間占滿一行,但通過 margin和左右兩邊留出10px的間隔
兩邊使用 float 和負 margin
<style> .left, .right, .main { height: 200px; line-height: 200px; text-align: center; } .main-wrapper { float: left; width: 100%; } .main { margin: 0 110px; background: black; color: white; } .left, .right { float: left; width: 100px; margin-left: -100%; background: green; } .right { margin-left: -100px; /* 同自身寬度 */ } </style> <div class="main-wrapper"> <div class="main">中間自適應</div> </div> <div class="left">左邊固定寬度</div> <div class="right">右邊固定寬度</div>
實現過程:
- 中間使用了雙層標簽,外層是浮動的,以便左中右能在同一行展示
- 左邊通過使用負 margin-left:-100%,相當於中間的寬度,所以向上偏移到左側
- 右邊通過使用負 margin-left:-100px,相當於自身寬度,所以向上偏移到最右側
缺點:
- 增加了 .main-wrapper 一層,結構變複雜
- 使用負 margin,調試也相對麻煩
使用 display: table 實現
<table>
標簽用於展示行列數據,不適合用於佈局。但是可以使用 display: table
來實現佈局的效果
<style> .container { height: 200px; line-height: 200px; text-align: center; display: table; table-layout: fixed; width: 100%; } .left, .right, .main { display: table-cell; } .left, .right { width: 100px; background: green; } .main { background: black; color: white; width: 100%; } </style> <div class="container"> <div class="left">左邊固定寬度</div> <div class="main">中間自適應</div> <div class="right">右邊固定寬度</div> </div>
實現原理:
- 層通過 display: table設置為表格,設置 table-layout: fixed`表示列寬自身寬度決定,而不是自動計算。
- 內層的左中右通過 display: table-cell設置為表格單元。
- 左右設置固定寬度,中間設置 width: 100% 填充剩下的寬度
使用flex實現
利用flex
彈性佈局,可以簡單實現中間自適應
代碼如下:
<style type="text/css"> .wrap { display: flex; justify-content: space-between; } .left, .right, .middle { height: 100px; } .left { width: 200px; background: coral; } .right { width: 120px; background: lightblue; } .middle { background: #555; width: 100%; margin: 0 20px; } </style> <div class="wrap"> <div class="left">左側</div> <div class="middle">中間</div> <div class="right">右側</div> </div>
實現過程:
- 僅需將容器設置為
display:flex;
, - 盒內元素兩端對其,將中間元素設置為
100%
寬度,或者設為flex:1
,即可填充空白 - 盒內元素的高度撐開容器的高度
優點:
- 結構簡單直觀
- 可以結合 flex的其他功能實現更多效果,例如使用 order屬性調整顯示順序,讓主體內容優先載入,但展示在中間
grid網格佈局
代碼如下:
<style> .wrap { display: grid; width: 100%; grid-template-columns: 300px auto 300px; } .left, .right, .middle { height: 100px; } .left { background: coral; } .right { background: lightblue; } .middle { background: #555; } </style> <div class="wrap"> <div class="left">左側</div> <div class="middle">中間</div> <div class="right">右側</div> </div>
跟flex
彈性佈局一樣的簡單
參考文獻
-
https://zhuqingguang.github.io/2017/08/16/adapting-two-layout/
-
https://segmentfault.com/a/1190000008705541
如果對您有所幫助,歡迎您點個關註,我會定時更新技術文檔,大家一起討論學習,一起進步。