CSS彈性盒佈局

Flexible Box Layout

1、Flex佈局概述

Flex,即Flexible Box, 意爲"彈性盒",用於爲盒裝模型提供最大的靈活性。css

任何一個容器均可以指定爲Flex佈局。
塊級元素可設置display:flex; 行內元素可設置display:inline-flex。
webkit內核的瀏覽器(Chrome,Safari),需加上-webkit前綴,即-webkit-flex,-webkit-inline-flex。
設爲flex佈局後,元素的float、clear、vertial-align屬性將失效。html

1. Flex容器和Flex項目:

  • Flex容器(flex container): 採用Flex佈局的元素。
  • Flex項目(flex item): Flex容器的全部子元素。

2. 容器的兩根軸及相關位置、尺寸

  • 主軸(main axis):容器的水平軸
  • 交叉軸(cross axis): 容器的垂直軸
  • main start:主軸的開始位置,即與邊框的交叉點
  • main end:主軸的結束位置
  • cross start: 交叉軸的開始位置
  • cross end:交叉軸的結束位置
  • main size: 單個項目佔據的主軸空間尺寸(項目默認沿主軸排列)
  • cross size: 單個項目佔據的交叉軸空間尺寸

以下圖:web

2、Flex容器屬性

Flex容器有6個屬性:瀏覽器

  • flex-direction
  • flex-wrap
  • flex-flow (flex-derection和flex-wrap的簡寫)
  • justify-content
  • align-items
  • align-content

1. flex-direction

決定主軸的方向。佈局

.container {
    flex-direction: row | row-reverse | column | column-reverse
}

flex-direction屬性可能值:flex

  • row(default):主軸爲水平方向,起點在左端。
  • row-reverse:主軸爲水平方向,起點在右端。
  • column:主軸爲垂直方向,起點在上端。
  • column-reverse:主軸爲垂直方向,起點在下端。

2. flex-wrap

規定項目在一條軸線上排不下的時候,如何換行。spa

.container {
    flex-wrap: nowrap | wrap | wrap-reverse
}

flex-wrap屬性可能值:.net

  • nowrap(default):不換行
  • wrap:換行,第一行在上方
  • wrap-reverse:換行,第一行在下方

3. flex-flow (簡寫屬性)

是flex-direction和flex-wrap的簡寫形式。默認爲flex-flow: row nowrapcode

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

4. justify-content

定義項目在主軸方向上的對齊方式。htm

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

其具體對齊方式與主軸的方向有關,默認主軸方向是row,在此狀況下:

  • flex-start(default):左對齊
  • flex-end:右對齊
  • center: 居中
  • space-between: 兩端對齊,項目之間的間隔都相等
  • space-around: 每一個項目兩側的間隔相等,那麼項目之間的間隔是項目與邊框的間隔的兩倍

以下圖所示:

5. align-items

定義項目在交叉軸方向上的對齊方式(項目可能仍是沿主軸排列的)。

.container {
    align-items: flex-start | flex-end | center | baseline | stretch;
}

其具體的對齊方式與交叉軸的方向有關。這裏假設交叉軸是垂直方向。

  • stretch(default):若是項目未設置高度或高度爲auto,則將佔滿整個容器的高度
  • flex-start: 上對齊
  • flex-end: 下對齊
  • center: 垂直居中對齊
  • baseline: 項目的第一行文字的baseline(基線)對齊

以下圖所示:

6. align-content

定義多行主軸的對齊方式。若是項目只有一行主軸,則該屬性不起做用

.container {
    align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}

align-content屬性可能值:

  • stretch(default):軸線佔滿整個交叉軸。
  • flex-start:與交叉軸的起點對齊。
  • flex-end:與交叉軸的終點對齊。
  • center:與交叉軸的中點對齊。
  • space-between:與交叉軸兩端對齊,軸線之間的間隔平均分佈。
  • space-around:每根軸線兩側的間隔都相等。因此,軸線之間的間隔比軸線與邊框的間隔大一倍。

以下圖所示:

3、Flex項目屬性

flex項目也有6個屬性:

  • order
  • flex-grow
  • flex-shrink
  • flex-basis
  • flex (flex-grow、flex-shrink、flex-basis的簡寫)
  • align-self

1. order

定義項目的排列順序索引。

.item {
  order: 0|1|2|-1|999
}

order屬性可能值:全部interger

  • 默認爲0。
  • 能夠爲負。
  • 數值越小排列越靠前。
  • order屬性值相等的項目按照書寫順序排列。

以下圖所示:

