彈性布局

簡介

  • 傳統(tǒng)布局基于盒子模型乌叶,通過 display float position 屬性進行布局,但是有些效果在盒模型下不好實現(xiàn)芹敌,比如垂直方向居中蠢沿。
  • 2009年 W3C 提出Flex布局,主流瀏覽器均可支持,其中IE瀏覽器在IE10之后開始支持

基礎語法

概念

Flex容器

  • 采用Flex布局的元素陆盘,稱為Flex容器(flex container)普筹。它的所有子元素自動成為容器成員,稱為Flex項目(flex item)
  • 給元素添加 display: flex 屬性使元素成為Flex容器隘马,即開啟了彈性布局太防,行內(nèi)元素也可用 display: inline-flex; 成為Flex容器
  • 開啟彈性布局后Flex容器的子元素的 float clear vertical-align 屬性將失效

主軸和副軸

  • 在Flex容器內(nèi)使用主軸和副軸概念;默認x軸為主軸酸员,y軸為副軸蜒车;可由Flex容器的 flex-direction 屬性修改
  • 主軸副軸中有起始位置的概念,默認的起始位置為x軸的左側y軸的上側
  • 在使用彈性布局時幔嗦,需要通過主軸和副軸確定編輯的方向酿愧,F(xiàn)lex容器內(nèi)的元素默認會處于類似 float 的狀態(tài),例html結構如下:
<div class="container">
    <div class="pink"></div>
    <div class="green"></div>
    <div class="blue"></div>
</div>

當主軸為x軸時:


主軸為x軸的效果圖
主軸為x軸的效果圖

當主軸為y軸時:


主軸為y軸的效果圖
主軸為y軸的效果圖

即主軸方向決定了容器內(nèi)元素的排列方向

容器屬性

flex-direction
flex-wrap
flex-flow
justify-content
align-items
align-content

1. flex-direction

設置主軸方向

.box {
  flex-direction: row | row-reverse | column | column-reverse;
}

row(默認值):主軸為x軸崭添,起始位置為左


row效果圖
row效果圖

row-reverse:主軸為x軸寓娩,起始位置為右


row-reverse效果圖
row-reverse效果圖

column:主軸為y軸,起始位置為上


column效果圖
column效果圖

column-reverse:主軸為y軸呼渣,起始位置為下


column-reverse效果圖
column-reverse效果圖

2. flex-wrap

設置可換行屬性棘伴,默認下容器內(nèi)子元素會按照主軸方向排一行,不會換行屁置,當總長度超過容器時子元素會被壓縮焊夸,通過 flex-wrap 屬性可設置換行模式

.box{
  flex-wrap: nowrap | wrap | wrap-reverse;
}

nowrap(默認值):不換行,width設置為22%的6個子元素被壓縮在一行


nowrap效果圖
nowrap效果圖

wrap:換行蓝角,第一行從最上側開始


wrap效果圖
wrap效果圖

wrap-reverse:換行阱穗,第一行從最底部開始


wrap-reverse效果圖
wrap-reverse效果圖

3. flex-flow

flex-direction 和 flex-wrap 的聯(lián)寫模式

.box {
  flex-flow: <flex-direction> || <flex-wrap>;
}

4. justify-content

設置主軸方向的對其方式

.box {
  justify-content: flex-start | flex-end | center | space-between | space-around;
}

flex-start(默認值):左對齊
flex-end:右對齊
center: 居中
space-between:兩端對齊,項目之間的間隔都相等使鹅。
space-around:每個項目兩側的間隔相等揪阶。所以,項目之間的間隔比項目與邊框的間隔大一倍患朱。


justify-content效果圖
justify-content效果圖

5. align-items

設置副軸方向對其方式

