css知識:flex 、bfc

Tra發表於2019-01-10

1.flex

       flex是css3新出來的佈局方式,是非常厲害常用的東西。

       詳情可查詢www.runoob.com/w3cnote/fle…

2.flex易錯點:

       2.1 flex-grow (擴大)

 <div class="main">          
     <div class="item1">11</div>          
     <div class="item2">22</div>          
     <div class="item3">33</div>  </div>
<style>            
.main{
    width:500px;
    height: 200px;
    display: flex;
}            
.item1{
     width:100px;                
     flex-grow: 1;                
     background: #f00;            
}            
.item2{
     width:100px;                
     background: #f60;           
 }            
.item3{               
    width:150px;                
    background: #ff0            
} 
</style>複製程式碼

  頁面ui為:

css知識:flex 、bfc

我們發現:

   item1元素佔據了除了item2和item3所有的位置。

為什麼會出現這樣的情況?

    那我們需要從"剩餘空間"這個詞說起。

    什麼是剩餘空間呢?具備flex環境的父容器,通常是有一條主軸和一條側軸,預設情況下主軸就是水平從左向右的,側軸是垂直從上到下的(類似書寫模式)。 剩餘空間就是父容器在主軸的方向上還有多少可用的空間。

     main是父容器,item1、item2、item3就是子元素,那麼

剩餘空間 = main元素寬度 - item1寬度 - item2寬度 - item3寬度 = 150px;(上述程式碼計算)

flex-grow其實就是參與剩餘空間的寬度,預設為0,說明元素預設都不會參與使用剩餘空間。

  1. 此例中,只有item1設定了flex-grow:1,也就是說剩餘空間1等分,全部給了item1,所以item1的實際寬度為:250px;
  2. 如果此例中,item2也設定了flex-grow:2,則說明剩餘空間已經3等分了,(item1和item2都設定了flex-grow),所以item1寬度 = 100 + 150 / 3 *1 = 150px; item2寬度 = 100 + 150 /3 * 2 = 200px;

    2.2 flex-basis

     這個屬性值的作用也就是width的替代品。 如果子容器設定了flex-basis或者width,那麼在分配空間之前,他們會先跟父容器預約這麼多的空間,然後剩下的才是歸入到剩餘空間,然後父容器再把剩餘空間分配給設定了flex-grow的容器。 如果同時設定flex-basis和width,那麼width屬性會被覆蓋,也就是說flex-basis的優先順序比width高。有一點需要注意,如果flex-basis和width其中有一個是auto,那麼另外一個非auto的屬性優先順序會更高。

   2.3 flex-shrink (縮小)

    注意一句話: 如果剩餘空間為正數,則說明子專案寬度之和小於 父元素專案寬度,也就不存在flex-shrink

    當子專案不存在換行,且子專案寬度之和 大於 父元素專案寬度,為了完整的顯示子元素,肯定會子專案進行縮小處理,那這個縮小規則是什麼呢?

     flex-shrink:預設為1,也就說如果子專案寬度之和 大於 父元素專案寬度,那麼所有的子元素都縮小相同的寬度。

 <div class="main">          
    <div class="item1">11</div>          
    <div class="item2">22</div>          
    <div class="item3">33</div>  
</div>

<style>            
.main{               
    width:500px;                
    height: 200px;               
    display: flex;            
}            
.item1{
    width:200px;                
    background: #f00;            
}            
.item2{                
     width:300px;                
     background: #f60;
     flex-shrink:2            
}            
.item3{                
    width:150px;                
    background: #ff0            
}
 </style>複製程式碼

     如果此例中,item2的flex-shrink:2,如果預設的壓縮率是x,則item2的壓縮率為2x

     則 500 = 200 *( 1-x) + 300 *( 1-2x) +150*(1-x) 可以計算出每個子元素各佔的寬度。

     如果flex-shrink:0;則說明這個容器在任何時候都不被壓縮

    也就是說:必須子元素合盒子寬度之和 大於 父元素,該屬性才會生效。

        2.3 flex

          flex屬性是flex-grow, flex-shrink 和 flex-basis的簡寫,預設值為0 1 auto。後兩個屬性可選。

總結:

1、剩餘空間=父容器空間-子容器1.flex-basis/width - 子容器2.flex-basis/width - …
2、如果父容器空間不夠,就走壓縮flex-shrink,否則走擴張flex-grow;
3、如果你不希望某個容器在任何時候都不被壓縮,那設定flex-shrink:0;
4、如果子容器的的flex-basis設定為0(width也可以,不過flex-basis更符合語義),那麼計算剩餘空間的時候將不會為子容器預留空間。
5、如果子容器的的flex-basis設定為auto(width也可以,不過flex-basis更符合語義),那麼計算剩餘空間的時候將會根據子容器內容的多少來預留空間。


2.BFC

