flexbox彈性盒子唉匾,真正意義上的布局樣式

前段時間接手了一個基于cef1的項目孕讳,由于其特別限定的場景,在查詢了對html5的支持后巍膘,整站都采用了flexbox布局厂财,也從頭熟悉了一遍該布局的使用方法。故分享出來峡懈,供參考璃饱。

背景

Flexbox Layout,俗稱Flexible box模型肪康,由W3C于2009年開始起草的css3布局樣式帜平。它旨在提供一種更加有效的布局方式,控制父容器中子元素的布局梅鹦,排列以及分布裆甩,甚至在它們的尺寸未知或動態(tài)變化的情況下,都能夠做到正確的展現(彈性盒子中的flex也由此而得名)齐唆。

彈性盒子的核心概念是父容器擁有能夠改變其子元素的的寬度/高度和排列順序嗤栓,使得子元素能夠以最佳的尺寸填充整個父容器的可用空間。簡單來說箍邮,一個彈性盒子能夠充分擴展它的子元素尺寸使其填滿自身的可用空間茉帅,或者收縮子元素來防止溢出。

最重要的一點是锭弊,相對于傳統(tǒng)的塊布局block以及行布局inline來說堪澎,彈性盒子模型是方向不可知的(direction-agnostic)。盡管塊布局以及行布局能夠很好的滿足頁面布局味滞,但是它們缺乏彈性樱蛤,不能很好地支持大型或者是復雜的應用(特別在屏幕進行橫豎屏切換,改變視圖尺寸剑鞍,延伸昨凡,收縮等等復雜情景下)。

注意:彈性盒子布局適合作用在一個應用的組件和小范圍的布局,例如,一個歌曲列表呻疹,一個導航條供屉,等等瑟押。相對的泽论,Grid layout韩脏,即柵格布局則傾向于進行大規(guī)模的界面布局脉让,例如晌杰,整體界面的分欄布局跷睦,左右結構,上下結構乎莉,等等送讲。

基本原理

由于彈性盒子是一整套模型而不是單獨的一個css屬性,它包含了一個屬性集合惋啃,其中的一些屬性作用于父容器(flex container)哼鬓,另一些則作用于子元素(flex items),所以特別需要區(qū)分這些屬性的作用對象边灭。

如果說常規(guī)布局是建立在塊級和行級方向(block and inline flow directions)上的异希,那么彈性盒子布局則是建立彈性流方向(flex-flow directions)上的。

彈性盒子模型

如上圖所示绒瘦,假設主軸是橫向的称簿,那么子元素將會沿著主軸從左至右依次排列,或者是沿著與主軸垂直的交叉軸由上至下依次排列惰帽。下面我們一一進行剖析:

main axis(主軸)

父容器的主軸是子元素排列的基本軸憨降,但這并不意味著基本軸必須是橫向的,這取決于父容器的flex-direction屬性(后邊會介紹到)该酗。例如授药,如果子元素是豎向排列的,那么主軸則是豎向的那條軸呜魄。

main-start | main-end

子元素會沿著main-start從左至右排列悔叽,直到main-end。值得注意的是爵嗅,默認情況下娇澎,子元素只會排列在一排上,就算已經到達了父容器的右邊緣睹晒,也不會進行換行趟庄,除非設置了flex-wrap屬性(后邊會介紹到)。

main size

在父容器中主軸上的子元素的主尺寸(不論寬度或者高度)之和册招,構成了彈性盒子的主尺寸岔激。例如,如果子元素是橫向排列的是掰,則寬度則是主尺寸,相對的辱匿,如果子元素是豎向排列的键痛,則高度則是主尺寸炫彩。

cross axis

垂直于主軸的軸,稱之為交叉軸絮短。顯然江兢,交叉軸的方向取決于主軸的方向。

cross-start | cross-end

當父容器中的子元素換行時丁频,子元素的行排列的方向則是沿著交叉軸進行的杉允,從cross-start開始,直到cross-end席里。

cross size

和main size同理叔磷,只是方向與之垂直。


下面進行彈性盒子屬性詳解奖磁,分為兩類改基,分別是父容器屬性和子元素屬性。


父容器屬性(flex-container)

父容器

display

用于定義彈性盒子的顯示方式咖为。

.flex-container {
  display: flex; // 實際相當于block-flex秕狰,塊級容器,寬度同其外層容器
  display: inline-flex; // 顧名思義躁染,行級容器鸣哀,寬度取決于其子元素
}

flex-direction

用于定義主軸方向,同時也決定了子元素的排列方向吞彤。

flex-direction
.flex-container {
  flex-direction: row; // 子元素由左至右排列(默認值)
  flex-direction: row-reverse; // 子元素由右向左排列
  flex-direction: column; // 子元素由上至下排列
  flex-direction: column-reverse; // 子元素由下至上排列
}

flex-wrap

默認情況下我衬,所有的子元素都會嘗試沿著主軸在排列在同一行(列)上,這個屬性用來對子元素進行換行排列备畦,即當子元素排列到main-end的時候低飒,會自動進行換行。

