Flex Box 案例實踐

前言

基於前一篇文章關於 Flex 語法知識的梳理,這篇文章整理出一些常見的 Flex 佈局解決方案。實現方式仁者見仁,歡迎你們評論區指正交流。css

文中的案例主要包含如下幾個方面:html

  • 元素垂直居中佈局
  • 兩欄佈局
  • 三欄佈局

現代瀏覽器都支持 Flex Box 語法,能夠放心使用:前端

正文

在開始以前,仍是把這張圖貼上,着重理解 Flex Box 裏主軸(main axis)和交叉軸(cross axis)的概念。git

1.垂直居中

在 Flex 佈局方案出現以前,前端領域要實現元素的垂直居中一直都不是件容易的事。彼時,前端領域也涌現了一大批實現垂直居中的解決方案,這裏簡單回顧一下歷史:瀏覽器

  • 水平居中
    • 行內元素 直接設置 text-align:center; 就能夠了
    • 塊級元素 設置寬高後使用 margin:0 auto;
  • 垂直居中
    • 行內元素(分爲單行和多行的狀況)

    單行文本能夠直接在其父盒子上設置 heightline-height 兩個值相同便可;多行文本可能就須要配合使用 tabletable-cell 的方式,或者添加僞元素佔位填充的方式實現。網絡

    • 塊級元素(分爲固定寬高和寬高不定的狀況)

    能夠藉助絕對定位。固定寬高的狀況設置top:50%; margin-top:-width/2;寬高不定的設置top:50%;transform: translateY(-50%);ide

但這些方案如今均可以拋開,直接使用 Flex Box 便可。佈局

藉助 Flex 語法,實現元素的水平垂直居中,在Flex Box內即讓元素在主軸(main axis)和交叉軸(cross axis)上分別居中。語法梳理裏整理過,justify-content定義了元素在主軸方向上的排列方式,align-item 定義了元素在交叉軸上的排列方式,因此一個可行的解決方案即爲:post

.parent{
    display:flex;
    justify-content:center;
    align-items:center;
}
複製代碼

https://codepen.io/xutaogit/pen/jQwGKJ
上述解決方案是在父容器裏針對子元素作了配置,若是使用子元素自己,有一個 align-self 屬性會覆蓋容器的 align-items屬性,定義其在容器內部交叉軸上的排列方式。因此,另外一個可行的解決方案可爲:

.parent{
    display:flex;
    justify-content:center;
}
.child{align-self:center;}
複製代碼

獲得的效果和上面是同樣的,具體可參見:flex-center學習

2.兩欄佈局

兩欄佈局常見於一些博客或信息類網站,分爲固定寬+自適應不定寬+自適應兩種模式。這裏給出一個基本佈局結構:

<div class="box">
  <main>正文內容容</main>
  <aside>側邊欄內容</aside>
</div>
複製代碼
  • 固定寬+自適應:側邊欄固定寬度 200px,主內容區域自適應;主內容區域結構靠前是爲了優先加載顯示,側邊區域可經過設置order調整。
.box{display:flex}
.box aside{width:200px; order:-1;}      //設置 order 讓側邊欄前置顯示
.box main{flex-grow:1}                  //設置 flex-grow:1 會使該板塊填充容器空白空間
複製代碼

上述代碼之因此設置 flex-grow:1 能達到填充容器剩餘空間的緣由:側邊欄(aside)默認的flex-grow:0代表不放大,同時主內容區域設置爲 1 意味着該元素放大填充整個空白區域。具體效果如圖示,側邊欄內容再多也只是在元素塊內換行顯示:

  • 不定寬+自適應:理解爲兩欄均爲自適應寬度。能夠作一個假設,主內容區域寬度是側邊欄兩倍,一個可行的方案是:
.box{display:flex}
.box aside{flex:1; order:-1;}      //等價於 flex:1 1 0;
.box main{flex:2;}          //等價於 flex:2 2 0;             
複製代碼

語法篇關於flex屬性有說起它是flex-grow,flex-shrinkflex-basis三個屬性的合併寫法。默認值是:0 1 auto。即元素默認不放大,在容器空間不足時會縮小,內容換行顯示。
上述代碼即爲把容器空白區域等分紅三份,側邊欄佔據一份,主內容區域佔據兩份。 視覺效果和上圖相似。

3.三欄佈局

三欄佈局主要是指主體區域內容劃分爲三塊,左右兩邊固定寬度,中間內容寬度自適應佈局。

其實在業界有兩個熱門的解決方案:「聖盃佈局」和「雙飛翼佈局」。之因此有不一樣的叫法只是實現方式不一樣:

<!--聖盃佈局結構-->
<div class="content">
  <div class="center"></div>
  <div class="left"></div>
  <div class="right"></div>	
</div>
<!--雙飛翼佈局結構-->
<div class="content">
  <div class="center">
    <div class="middle"></div>
  </div>
  <div class="left"></div>
  <div class="right"></div>	
</div>
複製代碼

聖盃佈局原理:父盒子設置兩個側邊欄寬度須要的padding值,center盒子設置100%於父盒子的寬且子盒子均脫離文檔左浮動;特別要注意的是由於父盒子設置了padding值,子盒子須要設置relaive相對於文檔而後用負邊距進行定位。

雙飛翼佈局原理:center 盒子內部的middle元素設置供給左右兩邊側邊欄寬度的margin值,center盒子設置100%於父盒子的寬且子盒子均脫離文檔左浮動;而後側邊盒子經過負邊距抵消middle盒子內預設的margin值進行定位。

具體實現代碼網絡上有不少資源,這裏就不展開了。

迴歸到Flex Box,發現事情變得簡單不少。咱們針對聖盃結構進行佈局(由於雙飛翼佈局須要額外添加一個元素),一個可行的解決方案以下:

<!--左右側邊欄均自適應寬度-->
.content{display:flex; height:200px;}
.content .left{order:-1; background:#3498db;flex-grow:1;}
.content .right{background:#34495e;flex-grow:1;}
.content .center{flex-grow:2;background:#e74c3c}

<!--左右側邊欄固定寬度-->
.content{display:flex; height:200px;}
.content .left{order:-1; background:#3498db;width:200px;}
.content .right{background:#34495e;width:200px;}
.content .center{flex-grow:1;background:#e74c3c}
複製代碼

配合添加headerfooter,並且每每中間content內容須要自適應高度。基於聖盃佈局結構,能夠在外部父盒子設置flex-direction作總體垂直方向佈局。HTML結構和樣式代碼能夠是:

<div class="container">
  <div class="header">This is head</div>
  <div class="content">
      <div class="center">center</div>
      <div class="left">left</div>
      <div class="right">right</div>
  </div>
  <div class="footer">This is foot</div>
</div>
複製代碼
.container{display:flex; flex-direction:column;min-height:100vh;} //設置容器相對視窗 100% 高度
.header,.footer{flex:1;}
.header{background:#1abc9c;}
.content{flex:1;display:flex;}
.left{order:-1; background:#3498db;flex: 0 0 12em;}
.right{background:#34495e;flex: 0 0 10em;}
.center{background:#e74c3c;flex:1;}
.footer{background:#f1c40f;}
複製代碼

若是要在移動設備上顯示效果良好,主體區域內容要改變元素排列方式,可能須要添加media query作適配。

@media (max-width: 768px) {
  .content {
    flex-direction: column;
    flex: 1;
  }
  .left,
  .right,.center{
    flex: auto;
  }
}
複製代碼

https://codepen.io/xutaogit/pen/jQwGKJ

4.更多參考

以上。

文中案例參考連接

相關文章
相關標籤/搜索