1.多欄布局
使用float或position進行頁面布局時,有個比較顯著的缺點,元素之間是各自獨立的,因此經常底部不能對齊,導致頁面中出現一塊空白區域。使用多欄布局,可以將一個元素中的內容分為兩欄或多欄去顯示。
- 元素內部使用多欄布局(指定元素總寬度,多欄均分寬度):
div#div1{
width: 40em; // 指定元素總寬度
column-count: 2; // 指定內部分成兩欄
-moz-column-count: 2; // FireFox
-webkit-column-count: 2; // Safari、Chrome、Opera
}
- 元素內部使用多欄布局(不指定元素總寬度,指定每欄寬度):
// 元素如果沒設定總寬度,則外面要套個容器元素
div#container{
width: 42em;
}
div#div1{
column-count: 2; // 指定元素內部分兩欄
-moz-column-count: 2;
-webkit-column-count: 2;
column-width: 20em; // 指定每欄寬度
-moz-column-width: 20em;
-webkit-column-width: 20em;
}
- 還可以指定多欄之間的間隔距離,以及間隔線:
div#div1{
column-count: 2; // 指定元素內部分兩欄
-moz-column-count: 2;
-webkit-column-count: 2;
column-width: 20em; // 指定每欄寬度
-moz-column-width: 20em;
-webkit-column-width: 20em;
column-gap: 3em; // 指定欄之間間隔距離
-moz-column-gap: 3em;
-webkit-column-gap: 3em;
column-rule: 1px solid red; // 指定欄之間分隔線
-moz-column-rule: 1px solid red;
-webkit-column-rule: 1px solid red;
}
使用多欄布局時,各欄寬度是相等的。也不可能具體指定什么欄中顯示什么內容,因此比較適合用在顯示文章內容的場景,不適合用于布局網頁結構。
2. 盒布局
除多欄布局外,還可以使用盒布局解決使用float或position時多欄底部不能對齊的問題。
- 使用float的舊方式(底部不對齊):
#left-sidebar{
float: left;
width: 200px;
padding: 20px;
background-color: orange;
}
#contents{
float: left;
width: 300px;
padding: 20px;
background-color: yellow;
}
#right-sidebar{
float: left;
width: 200px;
padding: 20px;
background-color: limegreen;
}
#left-sidebar, #contents, #right-sidebar{
box-sizing: border-box;
}
- 使用盒布局:
#container{
display: -moz-box; // 指定使用盒布局 FireFox
display: -webkit-box; // Safari、Chrome、Opera
}
#left-sidebar{ // 刪除float
width: 200px;
padding: 20px;
background-color: orange;
}
#contents{ // 刪除float
width: 300px;
padding: 20px;
background-color: yellow;
}
#right-sidebar{ // 刪除float
width: 200px;
padding: 20px;
background-color: limegreen;
}
#left-sidebar, #contents, #right-sidebar{
box-sizing: border-box;
}
3. 彈性盒布局
在使用盒布局時,我們對各區塊是單獨設定寬度的。如果想讓區塊的總寬度等于瀏覽器的寬度,并且能隨著窗口寬度的改變而改變,那么彈性盒布局就派上用場了。因此相比盒布局,彈性盒布局用來布局整個網頁總體結構無疑是更佳的。
- 將盒布局改成彈性盒布局:
#container{ // box改成flex
display: flex;
}
#left-sidebar{
width: 200px;
padding: 20px;
background-color: orange;
}
#contents{ // 去除中間欄的寬度,改成flex屬性
flex: 1;
padding: 20px;
background-color: yellow;
}
#right-sidebar{
width: 200px;
padding: 20px;
background-color: limegreen;
}
#left-sidebar, #contents, #right-sidebar{
box-sizing: border-box;
}
- 使用order屬性改變元素的顯示順序(內容在最左邊,右欄在中間,左欄在最右邊):
#container{
display: flex;
}
#left-sidebar{
order : 3;
width: 200px;
padding: 20px;
background-color: orange;
}
#contents{
order: 1;
flex: 1; // 是flex-grow、flex-shrink 和 flex-basis的縮寫
padding: 20px;
background-color: yellow;
}
#right-sidebar{
order: 2;
width: 200px;
padding: 20px;
background-color: limegreen;
}
#left-sidebar, #contents, #right-sidebar{
box-sizing: border-box;
}
flex 屬性定義彈性盒模型子元素如何分配“容器剩余空間”,是 flex-grow、flex-shrink 和 flex-basis 屬性的簡寫屬性:
flex: 1: 則其計算值為 flex: 1 1 0%; // 子元素不定義flex相關屬性時的默認值
flex: auto,:則其計算值為 flex: 1 1 auto;// flex-basis為auto,伸縮基準值為自身width值,如果沒有定義width,則基準值為內容寬度
flex: none,:則其計算值為 flex: 0 0 auto;// 本子元素不參與容器剩余空間分配
flex-grow:
擴展比率,即剩余空間是正值時此「flex子項」相對于「flex容器」里其他「flex子項」能分配到空間比例。在「flex」屬性中該值如果被省略則默認為「1」。
flex-shrink:
收縮比率,即剩余空間是負值時此「flex子項」相對于「flex容器」里其他「flex子項」能收縮的空間比例。在收縮的時候收縮比率會以伸縮基準值加權在「flex」屬性中該值如果被省略則默認為「1」。
flex-basis:
伸縮基準值,即在根據伸縮比率計算出剩余空間的分布之前,「flex子項」長度的起始數值。在「flex」屬性中該值如果被省略則默認為「0%」在「flex」屬性中該值如果被指定為「auto」,則伸縮基準值的計算值是自身的width值,如果自身的寬度沒有定義,則長度取決于內容。
- 使用flex-direction改變元素的排列順序
#container{
display: flex;
border: solid 5px blule;
flex-direction: column; // 縱向排列(默認row)
width: 500px
height: 300px;
}
- 控制換行方式
子元素寬度超過容器時,默認會進行伸縮或擴張。可通過制定flex-wrap屬性控制換行:
#container{
display: flex;
border: solid 5px blue;
flex-direction: row;
flex-wrap: wrap; // 換行
width: 500px;
height: 300px;
}
#text-a{
background-color: orange;
}
#text-b{
background-color: yellow;
}
#text-c{
background-color: limegreen;
}
#text-a, #text-b, #text-c{
box-sizing: border-box;
font-size: 1.5em;
font-weight: bold;
// 3個子元素寬度合計超過容器寬度,由于對容器設置了flex-wrap: wrap,因此會換行而不伸縮
width: 250px;
}
4. 彈性盒布局下,指定元素的水平和垂直對齊方式
當flex-grow屬性值不為0時,各子元素在main axis軸方向上自動伸縮,所以justify-content無效。
下面假設彈性盒的布局方向按照默認的flex-direction: row,橫向布局:
-
justify-content指定元素在水平方向(main axis)的對齊方式
justify-content屬性值如下:
flex-start:從main-start開始布局所有子元素
flex-end:從main-end開始布局所有子元素
center:居中布局所有子元素
space-between:將剩余空間平均分配在子元素之間
space-around:子元素周圍平均分配剩余空間下面是一個示例,在容器里指定justify-content:
#container{
display: flex;
border: 5px solid blue;
flex-direction: row;
width: 600px;
height: 30px;
justify-content: flex-end;
}
align-items指定子元素在垂直方向(cross axis)的對齊方式
align-items屬性值如下:
flex-start:從cross-start開始布局所有子元素
flex-end:從cross-end開始布局所有子元素
center:居中布局所有子元素
baseline:
stretch:垂直方向上高度被調整為最大align-self指定某子元素的脫離出align-items的獨立對齊方式
align-self屬性值如下:
auto:繼承父元素的align-items屬性值
其他可指定屬性值同align-items
下面是一個示例,在容器里指定justify-content:
#container{
display: flex;
border: 5px solid blue;
flex-direction: row;
width: 600px;
align-items: flex-start;
}
#div-a{
background-color: orange;
width: 100px;
font-size: 12px;
align-self: flex-end;
}
#div-b{
background-color: yellow;
width: 150px;
font-size: 24px;
}
#div-c{
background-color: limegreen;
width: 200px;
font-size: 36px;
}
彈性盒多行布局時(flex-wrap: wrap),可以使用align-content屬性指定各行的對齊方式。該屬性與align-items的區別在于:align-items指定子元素的對齊方式,而align-content指定行對齊方式。