flex-wrap
.flex-container {
  flex-wrap: nowrap; // 子元素都在排列在同一行(默認值)
  flex-wrap: wrap; // 子元素將沿著交叉軸正向排列在多行中
  flex-wrap: wrap-reverse; // 子元素將沿著交叉軸反向排列在多行中
}

flex-flow

flex-direction和flex-wrap的屬性縮寫懂盐。

.flex-container {
  flex-flow: <'flex-direction'> || <'flex-wrap'>;
  flex-flow: row nowrap; // 橫向排列 不換行(默認值)
}

justify-content

定義子元素在主軸上的對其方式褥赊。主要用在當所有的子元素在同一行,且為非彈性元素時莉恼,分配剩下的額外空間拌喉;或者是彈性元素但是并沒有撐滿整個父容器的主尺寸。該屬性也能夠對溢出的子元素起到一定的控制作用俐银,例如尿背,當子元素溢出時,對其進行居中捶惜,則左右溢出的寬度將是相等的田藐。

justify-content
.flex-container {
  justify-content: flex-start; // 子元素向主軸起點看齊排列(默認值)
  justify-content: flex-end; // 子元素向主軸終點看齊排列
  justify-content: center; // 子元素居中排列
  justify-content: space-between; // 子元素以相同的間距從主軸的起點和終點開始平均排列
  justify-content: space-around; // 子元素以相同的邊距延主軸平均排列
}

小貼士:justify-centent: center;還可以配合align-self: center;進行內容的居中垂直布局

align-items

用于定義排列在同一主軸的子元素在交叉軸方向上的排列方式(可以想象成是justify-content屬性的交叉軸版)。

align-items
.flex-container {
  align-items: flex-start; // 子元素向交叉軸起點看齊排列
  align-items: flex-end; // 子元素向交叉軸終點看齊排列
  align-items: flex-center; // 子元素在交叉軸居中排列
  align-items: flex-stretch; // 子元素沿交叉軸拉伸排列(撐滿整個交叉軸的長度)(默認值)
  align-items: flex-baseline; // 子元素在交叉軸上沿其文本的基線對其排列
}

align-content

用于定義父容器中的多行/列在交叉軸上的排列方式(有點類似于多個子元素在主軸上的justify-content排列)汽久。

align-content
.flex-container {
  align-content: flex-start; // 多排子元素從交叉軸起點進行排列
  align-content: flex-end; // 多排子元素從交叉軸終點進行排列
  align-content: center; // 多排子元素在交叉軸居中排列
  align-content: stretch; // 多排子元素沿交叉軸拉伸排列(撐滿整個交叉軸的長度)(默認值)
  align-content: space-between; // 多排子元素以相同的間距從交叉軸的起點和終點開始平均排列
  align-around: // 多排子元素以相同的邊距延交叉軸平均排列
}

小貼士:當只有一排子元素時鹤竭,align-content屬性并沒有什么卵用。


子元素屬性(flex-items)

子元素

order

默認情況下景醇,子元素按照它們在源碼中出現的位置進行排列臀稚。幸運的是,通過order屬性三痰,則能夠控制子元素在父容器中的排列順序吧寺,這大大增加了布局的靈活性。

order

上圖中的數字散劫,代表了元素的順序值(整型稚机,且接受負值),且order: 0;無order屬性等效舷丹。

.flex-item: {
  order: <integer>;
  order: -1|1|2...n;
}

flex-grow

用于定義子元素能否伸展的能力抒钱。它接受一個數字來作為比例值,這使得子元素能夠自動檢測父容器中的可用空間颜凯,并將其進行填充谋币。

如果所有的子元素都有flex-grow: 1,那么所有子元素都將均分主軸的長度症概;如果其中有一個子元素有flex-grow: 2蕾额,那么這個子元素將占據其他flex-grow: 1的子元素占據主軸長度的兩倍(至少會盡量這樣做)。

flex-grow
.flex-item {
  flex-grow: <number>; // 非負自然數(包括0)
  flex-grow: 0; // 默認值
  flex-grow: 1|2...n;
}

小貼士1:如果子元素的內容超過了其flex-grow所分配的空間彼城,則會繼續(xù)伸展诅蝶,直到滿足子元素內容的長度。
小貼士2:如果父容器設置了flex-wrap: wrap;募壕,那么擠到第二排的子元素將按照第二排的主軸長度進行flex-grow比例的重新計算调炬。

flex-shrink

用于定義了子元素收縮的能力。

flex-shrink

上圖中舱馅,父容器寬度固定為500px缰泡,子元素設置了flex-basis: 120px; flex-shrink: 1;,此時代嗤,D和E設置了flex-shrink: 2棘钞。這樣,D和E將會收縮自身的長度干毅,盡量將所有的元素都排在父容器的主軸上且盡量不超過父容器的寬度500px宜猜。

flex-basis

