浮動、定位、BFC、外邊距合并

一、浮動元素有什么特征?對父容器、其他浮動元素、普通元素、文字分別有什么影響?

float指定一個元素沿著其容器左側或者右側放置,允許行內元素和文本圍繞它。使用后,該元素會從正常流動中移除,雖然還會保持一定流動性(兩個浮動碰到一起)。由于元素浮動后,脫離了普通文檔流,并且一直左移或者右移直到碰到父元素邊框或者另一個浮動元素才停止(一行占滿會自動換行),所以,浮動元素會覆蓋在普通文檔流元素之上(如果有的話)。而且,父元素也會塌陷,不再包裹得住浮動元素。

參考:float | MDN

二、清除浮動指什么? 如何清除浮動? 兩種以上方法

清除浮動,可以通過clear: left | right | both實現。或者對目標元素轉換成不同的 BFC ,BFC后面再說,這里主要通過clear: both解決。直接上代碼

1. 直接使用clear: both清除浮動,主要用于兄弟元素情況。

<style>
  .div1 {
    float: left;
    background-color: #333;
  }
  
  .div1,.div2 {
    width: 150px;
    height: 150px;
  }
    
  .div2 {
    background-color: #f03;
    clear: both;
  }
</style>
  <div class="div1"></div>
  <div class="div2"></div>

在線演示

2. 通過加一個額外標簽,阻止父元素塌陷。

<style>
    .div1 {
        float: left;
        background-color: #333;
      }
  
    .div1,.div2 {
      width: 150px;
      height: 150px;
    }
    
    .div2 {
      background-color: #f03;
    }
  
    .clear {
      clear: both;
    }
</style>
<div class="div0">
  <div class="div1"></div>
  <div class="clear"></div>
</div>
<div class="div2"></div>

在線演示

3. 通過為父元素添加overflow:hidden來阻止父元素塌陷。

<style>
  .div0 {
    overflow: hidden;
  }
  
  .div1 {
    float: left;
    background-color: #333;
  }
  .div1,.div2 {
    width: 150px;
    height: 150px;
  }
  .div2 {
    background-color: #f00;
  }
</style>
<div class="div0">
  <div class="div1"></div>
</div>
<div class="div2"></div>

在線演示

三、有幾種定位方式,分別是如何實現定位的,參考點是什么,使用場景是什么?

定位有四種:static --> 靜態定位relative --> 相對定位absolute --> 絕對定位fixed --> 固定定位,下面詳細說。

1. 靜態定位。

positon: static其實就是元素默認值,正常的文檔流。

2. 相對定位

position: relative是比靜態定位強大一點點的定位。假如不為元素加上top、bottom、left、right,那么它表現得和靜態定位一模一樣。所以說它就是在靜態定位的基礎上多了個可選擇移動效果,但在移動后,如top: 20px; left: 20px,該元素占據的空間還是原來位置,只是展示效果平移了而已,所以這樣有可能覆蓋其他元素。應用于不想脫離文檔流,但又想平移的場景,同時relative也是absolute的參考對象,后面說。現在看個例子:

<style>
  div {
    display: inline-block;
    width: 200px;
    height: 200px;
  }
  
  .div1 {
    background-color: #333;
  }
  .div2 {
    background-color: #f00;
    position: relative;
    left: 20px;
    top: 20px;
  }
  .div3 {
    background-color: #0f0;
  }
</style>
<div class="div1"></div>
<div class="div2"></div>
<div class="div3"></div>

在線演示

3. 絕對定位

postion: absolute會使元素脫離文檔流,變得無比強大,只有一個樣式能束縛它,position: relative。所以要清楚的知道,絕對定位可以到處跑,但相對定位就是它的邊界,就像悟空逃不出佛祖一樣。如果父元素一直沒有relative,它就會繼續往上找,直到找到根元素或者relative祖先元素。與相對定位相比,絕對定位不再占據空間,可隨意覆蓋在任意元素上,只要它的z-index夠大(z-inde后面說),舉個例子:

