前言
flex為css的布局帶來了新的時(shí)代罗晕,作為一個(gè)重構(gòu)工程師济欢,我們再也不用局限于float和position,特別是在移動(dòng)端小渊,我們可以利用flex輕松實(shí)現(xiàn)以往float和psition很難實(shí)現(xiàn)甚至是無法實(shí)現(xiàn)的布局法褥。 本文主要講解flex的三個(gè)子屬性:flex-grow、flex-shrink酬屉、flex-basis半等。他們只是博大精深的flex中的一部分揍愁,
flex布局發(fā)生在父容器和子容器之間。父容器需要有flex的環(huán)境(display:flex;)杀饵,子容器才能根據(jù)自身的屬性來布局莽囤,簡單的說,就是瓜分父容器的空間切距。相反就是說如果父容器沒有flex的環(huán)境朽缎,那么子容器就無法使用flex的規(guī)則來劃分父容器的空間。
講到瓜分父容器的空看射众,那么首先需要講一個(gè)很重要的詞:剩余空間沙兰。
什么是剩余空間呢皇忿?具備flex環(huán)境的父容器,通常是有一條主軸和一條側(cè)軸最筒,默認(rèn)情況下主軸就是水平從左向右的,側(cè)軸是垂直從上到下的(類似書寫模式)蔚叨。 剩余空間就是父容器在主軸的方向上還有多少可用的空間床蜘。比如看下面這段html結(jié)構(gòu):
container就是父容器,B1 B2 B3就是子容器缅叠,假如container的width是500px悄泥,那么剩余空間就是:500px - B1.width - B2.width - B3.width。嗯就是這么簡單肤粱!
flex-grow (default:0)
知道了剩余空間的概念弹囚,首先來看一下flex-grow。上面那個(gè)例子领曼,我們假設(shè)container的width是500px鸥鹉,現(xiàn)在我們再假設(shè)B1、B2庶骄、B3的width是100px毁渗,那么剩余空間就是500-100*3=200。 知道了剩余空間有什么用呢单刁?這個(gè)時(shí)候flex-grow就該出場了灸异,假如我們這個(gè)時(shí)候?qū)1設(shè)置flex-grow:1,那么我們會(huì)發(fā)現(xiàn)羔飞,B1把B2和B3都擠到右邊了肺樟,也就是說剩余的200px空間都被B1占據(jù)了,所以此時(shí)B1的width比實(shí)際設(shè)置的值要大逻淌。
所以這里flex-grow的意思已經(jīng)很明顯了么伯,就是索取父容器的剩余空間,默認(rèn)值是0卡儒,就是三個(gè)子容器都不索取剩余空間田柔。但是當(dāng)B1設(shè)置為1的時(shí)候俐巴,剩余空間就會(huì)被分成一份,然后都給了B1硬爆。 如果此時(shí)B2設(shè)置了flex-grow:2欣舵,那么說明B2也參與到瓜分剩余空間中來,并且他是占據(jù)了剩余空間中的2份摆屯,那么此時(shí)父容器就會(huì)把剩余空間分為3份邻遏,然后1份給到B1,2份給到B2虐骑,
flex-basis (default:auto)
初次見flex-basis這個(gè)屬性准验,還挺疑惑的,不知道它是用來干嘛的廷没。 后來研究發(fā)發(fā)現(xiàn)糊饱,這個(gè)屬性值的作用也就是width的替代品。 如果子容器設(shè)置了flex-basis或者width颠黎,那么在分配空間之前另锋,他們會(huì)先跟父容器預(yù)約這么多的空間,然后剩下的才是歸入到剩余空間狭归,然后父容器再把剩余空間分配給設(shè)置了flex-grow的容器夭坪。 如果同時(shí)設(shè)置flex-basis和width,那么width屬性會(huì)被覆蓋过椎,也就是說flex-basis的優(yōu)先級(jí)比width高室梅。有一點(diǎn)需要注意,如果flex-basis和width其中有一個(gè)是auto疚宇,那么另外一個(gè)非auto的屬性優(yōu)先級(jí)會(huì)更高亡鼠。
tips:flex-basis和width為auto值,那最后的空間就是根據(jù)內(nèi)容多少來定的敷待,內(nèi)容多占據(jù)的水平空間就多间涵。
flex-shrink (default:1)
好了,上面講了這么多榜揖,你們應(yīng)該都明白了把勾哩。 有人會(huì)想,不就這樣嘛举哟,很容易啊钳幅,不就是剩余空間的分配嗎?
是的炎滞,上面講的都是剩余空間的分配。但是诬乞,你有沒有想過還有沒有其他的情況呢册赛?可以發(fā)現(xiàn)钠导,上面講的例子B1 B2 B3的寬度總和都是沒有超過父容器的寬度的。 那如果三個(gè)子容器的寬度總和超過父容器的寬度呢森瘪?那還有剩余空間可以分配嗎牡属,此時(shí)瀏覽器又是怎么處理呢?請看下面:
tips:flex環(huán)境默認(rèn)是不換行的扼睬,即使父容器寬度不夠也不會(huì)逮栅,除非設(shè)置flex-wrap來換行
此時(shí)我們會(huì)發(fā)現(xiàn),B1設(shè)置的flex-grow沒有作用窗宇,不但沒有獲取到剩余空間,他的空間甚至是比他定義的300px還要小军俊,而且我們發(fā)現(xiàn)B2和B3的空間也相應(yīng)的被壓縮了侥加。 那么這里的問題就是:
1粪躬、為什么flex-grow沒有作用,反而被壓縮呢镰官?
2提前、三個(gè)容器的壓縮比例是這樣的呢?
這就是這一節(jié)的重點(diǎn)了 -> flex-shrink
同樣的泳唠,三個(gè)容器處于flex環(huán)境中,所以布局之前警检,父容器還是會(huì)計(jì)算剩余空間。 這一次計(jì)算的結(jié)果是這樣的:剩余空間=500px - 300px - 160px - 120px = -80px扇雕,剩余空間是一個(gè)負(fù)數(shù)所以很容易理解第一個(gè)問題拓售,即使是設(shè)置了flex-grow,但是由于沒有剩余空間镶奉,所以B1分配到的空間是0础淤。
由于flex環(huán)境的父容器的寬度500px是不會(huì)變,所以子容器的寬度總和最多為父容器的寬度鸽凶,那就只有兩個(gè)辦法:第一個(gè)是使子容器換行建峭,第二個(gè)是壓縮子容器使之剛好撐滿父容器的寬度玻侥。 因?yàn)閒lex子容器是默認(rèn)不換行的亿蒸,所以這里不做討論掌桩。而第二種壓縮,實(shí)際上就是上面例子表現(xiàn)出來的樣式〔ǖ海現(xiàn)在就遇到了上面第二個(gè)問題,這三個(gè)的壓縮比例是多少呢则拷,各自需要壓縮的空間是多少呢?
這個(gè)時(shí)候就需要談?wù)刦lex-shrink煌茬,這個(gè)屬性其實(shí)就是定義一個(gè)子容器的壓縮比例物延。他的默認(rèn)值是1宣旱,所以上面那個(gè)例子叛薯,就是三個(gè)子容器壓縮的比例是一樣的 1:1:1。 如果此時(shí)我們設(shè)置B1的壓縮比例是2耗溜,那會(huì)怎樣呢?
我們可以發(fā)現(xiàn)抖拴,B1被壓縮的更多了。而B2和B3得到了跟多的空間阿宅。那我們怎么得出他們各自的壓縮率呢?我們假設(shè)B2 B3的壓縮率是X1蛉鹿,那么B1的壓縮率就是X2了,那就有了如下方程:
X2 = 2 * X1;
500 = 300 * X2 + 160 * X1 + 120 * X1;
通過上面我們就可以解出X1和X2等于多少了妖异,這樣就可以計(jì)算出壓縮率和被壓縮了多少空間了。
總結(jié)
通過上面的分析他膳,我們就可以得出這樣幾個(gè)結(jié)論:
1绒窑、剩余空間=父容器空間-子容器1.flex-basis/width - 子容器2.flex-basis/width - …
2棕孙、如果父容器空間不夠,就走壓縮flex-shrink分歇,否則走擴(kuò)張flex-grow;
3、如果你不希望某個(gè)容器在任何時(shí)候都不被壓縮葬燎,那設(shè)置flex-shrink:0;
4谱净、如果子容器的的flex-basis設(shè)置為0(width也可以,不過flex-basis更符合語義)壕探,那么計(jì)算剩余空間的時(shí)候?qū)⒉粫?huì)為子容器預(yù)留空間。
5李请、如果子容器的的flex-basis設(shè)置為auto(width也可以,不過flex-basis更符合語義)导盅,那么計(jì)算剩余空間的時(shí)候?qū)?huì)根據(jù)子容器內(nèi)容的多少來預(yù)留空間
轉(zhuǎn)載:深入理解css3中的flex-grow、flex-shrink白翻、flex-basis