前面的話
說起自適應布局方式,單列定寬單列自適應布局是最基本的布局形式。本文將從float、inline-block、table、absolute、flex和grid這六種思路來詳細說明如何巧妙地實現布局
float
【思路一】float
說起兩列布局,最常見的就是使用float來實現。float浮動布局的缺點是浮動后會造成文本環繞等效果,以及需要及時清除浮動。如果各浮動元素的高度不同時,可能會出犬牙交錯的效果
【1】float + margin
將定寬的一列使用float,而自適應的一列使用計算后的margin
<style> p{margin: 0;} .parent{overflow: hidden;zoom: 1;} .left{float: left;width: 100px;} .right{margin-left: 120px;} </style>
<div class="parent" style="background-color: lightgrey;"> <div class="left" style="background-color: lightblue;"> <p>left</p> </div> <div class="right" style="background-color: lightgreen;"> <p>right</p> <p>right</p> </div> </div>
[缺點1]IE6-瀏覽器下3像素bug,具體表現在右側首行文字會向右偏移3px。解決辦法是在left元素上設置margin-right: -100px
[缺點2]當右側容器中有元素清除浮動時,會使該元素不與左側浮動元素同行,從而出現文字下沉現象
【2】float + margin + (fix)
(fix)代表增加結構,為了解決上述方法中的兩個缺點,可以通過增加結構來實現。自適應的一列外側增加一層結構.rightWrap並設置浮動。要實現自適應效果,.rightWrap寬度必須設置為100%。若不設置,float后的元素寬度將由內容撐開。同時再配合盒模型屬性的計算,設置計算后的負margin值,使兩列元素在同一行顯示。同時兩列之間的間距由.right的margin值確定。由於右側元素會層疊在左側元素之上,.left需要使用relative來提升層級
<style> p{margin: 0;} .parent{overflow: hidden;zoom: 1;} .left{position: relative;float: left;width: 100px;} .rightWrap{float: left;width: 100%;margin-left: -100px;} .right{margin-left: 120px;} </style>
<div class="parent" style="background-color: lightgrey;"> <div class="left" style="background-color: lightblue;"> <p>left</p> </div> <div class="rightWrap" style="background-color: pink;"> <div class="right" style="background-color: lightgreen;"> <p>right</p> <p>right</p> </div> </div> </div>
【3】float + margin + calc
除了增加結構的方法外,還可以使用calc()
[注意]IE8-、android4.3-、IOS5.1-不支持,android4.4+只支持加減運算
<style> p{margin: 0;} .parent{overflow: hidden;zoom: 1;} .left{float: left;width: 100px;margin-right: 20px;} .right{float: left;width: calc(100% - 120px);} </style>
<div class="parent" style="background-color: lightgrey;"> <div class="left" style="background-color: lightblue;"> <p>left</p> </div> <div class="right" style="background-color: lightgreen;"> <p>right</p> <p>right</p> </div> </div>
【4】float + overflow
還可以使用overflow屬性來觸發bfc,來阻止浮動造成的文字環繞效果。由於使用overflow不會改變元素的寬度屬性,所以不需要重新設置寬度。由於設置overflow:hidden並不會觸發IE6-瀏覽器的haslayout屬性,所以需要設置zoom:1來兼容IE6-瀏覽器
<style> p{margin: 0;} .parent{overflow: hidden;zoom: 1;} .left{ float: left;width: 100px;margin-right: 20px;} .right{overflow: hidden;zoom: 1;} </style>
<div class="parent" style="background-color: lightgrey;"> <div class="left" style="background-color: lightblue;"> <p>left</p> </div> <div class="right" style="background-color: lightgreen;"> <p>right</p> <p>right</p> </div> </div>
inline-block
【思路二】inline-block
inline-block內聯塊布局的主要缺點是需要設置垂直對齊方式vertical-align,則需要處理換行符解析成空格的間隙問題。IE7-瀏覽器不支持給塊級元素設置inline-block屬性,兼容代碼是display:inline;zoom:1;
【1】inline-block + margin + calc
一般來說,要解決inline-block元素之間的間隙問題,要在父級設置font-size為0,然后在子元素中將font-size設置為默認大小
[注意]IE8-、android4.3-、IOS5.1-不支持,android4.4+只支持加減運算
<style> p{margin: 0;} .parent{font-size: 0;} .left{display:inline-block;vertical-align:top;width:100px;margin-right:20px;font-size:16px;} .right{display:inline-block;vertical-align:top;width:calc(100% - 120px);font-size:16px;} </style>
<div class="parent" style="background-color: lightgrey;"> <div class="left" style="background-color: lightblue;"> <p>left</p> </div> <div class="right" style="background-color: lightgreen;"> <p>right</p> <p>right</p> </div> </div>
【2】inline-block + margin + (fix)
<style> p{margin: 0;} .parent{font-size: 0;} .left{position:relative;display:inline-block;vertical-align:top;width:100px;font-size:16px;} .rightWrap{display:inline-block;vertical-align:top;width:100%;margin-left: -100px;font-size:16px;} .right{margin-left: 120px;} </style>
<div class="parent" style="background-color: lightgrey;"> <div class="left" style="background-color: lightblue;"> <p>left</p> </div> <div class="rightWrap" style="background-color: pink;"> <div class="right" style="background-color: lightgreen;"> <p>right</p> <p>right</p> </div> </div> </div>
table
【思路三】table
使用table布局的缺點是元素被設置為table后,內容撐開寬度,所以需要設置width:100%。若要兼容IE7-瀏覽器,需要改為<table>結構。由於table-cell元素無法設置margin,若需要在元素間設置間距,需要增加結構
<style> p{margin: 0;} .parent{display:table;width: 100%;table-layout: fixed;} .left,.rightWrap{display:table-cell;} .left{width: 100px;} .right{margin-left: 20px;} </style>
<div class="parent" style="background-color: lightgrey;"> <div class="left" style="background-color: lightblue;"> <p>left</p> </div> <div class="rightWrap" style="background-color: pink;"> <div class="right" style="background-color: lightgreen;"> <p>right</p> <p>right</p> </div> </div> </div>
absolute
【思路四】absolute
absolute布局的缺點是由於父元素需要設置為relative,且子元素設置為absolute,所以父元素的高度並不是由子元素撐開的,需要單獨設置。
[注意]IE6-不支持相對的偏移屬性同時設置
<style> p{margin: 0;} .parent{position: relative;width:100%;height:40px;} .left{position: absolute;left:0;width:100px;} .right{position: absolute;left:120px;right:0;} </style>
<div class="parent" style="background-color: lightgrey;"> <div class="left" style="background-color: lightblue;"> <p>left</p> </div> <div class="right" style="background-color: lightgreen;"> <p>right</p> <p>right</p> </div> </div>
flex
【思路五】flex
flex彈性盒模型是非常強大的布局方式。但由於其性能消耗較大,適合於局部小范圍的布局
[注意]IE9-瀏覽器不支持
<style> p{margin: 0;} .parent{display: flex;} .left{width:100px;margin-right: 20px;} .right{flex:1;} </style>
<div class="parent" style="background-color: lightgrey;"> <div class="left" style="background-color: lightblue;"> <p>left</p> </div> <div class="right" style="background-color: lightgreen;"> <p>right</p> <p>right</p> </div> </div>
grid
【思路六】: 使用柵格布局grid實現
[注意]IE10-瀏覽器不支持
<style> p{margin: 0;} .parent{display: grid;grid-template-columns: 100px 1fr;grid-gap:20px} </style>
<div class="parent" style="background-color: lightgrey;"> <div class="left" style="background-color: lightblue;"> <p>left</p> </div> <div class="right" style="background-color: lightgreen;"> <p>right</p> <p>right</p> </div> </div>