<style>
  div {
    display: inline-block;
    width: 200px;
    height: 200px;
  }
  
  .div1 {
    background-color: #333;
  }
  .div2 {
    background-color: #f00;
    position: absolute;
    left: 20px;
    top: 20px;
  }
  .div3 {
    background-color: #0f0;
  }
</style>
<div class="div1"></div>
<div class="div2"></div>
<div class="div3"></div>

在線演示

4. 固定定位

position: fixed與絕對定位非常相似,除了兩點:

  • 不再受到束縛,可自由翱翔。
  • 活動范圍有限制,永遠顯示在當前瀏覽器視窗范圍內。

舉個例子:

<style>
  body{
    margin: 0;
  }
  .div1,.div2,.div3 {
    width: 100%;
    height: 500px;
  }
  .div1 {
    background-color: #333;
  }
  .div2 {
    background-color: #f00;
  }
  .div3 {
    background-color: #0f0;
  }
  .fixed {
    position: fixed;
    top: 0;
    left: 50%;
   
    
    margin-left: -100px;
    width: 200px;
    padding: 15px 0;
    border: 2px solid;
    text-align: center;
    background-color: #fff;
  }
</style>
<div class="div1"></div>
<div class="div2"></div>
<div class="div3"></div>
<div class="fixed">我就一直在這里</div>

在線演示

參考: 定位 | MDN

四、z-index有什么作用? 如何使用?

1. 沒有z-index情況

你是否會有這個疑惑,當各種定位都跑到一起的時候,該顯示誰呢?答案是:在沒有z-index干擾之前,根據順序顯示,誰在最后,顯示誰,舉個例子:

  <style>
    body {
      margin: 0;
      font-size: 0;
    }
    div {
      display: inline-block;
      width: 200px;
      height: 200px;
    }
    
    .div1 {
      position: static;
      background-color: #333; 
    }
    
    .div2 {
      position: relative;
      background-color: #f00;
    }
    
    .div3 {
      position: absolute;
      background-color: #0f0;
      top: 0;
      left: 50px;
    }
    
    .div4 {
      position: fixed;
      background-color: #00f;
      top: 0;
      left: 300px;
    }
  </style>
  <div class="div1"></div>
  <div class="div2">
    <div class="div3"></div>
  </div>
  <div class="div4"></div>

在線演示

2. 開始使用z-index

那有沒有一種辦法,讓前面的元素先顯示呢?這就是z-index的作用了,默認定位的z-index: 0;為零(其實不是零,而是不存在,不存在和零在這里意思是不同的,下面分析)。誰的z-index大,就顯示誰,還是剛才的例子,只不過加多一個z-index

/* 在 div3 那里加上 */
.div3 {
  z-index: 1;
}

在線演示
此時,div3應該跑出來了,不再被div4困住。想要div4再次顯示,需要給div4加上z-index: 2(或者為 1 也可以,z-index相同,根據順序顯示)。因為,只要z-index比別人大 1 ,就可以達到覆蓋效果,所以最好不要亂用,像直接寫z-index: 9999這種是十分不妥的,萬一以后你想覆蓋它怎么辦?而且要記住,只有當靠前的元素向覆蓋后面的元素才用z-index,因為如果元素本來就是在最后,根據順序顯示,是無須加z-index的。

3. z-index: 0 和 默認沒有(不寫)z-index為什么不同

只要你設置了z-index,那么在為定位判斷z-index時,要明白:只能在兄弟元素之間比較。舉個例子:

  <style>
    body {
      margin: 0;
      font-size: 0;
    }
    div {
      display: inline-block;
      width: 200px;
      height: 200px;
    }
    
    .div1 {
      position: static;
      background-color: #333; 
    }
    
    .div2 {
      position: relative;
      background-color: #f00;
      z-index: 0;
    }
    
    .div3 {
      position: absolute;
      background-color: #0f0;
      top: 0;
      left: 50px;
      z-index: 999;
    }
    
    .div4 {
      position: fixed;
      background-color: #00f;
      top: 0;
      left: 300px;
      z-index: 2;
    }
  </style>
  <div class="div1"></div>
  <div class="div2">
    <div class="div3"></div>
  </div>
  <div class="div4"></div>

