彈性盒模型(伸縮布局)
一、彈性盒模型(伸縮布局)
flxible box
前言:
彈性布局,用來為盒子提供靈活性。就像是當把瀏覽器縮小的的時候,不會像float屬性會依然往下掉,靈活性不好。而且當布局盒裝模型的時候依賴於float+position+display,例如實現垂直居中就很不方便了。
一)語法
{display: flex;} /*作為塊級伸縮盒子顯示*/
{display: inline-flex;} /*作為內聯塊級伸縮盒子顯示:行內的元素也能使用*/
是不是感覺很熟悉呢?這就類似於 block 和 inline-block 。
註意:
1.任何的元素都能設置flex ;
2.兼容: {display: -webkit-flex;display: flex;}
3.當 {display:flex;} 後float、.clearfix 、vertical-align全部都失效;
4.要在 {display:flex;} 的盒子上設置寬度max-width:;而不是width這樣瀏覽器才能按比例去伸縮’;
5.關於p{flex:1;}:子元素即使有寬也沒有什麽卵用了,因為 {flex:1;} 會自動將div平均分配。
按照下面的套路,每個的p標簽的 width:100px;
div>p*6
span>a*6
div{display: flex;max-width: 600px;} div > p{flex: 1;}
/*任何元素都可以*/ span{display: flex;max-width: 600px;} span > a{flex: 1;}
二)基本概念
采用flex布局的元素,稱為”容器“(父元素flex-contain);
它的所有子元素自動成為容器的成員,稱為”flex項目“(子元素flex-item)。
容器(父級)加的樣式 項目(子元素)
註意:以下這些全給 父級 加的樣式
- flex-direction
- flex-wrap
- flex-flow
- justify-content
- align-items
- align-content
1.flex-direction屬性
1)定義:flex-direction屬性決定主軸的方向(即項目的排列方向)
div{ flex-direction: row; /*水平:默認*/ flex-direction: row-reverse; /*反向水平*/ flex-direction: column; /*垂直*/ flex-direction: column-reverse; /*反向垂直*/ }
2)伸縮流的方向:分為 主軸(x軸main axis)和 交叉軸(y軸cross axis)。
為了更好地去讓你明白,我用了同一個的例子: 首先,我用了一個div容器(父級)來包裹著6個p項目(子元素)。。然後div設置主軸為x軸並且正向;
div>p*6
span>a*6
div{display: flex;max-width: 600px;height: 600px;border: 1px solid #000; flex-direction: row; /*水平:默認*/
flex-direction: row-reverse; /*反向水平*/
} p{height: 100px;width: 100px;} p:nth-child(1){background: red;} p:nth-child(2){background: green;} p:nth-child(3){background: blue;} p:nth-child(4){background: yellow;} p:nth-child(5){background: gray;} p:nth-child(6){background: orange;}
於是,效果圖:
註意:主軸方向規定後,在主軸方向上,是不會溢出的。交叉軸方向則會溢出。
2.flex-wrap屬性
1)定義:如果一條軸線排不下,如何換行。
div{ flex-wrap: nowrap; /*默認:不換行*/ flex-wrap: wrap ; /*換行,第一行在上方*/ flex-wrap: wrap-reverse; /*反向換行,第一行在下方*/ }
2)條件:
- 固定容器(父元素);
- 項目(子元素)總寬度的和 > 容器的最大寬度max-width
驗證:我在容器div上添加了 {flex-wrap: wrap;} 然後,把項目的寬度 p{width: 200px;} ,之後
效果:
發現如果硬性讓項目的寬度 p{width: 200px;} ,然後硬性不換行 {flex-wrap: nowrap;} ,那麽項目的寬度就會變為容器的總寬度自動平分後的寬度,在這例子裏,也就是100px;
3.flex-flow屬性
1)定義: flex-decoration和flex-wrap的復合的寫法
{flex-flow: row wrap;} /*根據伸縮流方向是否換行*/
4.justify-content屬性
1)定義:規定伸縮項目(子元素)在伸縮容器(父元素)主軸(x/y)的對齊方式
div{
justify-content: flex-start; /*默認:左對齊*/ justify-content: flex-end; /*右對齊*/ justify-content: center; /*居中*/ justify-content: space-between; /*兩端對齊,項目之間的間隔都相等,中間的距離平均分配*/ justify-content: space-around; /*相當於加了左右的margin*/
}
其他的好理解,為了避免混淆主流主軸的方向 {flex-direction: row-reverse;} 關於內容是否反向的問題。。在此驗證 {justify-content: flex-end; } ,為了驗證方便,我把容器的寬度變為:
div{width: 700px;}
5.align-items屬性
1)定義:規定交叉軸的項目的對齊方式
/*下面假設交叉軸的方向為從上往下*/
div{
align-items: flex-start; /*交叉軸的起點對齊*/ align-items: flex-end; /*交叉軸的終點對齊*/ align-items: center; /*交叉軸的中點對齊*/ align-items: baseline; /*項目的第一行文字的基線對齊 字與字的基線對齊 可以用line-heigh來判斷*/ align-items: stretch; /*註意:默認 如果不設置高度或者設為auto 項目將占滿容器(父級)的高度*/
}
6.align-content屬性
1)定義:定義了多根軸線的對齊方式。如果項目只有一根軸線,該屬性不起作用。
div{ align-content: stretch; /* 默認 和上面的align-item不一樣 註意 它和space-between不一樣*/ align-content: flex-start; align-content: flex-end; align-content: center; align-content: space-between; /*間隔空間 意思就是上下之間的距離是除他們所占距離外的全部空間 就是他們靠邊*/ align-content: space-around; }
註意:以下這些全給 項目 加的樣式
- order
- flex-grow
- flex-shrink
- flex-basis
- flex
- align-self
1.order屬性
1)定義:定義項目的排列順序。
p{ order: 0; /*默認值*/ }
註意:
- 默認值為0;
- 支持負值;
- 數值越小越靠前;
- 不支持小數點。
為說明這個屬性,我決定簡單的說說就好,例子:讓他們的排列順序反向
用笨方法快速理解,其實你懂得:
p{height: 100px;width: 100px;} p:nth-child(1){background: red;order:5;} p:nth-child(2){background: green;order:4;} p:nth-child(3){background: blue;;order:3;} p:nth-child(4){background: yellow;;order:2;} p:nth-child(5){background: gray;;order:1;} p:nth-child(6){background: orange;;order:-1;}
效果圖:
2.flex-grow屬性
1)定義:定義項目的放大比例
p{ flex-grow: 0; /*默認值*/ }
2)註意:
- 默認為0;(如果有剩余的空間,子元素也不會放大)
- 數值越大,放大越厲害;
- 不支持負值;
關於公式:
子元素的增加/放大的寬度 = 父級剩余空間的尺寸 * 元素box-grow占子元素全部和的比
子元素的寬度 = 原有的寬度 + 子元素的增加/放大的寬度
註意:當只有一個子元素 {flex-grow: 1;} ,其他的 {flex-grow: 0;} 的時候,根據公式有1/0=無窮,所以余下的空間都由放大的子元素全占。
3.flex-shrink屬性
1)定義:定義了項目的縮小比例
p{
flex-shrink: 1; /*默認值*/
}
2)註意:
- 默認為1;
- 數值越大,縮小越厲害;數值越小,縮小的越不厲害;
- 不支持負值;
關於公式:
元素收縮的寬度 = 超出的寬度 * 元素flex-shrink占子元素全部和的比
子元素的寬度 = 原有的寬度 - 子元素的收縮的寬度
註意:當只有一個子元素 {flex-grow: 0;}時,其它子元素 {flex-grow: 1;} 的時候,在不斷縮小時,根據公式有0/6=0,所以 {flex-grow: 0;} 的子元素的寬度不變 。
4.flex-basis屬性
1)定義:定義了在分配多余空間之前,項目占據的主軸空間(main size)。瀏覽器根據這個屬性,計算主軸是否有多余空間。它的默認值為auto,即項目的本來大小。
p{ flex-basis: auto; /* 默認值 auto = 項目的本來大小 */ flex-basis: content; /* 沒有width時,默認基於內容自動計算寬度 */ flex-basis: 200px; }
註意:它可以設為跟width或height屬性一樣的值(比如350px),則項目將占據固定空間。
關於一丟丟的小發現:為了方便實驗,我增大了容器的寬度 div{width: 800px;} (由原來的600px變為800px),而其他全部不變。
當我的項目的寬度 p{width: 100px;} 的時候,我定義了 p1{flex-basis: 300px;} ,當縮小盒子的時候,發現 p1{width: 255px;} , p{width: 75px;} ,所以引發我的好奇心。。
因為 超出的寬度:800px-600px=200px, 每1/8縮小的寬度:200px * 1/8 = 25px;(基於flex-shrink的默認值都為1)
所以。。。。就這樣。。。
5.flex復合屬性
1)定義:是flex-grow 、flex-shrink 、 flex-basis的復合
基於最後一個值flex-basis值特殊,沒有寬度的默認值: {flex-basis: content;} (基於內容自動計算寬度)。
p{ flex: 0 1 auto; /*默認值:只會縮小,不會放大,以內容分配寬度,不分配剩下的空間*/ } p{ width: 100px; flex: 0 1 auto; /*默認值:當設定了寬度後,則只會縮小,不會放大,不以內容分配寬度,不分配剩下的空間*/ }
以下值是可以簡寫復合的:
前提:項目的寬度 = 容器的平均分配後的寬度
p{flex: 1;} /*自動平均分配空間,width沒有用了*/ p{width: 100px; flex: 0 1 auto;}
p{flex: auto;} p{flex: 1 1 auto;} /*一起放大,一起縮小,會先讓內容撐開,然後在分配剩下的空間*/
/*不放大,不縮小,會溢出,內容撐開寬度,不分配剩下的寬度*/
p{flex: none;} p{flex: 0 0 auto;}
實在沒法想象flex:none的效果,所以。。。
6.align-self屬性
1)定義:允許單個項目與其它項目(子元素)不同的排列方式,可覆蓋align-items屬性。
p{ align-self: auto ; /*默認值,表示繼承父元素的align-items屬性,如果沒有父元素,則等同於stretch*/ align-self: stretch; /*占滿容器的高度*/ align-self: flex-start; align-self: flex-end ; align-self: center; align-self: baseline; }
註意:項目都有可能分別取這6個值,除了auto,其他都與align-items屬性完全一致。
彈性盒模型(伸縮布局)