用于在空間被分配前,定義子元素的默認長度硝逢。這個值可以是長度(百分比姨拥,rem等等)或者是關鍵字(如auto等)绅喉。

.flex-item {
  flex-basis: <length> | auto(默認值); 
}

需要注意的是,如果flex-basis: 0;垫毙,那么子元素內容旁邊的額外空間是不計算在flex-basis內的霹疫。如果設置為auto拱绑,那么額外的空間將基于子元素的flex-grow進行計算综芥。計算方式如下圖所示。

https://www.w3.org/TR/css-flexbox-1/images/rel-vs-abs-flex.svg

在上圖中猎拨,子元素的flex-grow1:1:2膀藐。當flex-basis: 0;時,子元素內容旁邊的額外空間不計數红省;flex-basis: auto;時额各,子元素內容旁邊的額外空間計數,且比例由其flex-grow決定吧恃,這里則是1:1:2虾啦。故而,雖然我們的flex-grow設置為了1:1:2痕寓,但是由于flex-basis的影響傲醉,產生了不同的顯示結果。

flex

flex-grow呻率,flex-shrink硬毕,flex-basis的屬性縮寫。其中礼仗,flex-shrink和flex-basis是可選項吐咳,如不填寫這兩個值,則默認值為flex-shrink: 1元践,flex-basis: 0%韭脊。如果整個flex屬性都不填寫,則整個屬性默認值為0 1 auto单旁。

.flex-item {
  flex: none | [ <'flex-grow'> <'flex-shrink'> || <'flex-basis'> ];
  flex: 0 1 auto; // 不伸展 收縮度為1 自動基礎長度
}

小貼士:強烈建議采用屬性縮寫的方式來定義子元素的彈性屬性沪羔,因為它能幫助我們自動地設置許多默認值。

align-self

允許單個子元素覆寫父容器的align-items屬性(故兩者擁有同樣的屬性值)慎恒。

align-self
.flex-item {
  align-seft: auto | flex-start | flex-end | center | baseline | stretch;
}

小貼士:float任内,clearvertical-align這些屬性對一個彈性盒子布局的元素將失去作用融柬。

歡迎交流死嗦,完。

TODO:Grid layout 柵格布局


參考文獻

https://css-tricks.com/snippets/css/a-guide-to-flexbox/
https://www.w3.org/TR/css-flexbox-1/

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末粒氧,一起剝皮案震驚了整個濱河市越除,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖摘盆,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件翼雀,死亡現場離奇詭異,居然都是意外死亡孩擂,警方通過查閱死者的電腦和手機狼渊,發(fā)現死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來类垦,“玉大人狈邑,你說我怎么就攤上這事≡槿希” “怎么了米苹?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長砰琢。 經常有香客問我蘸嘶,道長,這世上最難降的妖魔是什么陪汽? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任训唱,我火速辦了婚禮,結果婚禮上掩缓,老公的妹妹穿的比我還像新娘雪情。我一直安慰自己,他們只是感情好你辣,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布巡通。 她就那樣靜靜地躺著,像睡著了一般舍哄。 火紅的嫁衣襯著肌膚如雪宴凉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天表悬,我揣著相機與錄音弥锄,去河邊找鬼。 笑死蟆沫,一個胖子當著我的面吹牛籽暇,可吹牛的內容都是我干的。 我是一名探鬼主播饭庞,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼戒悠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了舟山?” 一聲冷哼從身側響起绸狐,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤卤恳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后寒矿,有當地人在樹林里發(fā)現了一具尸體突琳,經...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年符相,在試婚紗的時候發(fā)現自己被綠了拆融。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡主巍,死狀恐怖冠息,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情孕索,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布躏碳,位于F島的核電站搞旭,受9級特大地震影響,放射性物質發(fā)生泄漏菇绵。R本人自食惡果不足惜肄渗,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望咬最。 院中可真熱鬧翎嫡,春花似錦、人聲如沸永乌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽翅雏。三九已至圈驼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間望几,已是汗流浹背绩脆。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留橄抹,地道東北人靴迫。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像楼誓,于是被迫代替她去往敵國和親玉锌。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內容

  • H5移動端知識點總結 閱讀目錄 移動開發(fā)基本知識點 calc基本用法 box-sizing的理解及使用 理解dis...
    Mx勇閱讀 4,395評論 0 26
  • CSS 3中彈性盒布局的最新版概述 在CSS 3中慌随,CSS Flexible Box模塊為一個非常重要的模塊芬沉,該模...
    吾名無雙閱讀 1,221評論 0 5
  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案躺同? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標簽默認的外補...
    _Yfling閱讀 13,728評論 1 92
  • 移動開發(fā)基本知識點 一.使用rem作為單位 html { font-size: 100px; } @media(m...
    橫沖直撞666閱讀 3,453評論 0 6
  • 事實上它是一種新類型的盒子模型,也有書上稱作彈性伸縮盒布局丸逸。比較新的布局方式:旨在提供一個更加有效的方式來布置蹋艺,對...
    zh_yang閱讀 11,320評論 3 14