在線演示

在上面的例子中,可以看到,絕對定位(positon: absolute)已經有z-index: 999,比固定定位(positon: fixed)的z-index: 2大得多,但因為相對定位(position: relative)的z-index只有 0 ,因此絕對定位無法實現最頂覆蓋。但如果相對定位(position:relative)不寫z-index的話,結果又會是不一樣的了,各位可自行測試。

五、position:relative和負margin都可以使元素位置發生偏移?二者有什么區別?

相對定位(postition: relative)的使用,不但使元素保持文檔流,而且使用top、bottom、left、right位移也不會改變本身占據空間位置。而負margin是靜態定位(position: static)位移的小技巧,是會讓元素本身位置發生改變的,使用在相對定位上也有同樣效果。看例子:

<style>
  body {
    margin: 0;
    padding-left: 100px;
  }
  .inline-block {
    display: inline-block;
    width: 200px;
    height: 200px;
    background-color: #333;
  }
  .div1 {
    position: relative;
    top: 0;
    left: -20px;
    /* margin-left: -20px; */
  }
  .div2 {
    margin-left: -20px;
  }
</style>
<div class="inline-block div1"></div>
<div class="inline-block"></div>
<div></div>
<div class="inline-block div2"></div>
<div class="inline-block"></div>

在線演示

記住,對相對元素使用負margin也是會使元素本身位置發生改變的,因為相對定位還是文檔流。

六、BFC 是什么?如何生成 BFC ?BFC 有什么作用?舉例說明

BFC(Block Formatting Context),譯為塊格式化上下文,說實話,這晦澀的翻譯會讓人更加困惑這個定義,且看我們怎么逐層分解!

1. 何為 BFC ?