2. flex-grow

定義若是存在剩餘空間的時候,項目的放大倍數。

.item { 
  flex-grow: 0|1|2|1.2
}

可能值:number,不能爲負。

  • 默認爲0。即即便存在剩餘空間,也不放大。
  • 若是全部項目的flex-grow都爲1,則它們將等分剩餘空間。
  • 若是一個項目的flex-grow爲2,其餘項目的flex-grow都爲1,則前者佔據的剩餘空間是後者的2倍

以下圖所示:

3. flex-shrink

定義若是全部項目的默認寬度之和大於容器的時候,項目的縮小比例。

.item {
    flex-shrink: 0|1|2|1.2
}

可能值: number,不能爲負。

  • 默認爲1。即若是空間不足,項目將縮小。
  • 若是全部項目的flex-shrink都爲1,則當空間不足時它們都將等比例縮小。
  • 若是一個項目的flex-shrink爲0,其餘項目的flex-shrink都爲1,則當空間不足時前者不縮小,後者縮小。

4. flex-basis

定義了項目在主軸方向的初始大小。若是不使用 box-sizing 來改變盒模型的話,那麼這個屬性就決定了 flex 元素的內容盒(content-box)的寬或者高(取決於主軸的方向)的尺寸大小。瀏覽器會根據這個屬性,計算主軸是否有多餘空間。

.item {
    flex-basis: auto|10em|3px|content|fill|max-content|min-content|fit-content;
}

flex-basis屬性可能值:length

  • auto(default):項目的原本大小
  • 能夠設爲和width或height屬性同樣的值,這樣項目將佔據固定空間。

5. flex (簡寫屬性)

是flex-grow、flex-shrink、flex-basis的簡寫形式。後兩個屬性可選。

可能值:

  • 默認爲0 1 auto。
  • auto: 1 1 auto
  • none: 0 0 auto

6. align-self

定義單個項目在交叉軸的對齊方式,它能夠覆蓋容器元素的align-items屬性。即該屬性容許單個項目有與其餘項目不同的交叉軸對齊方式。

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

可能值:

  • auto(default): 即與父元素的align-items一致。若是沒有父元素,則等同於stretch
  • flex-start| flex-end | center | baseline | stretch: 與align-items屬性徹底一致。

4、個人實踐