.box {
  align-items: flex-start | flex-end | center | baseline | stretch;
}
    ```
> flex-start:副軸的起點對齊
> flex-end:副軸的終點對齊
> center:副軸的中點對齊
> baseline: 項目的第一行文字的基線對齊
> stretch(默認值):如果項目未設置高度或設為auto鲁僚,將占滿整個容器的高度
![align-items效果圖](https://kabumie.github.io/images/md_img/align-items.png)
*這里只演示baseline效果,其它類似于justify-content的效果*

#### 6. align-content
在開啟換行模式后有換行時設置多行在副軸方向的對齊方式裁厅,如果主軸只有一行則該屬性無效
```css
.box {
  align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}

flex-start:與交叉軸的起點對齊
flex-end:與交叉軸的終點對齊
center:與交叉軸的中點對齊
space-between:與交叉軸兩端對齊冰沙,軸線之間的間隔平均分布
space-around:每根軸線兩側的間隔都相等。所以执虹,軸線之間的間隔比軸線與邊框的間隔大一倍
stretch(默認值):軸線占滿整個交叉軸


align-content效果圖
align-content效果圖

子元素屬性

order
flex-grow
flex-shrink
flex-basis
flex
align-self

1. order (常用)

定義子元素排列順序拓挥,值為無單位整數(shù),默認值為0袋励,值越小越靠近起始位置


order效果圖
order效果圖

2. flex-grow

  • 定義子元素放大比例侥啤,只有在容器主軸方向大小大于子元素總大小時才有效果当叭,即容器有空余,值為無單位非負數(shù)字愿棋,可設置浮點數(shù)科展,默認為0
  • 當值為0時代表子元素不放大,如果容器有剩余空間則空出
  • 如果有子元素 flex-grow 值不為0糠雨,則子元素會按照 flex-grow 值的比例放大并填充容器的剩余空間


    flex-grow效果圖
    flex-grow效果圖

具體計算方式:假設 A, B, C, D, E 的寬度分別是 100, 120, 130, 100, 100才睹,父級的寬度是660,父級寬減去子級的全部寬度甘邀,這樣剩余空間就是110琅攘。例子中B, C定義了flex-grow,分別是1松邪,2坞琴,那剩余空間分成3份,B1份逗抑,C2份剧辐,比例就是1:2,分配計算出來的值就是B :36.666666666666664, C:73.33333333333333邮府。這個時候剩余空間就被計算出來了荧关,相加后的結果就是B:156.66666666666666,C:203.33333333333331褂傀。
B的計算公式:120 + (110 / 3) * 1
C的計算公式: 130 + (110 / 3) * 2

3. flex-shrink

  • 定義子元素縮小比例忍啤,只有在容器主軸方向大小小于子元素總大小且不換行時才有效果,即容器空間不足仙辟,值為無單位非負數(shù)字同波,可設置浮點數(shù),默認為1
  • 為0表示子元素不縮小叠国,如果容器大小小于子元素總大小未檩,而所有子元素均不縮小,則子元素會超出容器范圍
  • 如果有子元素 flex-shrink 值不為0粟焊,則子元素會按照 flex-shrink 值的比例縮小在容器中


    flex-shrink效果圖
    flex-shrink效果圖

具體計算方式:假設 A, B, C 的寬度分別是155, 200, 50讹挎。父級寬度是300,計算超出的空間就是 -105吆玖,這樣超出的 105px 就要被 A, B, C 消化掉,比例是2:1:1马篮。
首先把每個項目的wdith值乘以 flex-shrink 值求積
A:(155 * 2) = 310
B:(200 * 1) = 200
C:(50 * 1) = 50沾乘。
然后再求和所有項目的乘積
(310 + 200 + 50) = 560
得到求占比之后還要乘以要騰出的空間
A:(310 / 560) * 105 = 58.125
B:(200 / 560) * 105 = 37.5
C:(50 / 560) * 105 = 9.375
得到每一項要騰出的空間
A:(155 - 58.125) = 96.875
B:(200 - 37.5) = 162.5
C:(50 - 9.375) = 40.625
這就是 A, B, C 按比例縮小后的大小

4. flex-basis

  • 本人對于 flex-basis 的意義并沒有完全理解,個人感覺有點像是設置了一個 max-width (主軸x軸時)浑测,很多人推薦在彈性布局中多使用 flex-basis 而不是直接設置 width height 屬性翅阵,這個屬性在下面的圣杯布局實例中有一次使用
  • 它的默認值為 auto歪玲,表示項目的本來大小

