前兩期講了position 布局和水平布局,這期接著之前的話題繼續(xù)聊聊更新一點的布局方式——Flexbox(彈性布局)获讳。
Overview
Flexbox 也就是 Flexible Box Layout 模塊苇经,是 CSS 提供的用于布局的一套新語法彰导。這套布局包含針對容器(flex container)和針對其直接子元素(彈性項饲梭,flex item)的兩類方法煌张。它可以控制的彈性特征包括:大小苛白、流動方向娃豹、橫縱兩軸的排布、順序等等购裙。Flex 已被 IE11 之后的瀏覽器完美支持懂版,除了少數(shù)惡心的應用,大家應該放心地使用 flexbox躏率;甚至應該盡量避免使用傳統(tǒng)的內(nèi)容布局方式躯畴。
彈性布局是一個 display 屬性民鼓,使用時直接在容器上添加該屬性即可。還是以上一期的導航欄為例:
<ul>
<li><a href="/home">HOME</a></li>
<li><a href="/onion">Onion</a></li>
<li><a href="/garlic">Garlic</a></li>
</ul>
我們給容器 ul 加上 flex 屬性:
ul {
display: flex;
}
效果很明顯蓬抄,彈性項<li>
全部變成了類似于 inline-block 的元素了——水平布局顯現(xiàn)出來了丰嘉。
Flex 方向:主軸和輔軸
Flexbox 可以針對某一區(qū)域控制其中元素的順序、大小嚷缭、分布以及對齊饮亏。事實上這個區(qū)域的元素可以沿著兩個方向排列:
- 主軸(main axis):也就是橫軸,水平方向的排列
- 輔軸(cross axis):也就是縱軸阅爽,垂直方向的排列
默認情況下子元素是依據(jù)主軸從左至右排布路幸,也就是flex-direction: row;
,但還有:row-reverse
付翁、 column
劝赔、column-reverse
等幾種排布。我們對比一下效果:
排布和我們的常識并不沖突胆敞,所以理解起來不難,
- row:從左往右排列
- row-reverse:從右往左排列
- column:從上至下排列
- column-reverse:從下至上排列
空間與對齊
上面提到了主軸和輔軸杂伟,flex 還可以對這兩個方向上的排布作出調整移层,這里需要記住兩個英語單詞:justify和align;從語義來說赫粥,前者翻譯過來是行(水平)排齊观话,后者是列(垂直)排齊。CSS 關鍵字里經(jīng)常出現(xiàn)這兩個單詞越平,大家記得區(qū)分語義频蛔。
justify-content
我們先看水平排布,它的屬性叫justify-content
秦叛,主要有五種:flex-start晦溪、flex-end、center挣跋、space-between三圆、space-around。
ul {
display: flex;
justify-content: flex-start;
}
默認為 flex-start避咆,表示左對齊舟肉;其他幾個也可顧名思義:右對齊、水平居中查库、居間留白路媚、空間環(huán)繞。
這里順便提一個與 flex 有點關系的常規(guī)的布局:如何讓首元素(HOME)左對齊樊销,剩余元素右對齊呢整慎?
很簡單脏款,讓首元素的右 margin 為 auto 即可,原理是:在 flex 布局里院领,外邊距 auto 會耗盡 flex 容器的所食诿空間,剩余彈性項就這樣被前面的 margin 擠到了行尾比然。
ul li:first-child {
margin-right: auto;
}
同理丈氓,讓第二個元素的左 margin 為 auto 也可以實現(xiàn)上面一模一樣的效果:
ul li:nth-child(2) {
margin-left: auto;
}
再換一個布局,如何把上圖的首元素擠到右側强法,剩余元素依舊左對齊呢万俗?
這里需要用到 Flexbox 的 order 屬性,它是彈性項的屬性饮怯,可以幫助我們完全擺脫源碼中的順序約數(shù)闰歪。Order 的默認值是 0,表示按源碼中的順序排列蓖墅。我給首元素加一個很大的 order 值库倘,如 999;瀏覽器發(fā)現(xiàn)它的 order 大于所有兄弟元素论矾,就直接把它放到了行尾教翩。然后我再把它的左 margin 設為 auto,首元素就被擠到最右側了贪壳。
ul li:first-child {
order: 999;
margin-left: auto;
}
Order 值不需要連續(xù)饱亿,且可正可負;只要可以比大小闰靴,相應的項就可以按值升序排列了彪笼。
align-items
Flexbox 有水平對齊,自然也有垂直對齊蚂且,叫 align-itmes配猫,是容器屬性,主要有四種: stretch杏死、flex-start章姓、center、flex-end识埋。
ul {
display: flex;
align-items: stretch;
}
默認值是stretch
——高度自動拉伸凡伊;其他值不拉伸高度,分別是上中下對齊窒舟。上述示例中所有元素的高度是一致的系忙,所以看不出垂直對齊的效果;下圖我特意把首元素的高度增加了一倍惠豺,大家就可以發(fā)現(xiàn)區(qū)別了:
align-items 屬性會對所有彈性項起效果银还,假如我只想調整末尾元素為居中對齊风宁,那該怎么辦呢?
Flexbox 提供了一個叫 align-self 的屬性為彈性項調整個別項的對齊方式蛹疯。我們只需要把 last-child 設成垂直居中即可:
li:last-child {
align-self: center;
}
這里順便提一下戒财,flexbox 并沒有justify-self
這個屬性,也就是說我們無法調整個別項的水平排布捺弦。嗯饮寞,輔軸功能并不見得比主軸弱。
伸縮
伸縮屬性也是用于調整個別項的排布列吼,屬性名就叫flex
li:fist-child {
flex: 1 1 auto;
}
事實上幽崩,它是三個屬性的語法糖,按序分別是:
- flex-grow:用于拉伸的彈性系數(shù)(自然數(shù))寞钥,默認值是 0
- flex-shrink:與 flex-grow 相反的彈性系數(shù)慌申,應用于收縮狀態(tài),默認值是 1
- flex-basis:在上面兩個屬性修正前的基準大小
伸縮屬性有點難講理郑,為了方便計算蹄溉,我稍微調整了一下尺寸,順便把各項的尺寸顯示出來:
ul {
display: flex;
width: 24em;
}
li {
width: 4em;
}
flex-basis
flex-basis 的默認值是 auto您炉,但也可以是單位值(如 16px类缤、1em),或是百分比(相對于主軸而言)邻吭。上面我事先寫死了彈性項<li>
的寬度,這時候所有彈性項的默認 flex-basis 就等價于 4em 了宴霸。接著再為首元素單獨設置 flex-basis 為 8em:
li:first-child {
flex-basis: 8em;
}
我們比對一下設置前后的效果:
很明顯囱晴,首元素寬度變成了之前的兩倍。在未被伸縮屬性修正前瓢谢,flex-basis 可以直接當成寬度來用:若設置了 width 屬性畸写,默認值 auto 等于 width;若沒有設置 width氓扛,auto 又會根據(jù)內(nèi)容實際長度設置數(shù)值枯芬。當然,flex-basis 并沒有這么簡單采郎,我們接著往下看千所。
flex-grow
上圖中的容器<ul>
還有剩余空間,我們不妨接著試試 flex-grow——為首元素加入伸展系數(shù):
li:first-child {
flex-basis: 8em;
flex-grow: 1;
}
在上述代碼的基礎上蒜埋,試著給另一個彈性項 last-child 添加 flex-grow:
li:last-child {
flex-basis: 4em;
flex-grow: 1;
}
嗯淫痰,我們應該可以看出一些端倪了:
- flex-grow 會拉伸彈性項,并最終填滿父元素的所有剩余空間
- 若多個彈性項同時設置了 flex-grow整份,它們會按一定的比例分配父元素的剩余空間
這里所謂的剩余空間 =
容器總長度 -
所有彈性項的 flex-basis 之和待错。
修正后,彈性項的實際長度 =
自身 flex-basis +
剩余空間 ×
自身的 flex-grow /
∑
所有彈性項的 flex-grow。
公式出來了宵膨,我很難再說得更清楚了迁酸。
flex-shrink
再看看收縮場景——當 flex 容器空間小于所有彈性項 flex-basis 之和時,flexbox 又會按一定比例壓縮各彈性項瓜客;flex-shrink 就是應用于這個場景的收縮比例系數(shù)适瓦。
在收縮場景里,總壓縮長度(負空間) =
所有彈性項的 flex-basis 之和 -
容器總長度忆家。
修正后犹菇,彈性項實際長度 =
自身 flex-basis -
總壓縮寬度 ×
[
自身(
flex-grow ×
flex-shrink)
/
∑
所有彈性項的(
flex-grow ×
flex-shrink)
]
。
flex-wrap
上面這個收縮計算有點麻煩了芽卿,而且也沒太必要計算出實際寬度揭芍。在很多的應用場景里,我們會直接給容器加一個flex-wrap: wrap;
屬性:當 flex 容器過窄時卸例,彈性項直接換行即可称杨。
ul {
display: flex;
flex-wrap: wrap;
}
這種根據(jù)寬度自動調整布局的設計,被稱為響應式設計筷转,這就是后話了姑原。
小結
本文簡單介紹了 flexbox 最常用的幾個屬性,涵蓋了橫縱方向的排布呜舒、對齊锭汛、大小、次序調整等等方面袭蝗。但是本文只是入門介紹唤殴,flexbox 的語法還有不少,具體實踐更遠超本文描述到腥,還是希望大家能繼續(xù)研讀 W3C 文檔朵逝。
相關
文章同步發(fā)布于an-Onion 的 Github。碼字不易乡范,歡迎點贊配名。