內(nèi)容布局(三):Flexbox布局

前兩期講了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>
Before Flex

我們給容器 ul 加上 flex 屬性:

ul {
  display: flex;
}
After Flex

效果很明顯蓬抄,彈性項<li>全部變成了類似于 inline-block 的元素了——水平布局顯現(xiàn)出來了丰嘉。

Flex 方向:主軸和輔軸

Flexbox 可以針對某一區(qū)域控制其中元素的順序、大小嚷缭、分布以及對齊饮亏。事實上這個區(qū)域的元素可以沿著兩個方向排列:

  • 主軸(main axis):也就是橫軸,水平方向的排列
  • 輔軸(cross axis):也就是縱軸阅爽,垂直方向的排列

默認情況下子元素是依據(jù)主軸從左至右排布路幸,也就是flex-direction: row;,但還有:row-reverse付翁、 column劝赔、column-reverse等幾種排布。我們對比一下效果:

Flex direction

排布和我們的常識并不沖突胆敞,所以理解起來不難,

  • row:從左往右排列
  • row-reverse:從右往左排列
  • column:從上至下排列
  • column-reverse:從下至上排列

空間與對齊

上面提到了主軸和輔軸杂伟,flex 還可以對這兩個方向上的排布作出調整移层,這里需要記住兩個英語單詞:justifyalign;從語義來說赫粥,前者翻譯過來是(水平)排齊观话,后者是(垂直)排齊。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;
}
justify-content

默認為 flex-start避咆,表示左對齊舟肉;其他幾個也可顧名思義:右對齊、水平居中查库、居間留白路媚、空間環(huán)繞。

這里順便提一個與 flex 有點關系的常規(guī)的布局:如何讓首元素(HOME)左對齊樊销,剩余元素右對齊呢整慎?

margin auto

很簡單脏款,讓首元素的右 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;
}

再換一個布局,如何把上圖的首元素擠到右側强法,剩余元素依舊左對齊呢万俗?

Order

這里需要用到 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 itmes

align-items 屬性會對所有彈性項起效果银还,假如我只想調整末尾元素為居中對齊风宁,那該怎么辦呢?

align-self

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

很明顯囱晴,首元素寬度變成了之前的兩倍。在未被伸縮屬性修正前瓢谢,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;
}
flex-grow 1

在上述代碼的基礎上蒜埋,試著給另一個彈性項 last-child 添加 flex-grow:

li:last-child {
  flex-basis: 4em;
  flex-grow: 1;
}
flex-grow 2

嗯淫痰,我們應該可以看出一些端倪了:

  1. flex-grow 會拉伸彈性項,并最終填滿父元素的所有剩余空間
  2. 若多個彈性項同時設置了 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;
}
flex-wrap

這種根據(jù)寬度自動調整布局的設計,被稱為響應式設計筷转,這就是后話了姑原。

小結

本文簡單介紹了 flexbox 最常用的幾個屬性,涵蓋了橫縱方向的排布呜舒、對齊锭汛、大小、次序調整等等方面袭蝗。但是本文只是入門介紹唤殴,flexbox 的語法還有不少,具體實踐更遠超本文描述到腥,還是希望大家能繼續(xù)研讀 W3C 文檔朵逝。

相關

文章同步發(fā)布于an-Onion 的 Github。碼字不易乡范,歡迎點贊配名。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市晋辆,隨后出現(xiàn)的幾起案子渠脉,更是在濱河造成了極大的恐慌,老刑警劉巖瓶佳,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件连舍,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機索赏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門盼玄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人潜腻,你說我怎么就攤上這事埃儿。” “怎么了融涣?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵童番,是天一觀的道長。 經(jīng)常有香客問我威鹿,道長剃斧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任忽你,我火速辦了婚禮幼东,結果婚禮上,老公的妹妹穿的比我還像新娘科雳。我一直安慰自己根蟹,他們只是感情好,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布糟秘。 她就那樣靜靜地躺著简逮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪尿赚。 梳的紋絲不亂的頭發(fā)上散庶,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音凌净,去河邊找鬼悲龟。 笑死,一個胖子當著我的面吹牛泻蚊,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播丑婿,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼性雄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了羹奉?” 一聲冷哼從身側響起秒旋,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎诀拭,沒想到半個月后迁筛,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡耕挨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年细卧,在試婚紗的時候發(fā)現(xiàn)自己被綠了尉桩。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡贪庙,死狀恐怖蜘犁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情止邮,我是刑警寧澤这橙,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站导披,受9級特大地震影響屈扎,放射性物質發(fā)生泄漏。R本人自食惡果不足惜撩匕,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一鹰晨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧滑沧,春花似錦并村、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至令漂,卻和暖如春膝昆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背叠必。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工荚孵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人纬朝。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓收叶,卻偏偏與公主長得像,于是被迫代替她去往敵國和親共苛。 傳聞我的和親對象是個殘疾皇子判没,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353