title: flex布局
date: 2017-07-07 14:13:33
tags: css筆記
flexbox是什么
即使不知道視窗大小或者未知元素情況之下都可以智能的、靈活的調整和分配元素和空間兩者之間的關系。簡單的理解,就是可以自動調整,計算元素在容器空間中的大小。
使用flexbox
要開始使用flexbox,必須先讓父元素變成一個flex容器,而此時子元素就變成了flex項目。
可以在父元素中設置display:flex
或者display:inline-flex
。這樣一個flexbox格式上下文就啟動了。
html結構
<ul> <!--parent element-->
<li></li> <!--first child element-->
<li></li> <!--second child element-->
<li></li> <!--third child element-->
</ul>
css樣式
ul {
display: flex;
border: 1px solid pink;
}
li {
list-style: none;
width: 100px;
height: 100px;
background-color: #8cacea;
margin: 8px;
}
flex容器屬性
flex-direction || flex-wrap || flex-flow || justify-content || align-items || align-content
當父元素設置為一個flex容器后,這幾個屬性可以直接使用在flex容器上。
flex-direction
flex-direction
屬性控制flex項目沿著主軸(Main Axis)的排列方向。
這個屬性具有四個值,分別是水平、垂直、水平反向、垂直反向
row(默認) || column || row-reverse || column-reverse
簡單來說就是flex-direction
屬性讓你決定flex項目如何排列,其實水平和垂直在flex中不是方向概念,它們常常被稱為主軸(Main-Axis)和側軸(Cross-Axis)
如果把flex-direction
屬性改為column
,這時flex項目將沿著Cross-Axis從上到下垂直排列。
html結構
<ul> <!--parent element-->
<li></li> <!--first child element-->
<li></li> <!--second child element-->
<li></li> <!--third child element-->
</ul>
css樣式
ul {
display: flex;
flex-direction: column;
border: 1px solid pink;
}
li {
list-style: none;
width: 100px;
height: 100px;
background-color: #8cacea;
margin: 8px;
}
在
flex-direction
改變方向后,實際上是改變的Main-Axis和Cross-Axis兩個軸的方向,如果設置flex-direction: column;
,那么實際上就是Main-Axis和Cross-Axis調換了位置。這將會影響之后基于Main-Axis和Cross-Axis的所有flex屬性的設置。
flex-wrap
flex-wrap
屬性有三個屬性值,分別是換行、不換行、反向換行
wrap || nowrap(默認) || wrap-reverse
flex的默認行為會在一行內容納所有的flex項目,即使瀏覽器出現滾動條(當flex項目的總體寬度大于瀏覽器窗口寬度)。默認是不換行的。
當flex項目過多時,也不會換行,所以每個項目會被壓縮。而且如果flex項目元素內有類似文字等內容會撐開flex項目,那么瀏覽器就會出現滾動條。
如果希望flex容器在其flex項目達到一定數量能換行,將flex-wrap
設置為wrap
即可。當一行再不能包含所有列表項的默認寬度,就會多行排列。
除此之外,還有一個值wrap-reverse
。它讓flex項目在容器中多行排列,只是方向是相反的。
flex-flow
flex-flow
是flex-direction
和flex-wrap
兩個屬性的連寫屬性。
就好比
border: 1px solid red
的概念
flex-flow: row wrap
相當于flex-direction: row; flex-wrap: wrap;
的寫法。
justify-content
justify-content
屬性主要定義了flex項目在Main-Axis上的對齊方式,有五個值可選:
flex-start(默認) || flex-end || center || space-between || space-around
justify-content: flex-start;
是讓所有flex項目靠Main-Axis開始邊緣(左對齊),也就是默認。
justify-content: flex-end;
是讓所有flex項目靠Main-Axis結束邊緣(右對齊)。
justify-content: center;
讓所有flex項目排在Main-Axis的中間(居中)
justify-content: space-between;
讓除了第一個和最后一個flex項目的兩者間間距相同(兩端對齊)
justify-content: space-around;
讓每個flex項目具有相同的空間,相當于是給每個flex項目相同的margin-left
和margin-right
align-items
align-items
屬性類似于justify-content
屬性,主要是控制flex項目在Cross-Axis對齊方式,有五個可選值:
flex-start || flex-end || center || stretch(默認) || baseline
align-items: stretch;
在沒有設置flex高度的情況下,讓所有的flex項目高度和flex容器高度一樣。
align-items: flex-start;
讓所有flex項目靠Cross-Axis開始邊緣(頂部對齊)
align-items: flex-end;
讓所有flex項目靠Cross-Axis結束邊緣(底部對齊)
align-items: center;
讓flex項目在Cross-Axis中間(居中對齊)
align-items: baseline;
讓所有flex項目在Cross-Axis上沿著他們自己的基線對齊
align-content
align-content
必須用于多行的flex容器,也是用來控制flex項目在flex容器里的排列方式,效果和align-items
相似,可選五個值:
flex-start || flex-end || center || stretch(默認)
align-content: stretch;
會拉伸flex項目,讓他們沿著Cross-Axis適用flex容器可用的空間。
align-content: flex-start;
讓多行flex項目靠Cross-Axis開始邊緣。
align-content: flex-end;
讓多行flex項目靠Cross-Axis結束位置
align-content: center;
讓多行flex項目在Cross-Axis中間
flex項目屬性
order || flex-grow || flex-shrink || flex-basis
order
允許flex項目在一個flex容器中重新排序,基本上可以改變flex項目的順序從一個位置移到另一個地方。
這也意味著flex項目的位置改變在html中不需要改變源代碼。
order
的默認值是0,也可以接收一個正值或一個負值。數值越大的flex項目排序越往后,如果兩個以上flex項目有相同的order
值,flex項目重新排序是基于html源文件的位置進行排序
<ul>
<li style="font-size:24px;">列表項1</li>
<li style="font-size:24px;">列表項2</li>
<li style="font-size:24px;">列表項3</li>
<li style="font-size:24px;">列表項4</li>
<li style="font-size:24px;">列表項5</li>
</ul>
li:nth-child(1) {
order: 2;
}
li:nth-child(2) {
order: 1;
}
li:nth-child(3) {
order: 3;
}
li:nth-child(4) {
order: 3;
}
flex-grow和flex-shrink
flex-grow
屬性控制flex項目在容器有多余的控件如何放大。默認值0。
flex-shrink
屬性控制flex項目在容器沒有額外空間又如何縮小。默認值1。
取值范圍是0或者大于0的任何正數值,這個數值是設置flex項目在容器中所占比。
首先來看flex-grow: 0;
的效果
flex容器有多余的空間,這時將flex-grow: 1;
即可讓flex忽略自己本身的寬度,平均分配flex內部的空間,通過這個數值也可以改變每個flex項目所占空間的占比。
而flex-shrink
屬性和flex-grow
屬性是相反的,現在設置flex-shrink: 0;
看一下。
如果像是這樣flex項目的寬度多出了flex容器,那么就需要將flex-shrink: 1;
,這樣會壓縮flex項目的寬度,讓其平均分配flex容器的空間,數值也是flex的占比。
flex-basis
flex-basis
屬性可以指定flex項目的初始大小,也就是在flex-grow
和flex-shrink
調整之前的大小。
flex-basis
默認值是auto
,可以取任何用于width屬性的值,比如% || em || rem || px
等等。但是如果要設置為0的話也要帶有單位,flex-basis: 0;
這種寫法是錯誤的。
flex-basis: auto;
這是默認情況flex項目的寬度。
可以看出flex項目的寬度就是由內容撐開,而使用flex-basis: 150px;
這樣flex的寬度就被設置為了固定的150px;
flex連寫
flex
是flex-grow
、flex-shrink
、flex-basis
三個屬性的連寫。
flex: 0 1 auto;
相當于flex-grow: 0; flex-shrink: 1; flex-basis: auto;
align-self
align-self
可以改變一個彈性項目沿著側軸的位置,而不影響相鄰的彈性項目。該屬性的可選值為:
auto(默認) || flex-start || flex-end || center || baseline || stretch。
align-self: flex-end;
、align-self: center;
、align-self: flex-start;
三個值的效果。
align-self: stretch;
會將目標flex項目拉伸,以沿著Cross-Axis填滿flex容器的可用空間。
align-self:baseline;
將目標flex項目沿著基線對齊,在這里效果和flex-start
效果相同。
最后一個是align-self: auto;
是將目標flex項目的值設置為父元素的align-items
的值,或者如果該元素沒有父元素的話,就設置為stretch
。
相對和絕對flex項目
相對和絕對flex項目主要區別在于間距和如何計算間距,相對flex項目內的間距是根據它的內容大小來計算的,而在覺得flex項目中,只根據flex屬性來計算。
先來看相對flex,flex項目設置flex: auto
,這個設置和flex: 1 1 auto;
是相同的,這樣flex項目就是基于其包含內容的大小而計算的。下面的圖中每個flex項目的內容不同,其占的寬度也不相同。
下面來設置成絕對的flex項目,flex: 1;
這個設置和flex: 1 1 0;
效果是一樣的。flex-basis: 0;
的情況下,flex項目會基于flex-grow
來計算自己的空間,而flex-grow: 1;
,所以每個flex所占空間相同。
從上面可以得出結論,絕對flex項目的寬度只基于flex屬性,相對flex的寬度基于內容的大小。