2.1 知識準備(對以往知識的重新理解)

  • float到底因為什麼出現? 
        在pc時代所謂的浮動佈局,其實是已經被濫用了,甚至出了一系列的‘bug’,所謂的高度塌陷等等。其實float出現的原因:為了實現文字環繞效果!!!
  • float有那些特性?
          float存在的特性:

          1.   脫離文件流

          2.  塊狀該元素(一個內聯元素,設定了float,則相當於為該內聯元素設定了 display:block)

          3.  沒有margin重疊

          4.   包裹性

假設浮動元素父元素寬度 200px,浮動元素子元素是一個 128px 寬度的圖片, 則此時浮動元素寬度表現為“包裹”,就是裡面圖片的寬度 128px      
  • margin重疊問題?

          1.相鄰兄弟元素之間的margin重疊。(發生在塊級元素,且只在垂直方向,並非某些部落格寫的僅僅在bfc裡出現,記住這是公用的規則)

          2.父元素和第一個子元素和最後一個子元素的的重疊問題(也是在垂直方向)

  • float脫離文件流? 和absolute的區別?

          我記的當初學習float absolute這些css屬性時,說到他們會脫離文件流

// 看下面程式碼(來自css世界-張鑫旭)						<div class="father">

   <img src="me.jpg">

   <p class="animal">小貓1,小貓2,...</p>

</div>img { float: left; }它的效果是一個:文字環繞圖片的效果。
// 明明當初學的時候說到: float元素會脫離文件流,那應該p內容會從最左邊開始展示,那為什麼是在img右邊
呢?
// 其實還有一個概念:部分無視和完全無視
部分無視:(以上面程式碼為例) 雖然img元素脫離了文件流,p會無視img(我們發現,p的width確實是螢幕寬度),
但是p內部的文字會為img讓出位置(所有的float元素都有這個問題)
完全無視:比如absolute元素,其他元素會完全無視

*** 這因為“部分無視”的緣故,才能有“文字環繞效果” ***複製程式碼

  • 提醒

       bfc這個東西,不要看部落格!看書即可,(張鑫旭大佬的《css世界》)!

       因為部落格裡寫的繁雜且亂,對於我們一般開發而言,僅僅知道bfc能幹什麼?能解決我們什麼問題即可。

       因為css的世界真的是繁雜且浩瀚,需要大量的時間去閱讀相關的知識。

2.2 BFC核心

         概念:塊級格式化上下文(block formatting context) ,反正看了聽了也不懂。(可以簡單理解為生成了一個封閉的空間,內部元素出不來,外部元素進不去,具有很強的防禦性)

         核心理念:只要一個元素具有bfc,內部元素如何折騰都不會影響到外面的元素。

         思考:

               我們上面說的margin重疊問題,以及float元素導致父元素高度塌陷問題。

              是不是這樣理解,只要這個父元素具有了bfc,那float導致的高度塌陷問題也就解決          了?如果bfc不解決高度塌陷問題,則與它的“核心理念”就背道而馳了。不解決這個問            題,那必然會影響到外面元素的問題。

               至於margin重合問題,如果該元素有bfc,如果margin重合問題依然存在,那勢必           影響到外面元素。(聯想一下,父元素和第一個子元素和最後一個子元素的的重疊問               題,如果第一個子元素具有了bfc,而它的重合問題依然存在,必然與“核心理念”背道             而馳)

         解決的問題:

              1.margin重疊問題解決了

              2.高度塌陷問題解決了

        問題來了,如何使一個元素具有bfc?

        讓一個元素具有bfc的條件有哪些?

       
  • <html>根元素;

  • float 的值不為 none;

  • overflow 的值為 auto、scroll 或 hidden;

  • display 的值為 table-cell、table-caption 和 inline-block 中的任何一個;

  • position 的值不為 relative 和 static。 

   

       我們想想:我們之前寫的清除浮動,不就是父元素{overflow:hidden},其實它是生成了bfc,解決了高度塌陷問題。

        所以,我們以後遇到margin重疊問題,高度塌陷問題,第一時間想到bfc可以解決。  

        我們平時很常用的解決方式就是 overflow:hidden(因為它造成的影響相對較小)

        其實這裡,我們經常遇到的想不通的css問題都迎刃而解了,那其實bfc最最重要的特性是構建流式佈局。

        ** 面試常見問題: 左邊固定寬度,右邊自適應佈局

       最最常見的解決方案:

// 方法1
.left{
 float:left;
 width:200px;
 height:200px
}
.right{
  overflow:hidden
}
// 方法2
.left{
 float:left;
 width:200px;
 height:200px
}
.right{
  display: table-cell; width: 9999px}// 以上均支援ie8及其以上適配               複製程式碼

2.3 BFC的總結

       在我們水平還有限的情況下,只需要記住:當我們遇到margin重疊,高度塌陷問題,流式佈局問題,第一印象想到bfc。想到生成bfc的條件,以及最常用的解決方法即可。