5. flex (常用)

  • flex-grow flex-shrink flex-basis 的聯(lián)寫,默認值為0 1 auto掷匠。后兩個屬性可選
  • 該屬性有兩個快捷值:auto (1 1 auto) 和 none (0 0 auto)
  • 通常直接用 flex 設置子元素比例大小滥崩,例如使用 flex: 1 直接設置大小比例,而不再單獨寫 flex-grow: 1

6. align-self (常用)

  • align-self 屬性允許單個項目有與其他項目不一樣的對齊方式讹语,可覆蓋 align-items 屬性钙皮。默認值為 auto,表示繼承父元素的 align-items 屬性顽决,如果沒有父元素短条,則等同于 stretch(默認值)
  • 除多出默認值 auto 外,屬性值同 align-items


    align-self效果圖
    align-self效果圖

應用實例

圣杯布局

  • 圣杯布局是指在頁面主體部分分為 left content right 3部分才菠,left和right固定大小茸时,content部分會自適應屏幕大小,后來國內(nèi)的淘寶團隊對其進行了改良赋访,改良后效果基本相同可都,一般叫做雙飛翼布局,使用搜索引擎搜索有很多相關介紹
  • 本身圣杯布局是使用 float margin padding 和定位等盒模型方法實現(xiàn)的蚓耽,關鍵點是使用負值的 margin 使left和right可以與設置為100%寬度的content浮動在同一行中渠牲,這里使用彈性布局則可以非常方便清晰的實現(xiàn)有自適應效果的圣杯布局

html結構:

<body>
    <div class="container">
        <div class="header"></div>
        <div class="content">
            <div class="left"></div>
            <div class="middle"></div>
            <div class="right"></div>
        </div>
        <div class="footer"></div>
    </div>
</body>

css樣式:

* {
    margin: 0;
    padding: 0;
}

html,
body {
    height: 100%;
}

.container {
    height: 100%;
    display: flex;
    flex-direction: column;
}

.header {
    flex: 1;
    background-color: gray;
}

.content {
    flex: 3;
    display: flex;
}

.content .left {
    background-color: red;
    flex: 0 0 200px;
}

.content .right {
    background-color: blue;
    flex: 0 0 200px;
}

.content .middle {
    background-color: whitesmoke;
    flex: 1;
}

.footer {
    flex: 1;
    background-color: gray;
}

@media (max-width: 768px) {
    .content {
        flex-direction: column;
    }
    .content .left,
    .content .right,
    .content .middle {
        flex: 1;
    }
}

效果圖:


圣杯布局效果圖
圣杯布局效果圖

這里做了屏幕大小判斷來適應移動端,在設置left和right寬度時使用的是 flex-basis田晚,而不是 width嘱兼,主要是因為在判斷屏幕寬度小于768px時需要層疊掉left和right原本的固定寬度,讓left和right可以自動填充整個屏寬贤徒,使用 flex-basis 可以在移動端樣式中直接設置 flex: 1 使 flex-basis 變?yōu)?auto芹壕,如果使用 width,在需要去掉固定寬度時則比較麻煩
使用彈性布局不僅在寬度上達到自適應接奈,在高度上也可以不受內(nèi)容限制踢涌,直接填充滿整個屏高

懸窗圖片展示板

  • 利用彈性布局可以用很少的代碼制作一個圖片懸窗的圖片展示板,彈性布局在處理寬高位置等方面非常方便序宦,實用的demo有很多睁壁,這里就只展示一個懸窗案例

html:

<div class="container">
    ![](../img/mm.png)
    <div class="content">
        <h3>Title</h3>
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laborum impedit ut officiis, nobis consequuntur fuga ipsam deleniti dolorem consequatur voluptatum saepe nam magni, aperiam voluptatibus officia. Sed facilis totam quis laborum laudantium cupiditate cumque, fuga illum asperiores alias libero quia, placeat debitis explicabo sint, rerum, at reiciendis inventore dolore officia!</p>
    </div>