首先要明白,BFC 指的是一個虛擬區域,一個塊級盒布局區域,,可以說是一個環境每個區域間相互不受影響。當你使用了以下元素時,你就為這個元素開辟了一個 BFC 保護區,用來保護這個元素。 參考:塊格式上下文 | MDN

  • 根元素或者其他包含它的元素(document
  • 浮動元素(元素的float不是none
  • 絕對定位元素(positionabsolute或者fixed
  • 內聯塊狀元素(display: inline-block
  • 表格單元格(display: table-cell
  • 表格標題(display: table-caption
  • overflow值不是visible的塊元素(默認就是overflow: visible

特別地,當里面元素都是行內元素或者文本時,創建出來的 BFC 就是 IFC(Inline Formatting Context)。

2. 如何理解 BFC ?

CSS 的渲染是從上往下排列元素塊的,最大的 BFC 就是 Document,在它里面的元素都要遵守他的規則。但 Document 里面允許創建新的 BFC,這些新的 BFC 會為自己內部建立新的規則,而且每個 BFC 之間不會相互干擾(就是基于這點解決外邊距合并和清除浮動的)。形象的理解就是, Document 是國家;普通塊元素是市(overflow: visible);新的 BFC 是省、直轄市(float、absolute、inline-block),他們允許有自己規則。

3. BFC 作用。

解決外邊距合并和清除浮動。外邊距合并下面說,現在說說清除浮動。

阻止浮動元素對其他元素的影響,可以為浮動元素新創建 BFC ,這樣浮動元素就不會影響外部元素了,如下,通過overflow: hidden創建了 BFC(雖然本身float也創建了 BFC ,但因為它在父元素內部,不會影響父元素外部的元素),阻止其影響其他元素:

<style>
  .div0 {
    overflow: hidden;
  }
  
  .float {
    float: left;
    background: #333;
  }
  
  .float,.div1 {
    width: 200px;
    height: 200px;
  }
  
  .div1 {
    background: #f00;
  }
</style>
<div class="div0">
  <div class="float"></div>
  <div class="float"></div>
</div>
<div class="div1"></div>

在線演示

參考:
什么是 BFC | Div.IO
關于 BFC | 穆乙
CSS 布局 | winter

七、在什么場景下會出現外邊距合并?如何合并?如何不讓相鄰元素外邊距合并?給個父子外邊距合并的范例

1. 何為外邊距合并?

外邊距合并(margin collapsing),準確來說,是外邊距塌陷。指的是 BFC 中相鄰的另個塊盒子的左右邊距和上下邊距發送疊加,兩者取最大值:

<style>
  div {
    width: 200px;
    height: 200px;
    background: #333;
    margin: 100px;
  }
</style>
<div></div>
<div></div>

在線預覽

在上面例子中,兩個<div>之間的間距只有100px,沒有達到預想中的200px,這就是外邊距合并。

2. 如何解決外邊距合并?

a. 首先要明確,外邊距合并只會發生在 BFC, 所以當前規則是 IFC 的話,就不會出現這種情況了,看例子:

<style>
  div {
    display: inline-block;
    width: 200px;
    height: 200px;
    background-color: #333;
    margin: 100px;
  }
</style>
<div></div>
<div></div>
<div></div>
<div></div>

b. 全部都是浮動元素不會出現外邊距合并

  <style>
    div {
      float: left;
      width: 200px;
      height: 200px;
      background-color: #333;
      margin: 100px;
    }
  </style>
  <div></div>
  <div></div>
  <div></div>
  <div></div>

在線預覽

c. 利用 BFC 來阻止合并

我們已經知道 BFC 之間不會相互影響,所以讓外邊距合并的元素各自創建一個 BFC ,就可以解決該問題

  <style>
    .div1 {
      width: 200px;
      height: 200px;
      margin: 100px;
      background-color: #333;
    }
    .div0 {
      overflow: hidden;
    }
  </style>
  <div class="div0">
    <div class="div1"></div>
  </div>
  <div class="div1"></div>

在線預覽

在上面例子,我們只建立了一個 BFC ,overflow: hidden建立。因為這個 BFC 不會影響的外邊的其他元素,所以效果就達到了。其實,在清除浮動的時候,在相鄰的非浮動元素加上overflow: hidden達到清除浮動效果,也是這個原理,因為float脫離了文檔流,但建立了新的 BFC,所以我們為受影響的元素創建 BFC 的話,根據 BFC 之間不會相互影響的規則,就可以達到清除浮動效果。如下例子:

  <style>
    body {
      margin: 0;
      padding: 1px;
    }
    div {
      width: 200px;
      height: 200px;
      background: #333;
      margin: 20px;
    }
    .float {
      float: left;
    }
    .normal {
      overflow: hidden;
    }
  </style>
  <div class="float"></div>
  <div class="normal"></div>

在線預覽

d. 當容器沒有paddingborder時,內部的margin會引發外邊距合并(父子外邊距合并)

這是一種很難發現的情況,但外邊距合并是會被內邊距padding阻止的,所以給父元素加1px的內邊距可以解決問題。或者為這個子元素建立新的 BFC,即在父元素加overflow: hidden(其他也可以)。

  <style>
    .div0 {
      margin: 100px;
      background: red;
      padding: 1px;
      /* overflow: hidden; */
    }
      .div1 {
        width: 200px;
        height: 200px;
        background-color: #333;
        margin: 150px;
      }
  </style>
  <div class="div0">
    <div class="div1"></div>
  </div>

在線預覽
參考:
談外邊距合并 | winter
外邊距合并 | MDN

八、編程任務

任務十 | GitHub

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1. 浮動元素有什么特征?對父容器、其他浮動元素、普通元素、文字分別有什么影響? 浮動元素脫離了普通文檔流。如果父...
    從這到那閱讀 442評論 0 0
  • relative:生成相對定位的元素,通過top,bottom,left,right的位置相對于其正常位置進行定位...
    zx9426閱讀 969評論 0 2
  • 一,浮動元素有什么特征?對父容器、其他浮動元素、普通元素、文字分別有什么影響? 浮動模型是一種可視化格式模型,浮動...
    DeeJay_Y閱讀 907評論 0 4
  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標簽默認的外補...
    _Yfling閱讀 13,814評論 1 92
  • 浮動元素有什么特征?對父容器、其他浮動元素、普通元素、文字分別有什么影響? 特征: 脫離正常文檔流,沿其容器的左側...
    _Dot912閱讀 739評論 0 3