CSS3為我們提供了一種可伸縮的靈活的web頁面配置方式-flexbox布局,它具有很強大的功能,可以很輕鬆實現很多複雜布局,在它出現之前,我們經常使用的布局方式是浮動或者固定寬度+百分比來進行布局,代碼量較大且難以理解。
為了更好理解flexbox布局,這裡首先要介紹幾個概念:
如果所示:
(1)主軸(側軸),flexbox布局裡面將一個可伸縮容器按照水平和垂直方向分為主軸或側軸,如果你想讓這個容器中的可伸縮項目在水平方向上可伸縮展開,那麼水平方向上就是主軸,垂直方向上是側軸,反之亦然;
(2)主軸(側軸)長度,當確定了哪個是主軸哪個是側軸之後,在主軸方向上可伸縮容器的尺寸(寬或高)就被稱作主軸長度,側軸方向上的容器尺寸(寬或高)就被稱作側軸長度;
(3)主軸(側軸)起點,主軸(側軸)終點,例如主軸方向是水平方向,通常在水平方向上網頁布局是從左向右的,那麼可伸縮容器的左border就是主軸起點,右border就是主軸終點,側軸是在垂直方向,通常是從上到下的,所以上border就是側軸起點,下border就是側軸終點;
(4)伸縮容器:如果要構建一個可伸縮的盒子,這些可伸縮的項目必須要由一個display:flex的屬性的盒子包裹起來,這個盒子就叫做伸縮容器;
(5)伸縮項目:包含在伸縮容器中需要進行伸縮布局的元素被稱作伸縮項目;
明確以上概念之後就可以來構建flexbox布局了;
第一步,構建一個flexbox容器,並在容器中放置幾個可伸縮項目,如下:
css代碼:
.flex-container{ display:flex; width:600px; height:230px; background-color: #ccc; }.flex-item{ background-color:blue; width: 100px; margin: 5px; }
HTML代碼:
<p class="flex-container"> <p class="flex-item ">A</p> <p class="flex-item ">B</p> <p class="flex-item ">A</p> <p class="flex-item ">B</p> </p>
效果如下:
其中四個可伸縮的項目在水平方向上被排列成了一行,同時可伸縮項目相靠左對齊;
display:flex代表這個容器是一個可伸縮容器,還可以取值為inline-flex,兩者的區別在於前者將這個容器渲染為區塊層級元素,後者將其渲染為內嵌元素。
這裡有幾個預設的屬性雖然沒有設定,但是預設值確實起作用了,它們是:
flex-direction屬性,它的取值為row,column,column-reverse,row-reverse,預設值是row,表示在水平方向上展開可伸縮項,如果取column代表在垂直方向上展開可伸縮項目,column-reverse,row-reverse代表相反方向,通俗講,flex-direction屬性就是用來定義主軸側軸方向的。給以上效果添加flex-direction:column效果如下:
justify-content屬性,用來表示可伸縮項目在主軸方向上的對齊,可以取值為flex-start,flex-end,center,space-between,space-around,其中flex-start,flex-end,表示相對於主軸起點和終點對齊,center表示置中對齊,space-between表示左右對齊並將剩餘空間在主軸方向上進行平均分配,space-around表示置中對齊然後在主軸方向上將剩餘空間平均分配
justify-content:space-between
css代碼:
.flex-container{ display:flex; width:600px; height:230px; background-color: #ccc; justify-content: space-between; }.flex-item{ background-color:blue; width: 100px; margin: 5px; }
效果如下:
可以看到它將各個可伸縮項目在主軸方向上左右對齊並平分了剩餘空間;
justify-content:space-around
css代碼:
.flex-container{ display:flex; width:600px; height:230px; background-color: #ccc; justify-content: space-around; }.flex-item{ background-color:blue; width: 100px; margin: 5px; }
效果如下:
可以看到這個屬性讓可伸縮項目沿著主軸方向進行了置中對齊並且均分了剩餘空間;
align-items屬性:該屬性是用來表示可伸縮項目在側軸方向上的對齊,可取的值有flex-start,flex-end,center,baseline,stretch,需要解釋的是baseline值,它是按照一個計算出來的基準線然後讓這些項目沿這個基準線對齊,基準線的計算取決於可伸縮項目的尺寸及內容,如下:
align-items:baseline;
css代碼:
.flex-container{ display:flex; flex-direction: row; width:600px; height:230px; background-color: #ccc; justify-content: space-around; align-items:baseline; } .flex-item{ background-color:blue; width: 100px; margin: 5px;; } .a{ margin-top: 10px; height: 100px; } .b{ margin-top: 20px; height: 150px; } .c{ margin-top: 30px; height: 80px; }
HTML代碼:
<p class="flex-container"> <p class="flex-item a">A</p> <p class="flex-item b">B</p> <p class="flex-item c">A</p> <p class="flex-item a">B</p> </p>
效果如下:
可以看到四個可伸縮項目在側軸方向上(垂直方向)高度不一,margin不一樣,但是最後都按照計算出來的一個基準線對齊;
align-items:stretch;
這個是取值會讓可伸縮項目在側軸方向上進行展開,前提是這些項目在側軸方向上沒有設定尺寸,否則會按照你設定的尺寸來渲染。
css代碼:
.flex-container{ display:flex; flex-direction: row; width:600px; height:230px; background-color: #ccc; justify-content: space-around; align-items:stretch; } .flex-item{ background-color:blue; width: 100px; /*height: 100px;*/ margin: 5px;; }
HTML代碼:
<p class="flex-container"> <p class="flex-item ">A</p> <p class="flex-item ">B</p> <p class="flex-item ">A</p> <p class="flex-item ">B</p> </p>
效果如下:
可以看到這些可伸縮項目在側軸方向上被展開了,因為在垂直方向上沒有設定高度。
到目前為止,我們所有的伸縮項目都是在一行或者一列上進行的,並沒有進行換行和換列,flex-wrap屬性工作表示是否支援換行或者換列,它有nowrap,wrap,wrap-reverse三個取值,nowrap是預設值,表示不換行或者換列,wrap表示換行或者換列,wrap-reverse表示支援換行或者換列,但是會沿著相反方向進行排列(如主軸是垂直方向換行後就按照先下後上的順序來排列伸縮項)
css代碼:
.flex-container{ display:flex; flex-direction: row; width:600px; height:230px; background-color: #ccc; justify-content: space-around; align-items:baseline; flex-wrap: wrap; } .flex-item{ background-color:blue; width: 100px; height: 70px; margin: 5px;; }
HTML代碼:
<p class="flex-container"> <p class="flex-item ">A</p> <p class="flex-item ">B</p> <p class="flex-item ">A</p> <p class="flex-item ">B</p> <p class="flex-item ">A</p> <p class="flex-item ">B</p> <p class="flex-item ">A</p> <p class="flex-item ">B</p></p>
效果如下:
可以看到伸縮項增多之後一行難以放下的時候會接著換行。wrap屬性保證換行後按照正常的從上到下順序排列
align-content屬性用來表示換行之後各個伸縮行的對齊,它的取值有 stretch,flex-start,flex-end,center,space-between,space-around,意義和align-items屬性取值意義相同,上面我們將7個伸縮項目分成了兩行來排列,
將css代碼添加align-content屬性,html代碼不變,如下:
CSS代碼:
.flex-container{ display:flex; flex-direction: row; width:600px; height:230px; background-color: #ccc; justify-content: space-around; align-items:baseline; flex-wrap: wrap; align-content: space-between; } .flex-item{ background-color:blue; width: 100px; height: 70px; margin: 5px;; }
效果如下:
可以看到兩個伸縮行在側軸(垂直)方向上左右對齊了。
flex-flow屬性,該屬性是個複屬性,它是flex-direction和flex-wrap的複合屬性,flex-direction:row;flex-wrap:wrap就等同於flex-flow:row wrap
order屬性,該屬性用來表示伸縮項目的相片順序,正常情況下伸縮項目會按照主軸起點到主軸終點排列,遇到換行或者換列會按照從側軸起點到終點進行排列(除非設定了某些 對齊的reverse),但是某些情況下這種預設顯示順序不符合要求,可以採用給伸縮項添加order屬性來指定排列順序,預設情況下,每個伸縮項的order都是0,改屬性可正可負,越大的值會被排列在越後面。
css代碼:
.flex-container{ display:flex; width:600px; height:230px; background-color: #ccc; justify-content: space-around; align-items:baseline; flex-flow: row wrap; align-content: space-between; } .flex-item{ background-color:blue; width: 100px; height: 70px; margin: 5px;; } .order1{ order:1; } .order2{ order:2; }
HTML代碼:
<p class="flex-container"> <p class="flex-item order1">1</p> <p class="flex-item order2">2</p> <p class="flex-item ">3</p> <p class="flex-item ">4</p> <p class="flex-item ">5</p> <p class="flex-item ">6</p> <p class="flex-item ">7</p> <p class="flex-item ">8</p></p>
效果如下:
預設情況下,會按照HTML的順序1-8進行顯示,但是由於給p1和2設定了大於0的order,所以他們被放在了最後顯示(因為其他沒有被設定的p的order預設屬性都是0)
margin屬性在flexbox布局中有很強大的作用,如果給某個可伸縮項設定某個方向上的margin為auto,那麼這個可伸縮項就會在這個方向上佔用該方向的剩餘空間來作為自己的這個方向上的margin。
css代碼:
.flex-container{ display:flex; width:600px; height:230px; background-color: #ccc; justify-content: space-around; align-items:baseline; flex-flow: row wrap; align-content: space-between; } .flex-item{ background-color:blue; width: 100px; height: 70px; margin: 5px;; } .a{ margin-right:auto; }
HTML代碼:
<p class="flex-container"> <p class="flex-item a">1</p> <p class="flex-item ">2</p> <p class="flex-item ">3</p></p>
效果如下:
由於給伸縮項1添加了margin-right為auto,所以它獨佔了本行的剩餘空間作為它的right margin值。
利用這個特性,我們在flexbox布局中很容易實現可伸縮元素的垂直水平置中,
css代碼;
.flex-container{ display:flex; width:600px; height:230px; background-color: #ccc; justify-content: space-around; align-items:baseline; flex-flow: row wrap; align-content: space-between; } .flex-item{ background-color:blue; width: 100px; height: 70px; margin: 5px;; } .a{ margin:auto; }
HTML代碼:
<p class="flex-container"> <p class="flex-item a">1</p></p>
效果如下:
align-self屬性,該屬性是給各個可伸縮項設定自己的在側軸上的對齊的,之前在容器上設定的align-item屬性是作為一個整體設定的,所有的元素對齊都一樣,align-self屬性會覆蓋之前的align-item屬性,讓每個可伸縮項在側軸上具有不同的對齊,取值和align-item相同:
css代碼:
.flex-container{ display:flex; flex-direction: row; width:600px; height:230px; background-color: #ccc; justify-content: space-around; align-items:baseline; align-content: space-between; } .flex-item{ background-color:blue; width: 100px; height: 70px; margin: 5px;; } .a{ align-self:flex-start ; } .b{ align-self:flex-end; } .c{ align-self:center; }
html代碼:
<p class="flex-container"> <p class="flex-item a">1</p> <p class="flex-item b">2</p> <p class="flex-item c">3</p></p>
效果如下:
可以看到三個伸縮項在側軸上被賦予了不同的對齊。
flex屬性,這個屬性是加在伸縮項上面的,它定義了伸縮項如何分配主軸尺寸,通常取值為auto或者數字,auto瀏覽器會自動均分,數字會按照伸縮項所佔的數字比重來分配空間,
這個屬性會覆蓋伸縮項在主軸上設定的尺寸,當給主軸上伸縮項設定了尺寸(寬或高)和這個屬性的時候,事實上還是會按照這個屬性來進行空間分配。
css代碼:
.flex-container{ display:flex; flex-direction: row; width:600px; height:230px; background-color: #ccc; justify-content: space-around; align-items:baseline; align-content: space-between; } .flex-item{ background-color:blue; width: 100px; height: 70px; margin: 5px;; } .a{ align-self:flex-start ; flex:1; } .b{ align-self:flex-end; flex:2; } .c{ align-self:center; flex:1; }
HTML代碼:
<p class="flex-container"> <p class="flex-item a">1</p> <p class="flex-item b">2</p> <p class="flex-item c">3</p></p>
效果如下:
可以看到伸縮項儘管設定了寬度,但是最終還是按照我們設定的flex比例對水平空間進行了分割。