.toprecommend-part {
  box-sizing: content-box;
    background-color: #f2e5da;
    padding-top: 8px;
    min-height: 96px;
    @media only screen and (min-width: 980px){ 
        margin-top:-30px;
    }
    //height: 300px;
    margin-bottom: 30px;
}
.toprecommend-container {
    //position: relative;
    margin:0 auto;
    min-width: 240px;
    max-width: 1220px;
    padding: 0 20px;    
}
.toprecommend-title {
    //font-family: MetricWeb, sans-serif;
    font-size: 16px;
    line-height: 20px;
    margin-top: 0px;
    margin-bottom: 8px;
    padding-bottom: 8px;
    border-bottom: 1px solid #ccc1b7;
    font-weight: 600;
  //position: relative;
  a {
    color: #000;
    text-decoration: none;
    cursor: pointer;
  }
}
.toprecommend-list { //flex容器
    margin-top: 8px;
    margin-bottom: 0px;
    display: flex;//容器中的直系子元素都會變爲 flex 元素
  flex-wrap: wrap;
  /* 指定flex元素單行顯示仍是多行顯示:
   * nowrap: flex元素被擺放到一行
   * wrap: flex元素被打斷到多個行中
   * wrap-reverse: 和 wrap 的行爲同樣,可是 cross-start 和 cross-end 互換。
  */
    zoom:1;
    clear: both;
    @media (min-width: 740px) {
      margin-left: -20px;
    }
}
.toprecommend-item {//flex元素
    display: block;
  flex-basis: 25%;//指定了 flex 元素在主軸方向上的初始大小。若是不使用 box-sizing 來改變盒模型的話,那麼這個屬性就決定了 flex 元素的內容盒(content-box)的寬或者高(取決於主軸的方向)的尺寸大小。
  /*
    min-width: 25%;
    max-width: 25%;
  width: 25%;
  */
  padding-left: 20px;
  flex: 1 1 0%;
  /** 規定了彈flex元素如何伸長或縮短以適應flex容器中的可用空間。它是一個簡寫屬性,能夠同時設置flex-grow, flex-shrink與flex-basis。
  * flex-grow:拉伸因子,爲正整數
  * flex-shrink:收縮因子,flex 元素僅在默認寬度之和大於容器的時候纔會發生收縮

  */
  -webkit-flex: 1 1 0%;
  -ms-flex: 1 1 0%;
  

  @media (min-width: 740px) {
    padding-left: 20px;
    -webkit-flex: 0 0 0%; //0,0纔是不拉伸也不收縮
    flex-basis: 33.33333%;
  }
  @media (min-width: 980px) {// M
    flex-basis: 25%;
  }
}
.toprecommend-item-content {
    padding-bottom: 12px;
    display: flex;
    font-size: 14px;
    line-height: 16px;
    position: relative;
    width: 100%;
    text-rendering: optimizeLegibility;
    -webkit-font-smoothing: antialiased;
}
.toprecommend-item-title {
    -webkit-box-flex: 1;
    -webkit-flex: 1 0 0%;
    -ms-flex: 1 0 0%;
    flex: 1 0 0%;
    -webkit-box-ordinal-group: 3;
    -webkit-order: 2;
    -ms-flex-order: 2;
    order: 2;
    a {
    font-size: 14px;
    line-height: 16px;
    font-weight: 600;
    color: #000;
    &:visited {
      color: #66605c;
    }
    &:hover {
      color: #736c67;
    }
  }
}
.toprecommend-item-image {
   @media (max-width:1220px) {
    display: none;
  }
  width: 30%;
  -webkit-flex-shrink: 0;
  -ms-flex-negative: 0;
  flex-shrink: 0;
  padding: 4px 10px 0 0;
  img {
   display: block;
  }
  a {
    display: block;
    text-decoration: none;
    cursor: pointer;
  }
}
<div class="toprecommend-part">
    <div class="toprecommend-container">
        <h2 class="toprecommend-title">
            <a class="list-link" href="#">爲您推薦</a>
        </h2>
        <ul id="story-recommend-top" class="toprecommend-list">
          <li class="toprecommend-item">
            <div class="toprecommend-item-content">
                <div class="toprecommend-item-title">
                    <a href="/story/001063419?tcode=smartrecommend&amp;ulu-rcmd=undefined">
                        並不風光的中產階級
                    </a>
                </div>
                <div class="toprecommend-item-image">
                    <a href="/story/001063419?tcode=smartrecommend&amp;ulu-rcmd=undefined">
                        <img src="http://i.ftimg.net/picture/6/000054146_piclink.jpg">
                    </a>
                </div>
            </div>
        </li>
        <li class="toprecommend-item">
            <div class="toprecommend-item-content">
                <div class="toprecommend-item-title">
                    <a href="/story/001062572?tcode=smartrecommend&amp;ulu-rcmd=undefined">
                        新加坡吸引綠地FDI全球居首
                    </a>
                </div>
                <div class="toprecommend-item-image">
                    <a href="/story/001062572?tcode=smartrecommend&amp;ulu-rcmd=undefined">
                        <img src="http://i.ftimg.net/picture/4/000037714_piclink_272_153.jpg">
                    </a>
                </div>
            </div>
        </li>
        <li class="toprecommend-item">
            <div class="toprecommend-item-content">
                <div class="toprecommend-item-title">
                    <a href="/story/001063662?tcode=smartrecommend&amp;ulu-rcmd=undefined">
                        中國經濟疲弱對全球影響甚微
                    </a>
                </div>
                <div class="toprecommend-item-image">
                    <a href="/story/001063662?tcode=smartrecommend&amp;ulu-rcmd=undefined">
                        <img src="http://i.ftimg.net/picture/1/000054411_piclink.jpg">
                    </a>
                </div>
            </div>
        </li>
        <li class="toprecommend-item">
            <div class="toprecommend-item-content">
                <div class="toprecommend-item-title">
                    <a href="/story/001060926?tcode=smartrecommend&amp;ulu-rcmd=undefined">
                        「奇怪」的中印增加數據
                    </a>
                </div>
                <div class="toprecommend-item-image">
                    <a href="/story/001060926?tcode=smartrecommend&amp;ulu-rcmd=undefined">
                        <img src="http://i.ftimg.net/picture/5/000050235_piclink.jpg">
                    </a>
                </div>
            </div>
        </li>
      </ul>
    </div>
</div>

參考資料

https://developer.mozilla.org/en-US/docs/Glossary/Flex

https://developer.mozilla.org/en-US/docs/Web/CSS/display

Flex佈局教程:語法篇

Flex佈局教程:實例篇(內含骰子佈局、網格佈局、聖盃佈局)

相關文章
相關標籤/搜索