</div>

css:

* {
    margin: 0;
    padding: 0;
}

.container {
    width: 400px;
    padding: 15px;
    margin: 50px auto;
    background-color: whitesmoke;
    border-radius: 10px;
    display: flex;
}

.container img {
    margin-right: 15px;
    width: 80px;
    height: 80px;
}

.content {
    flex: 1;
}

.container p {
    font: 400 12px "微軟雅黑";
}

效果圖:


懸窗圖片展示板效果圖
懸窗圖片展示板效果圖

結尾

作者很無恥的直接使用了阮一峰博客中的一些說明圖片(因為自己做的一部分圖片搞丟了,實在不想再做了T.T)互捌;這里先謝阮大神潘明,但是個人感覺阮一峰這篇博客對于一些屬性的說明不太詳細。
在 flex-grow 和 flex-shrink 的具體計算上直接使用了xiecg的文章中的例子秕噪,因為這個例子寫的實在是太棒了钳降。

會同步在 kabumie 的 github 空間上

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市腌巾,隨后出現(xiàn)的幾起案子遂填,更是在濱河造成了極大的恐慌铲觉,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吓坚,死亡現(xiàn)場離奇詭異撵幽,居然都是意外死亡,警方通過查閱死者的電腦和手機礁击,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進店門盐杂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人客税,你說我怎么就攤上這事况褪。” “怎么了更耻?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵测垛,是天一觀的道長。 經(jīng)常有香客問我秧均,道長食侮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任目胡,我火速辦了婚禮锯七,結果婚禮上,老公的妹妹穿的比我還像新娘誉己。我一直安慰自己眉尸,他們只是感情好,可當我...
    茶點故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布巨双。 她就那樣靜靜地躺著噪猾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪筑累。 梳的紋絲不亂的頭發(fā)上袱蜡,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天,我揣著相機與錄音慢宗,去河邊找鬼坪蚁。 笑死,一個胖子當著我的面吹牛镜沽,可吹牛的內(nèi)容都是我干的敏晤。 我是一名探鬼主播,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼缅茉,長吁一口氣:“原來是場噩夢啊……” “哼茵典!你這毒婦竟也來了?” 一聲冷哼從身側響起宾舅,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤统阿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后筹我,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體扶平,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年蔬蕊,在試婚紗的時候發(fā)現(xiàn)自己被綠了结澄。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡岸夯,死狀恐怖麻献,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情猜扮,我是刑警寧澤勉吻,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站旅赢,受9級特大地震影響齿桃,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜煮盼,卻給世界環(huán)境...
    茶點故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一短纵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧僵控,春花似錦香到、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至泛烙,卻和暖如春理卑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蔽氨。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工藐唠, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鹉究。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓宇立,卻偏偏與公主長得像,于是被迫代替她去往敵國和親自赔。 傳聞我的和親對象是個殘疾皇子妈嘹,可洞房花燭夜當晚...
    茶點故事閱讀 43,494評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 作者: 阮一峰日期: 2015年7月10日原文鏈接:http://www.ruanyifeng.com/blog/...
    Mike_Gu閱讀 975評論 0 6
  • 1.Flex布局是什么? Flex是Flexible Box的縮寫绍妨,就是靈活的彈性頁面布局润脸。 作用是為盒子模型提供...
    LiLi原上草閱讀 659評論 0 7
  • 移動開發(fā)基本知識點 一.使用rem作為單位 html { font-size: 100px; } @media(m...
    橫沖直撞666閱讀 3,460評論 0 6
  • H5移動端知識點總結 閱讀目錄 移動開發(fā)基本知識點 calc基本用法 box-sizing的理解及使用 理解dis...
    Mx勇閱讀 4,431評論 0 26
  • 日子柬脸,一篇一篇的翻 足跡,一個一個的連 說不定歲月 會是一首美麗詩箋 休憩是監(jiān)時停泊的點 青春是生命永久的畫卷 仰...
    江城妖怪閱讀 271評論 3 2