BFC、Flex box,一文帶你探索CSS佈局定位的奧祕

相信全部前端開發者的入門課,都是從div和css開始的,CSS做爲基礎中的基礎,除了讓頁面由於樣式而變得豐富美觀外,更是決定了頁面元素的排列布局,然而不少時候,當咱們對CSS只知其一;不知其二,咱們總會在開發中遇到元素不能按照咱們所想的那樣呈現出來的問題,因此本文就來系統的講講CSS的佈局定位。css

盒模型

首先,咱們來了解構成頁面的元素。在CSS中,咱們的每一個元素本質上都是一個盒子,盒模型決定了一個元素的大小和他所佔大小,盒模型由如下幾部分組成:html

  • Margin(外邊距) - 清除邊框外的區域,外邊距是透明的。
  • Border(邊框) - 圍繞在內邊距和內容外的邊框。
  • Padding(內邊距) - 清除內容周圍的區域,內邊距是透明的。
  • Content(內容) - 盒子的內容,顯示文本和圖像。

那麼元素的大小到底取決於什麼呢?目前有兩種盒模型:W3C盒模型IE盒模型,兩種盒模型的計算方法不一樣,在CSS中,咱們能夠用box-sizing指定使用哪一種方式計算:前端

  • content-box(W3C盒模型):盒子寬高 = 內容寬高(content)
  • border-box(IE盒模型):盒子寬高 = 內容寬高(content) + 內邊距 (padding)+ 邊框(border)

看個例子:css3

// W3C盒模型
<style>
  .box {
    width: 200px;
    height: 200px;
    padding: 10px;
    margin: 10px;
    border: 5px solid red;
    background-color: yellowgreen;
  }
</style>

<div class="box"></div>
複製代碼

效果:chrome

// IE盒模型
<style>
  .box {
    width: 200px;
    height: 200px;
    padding: 10px;
    margin: 10px;
    border: 5px solid red;
    background-color: yellowgreen;
    box-sizing: border-box;
  }
</style>

<div class="box"></div>
複製代碼

效果:瀏覽器

因此咱們發現,無論是哪種盒模型,margin的長度都不會被包含在元素的寬高裏,可是magin將決定元素在其父元素中的位置。

display 屬性

display用於定義創建佈局時元素生成的顯示框類型,會影響到兄弟元素之間的佈局,他的取值有如下幾種:bash

  • none:此元素不會被顯示。
  • block: 此元素將顯示爲塊級元素,此元素先後會帶有換行符。
  • inline:默認值。此元素會被顯示爲內聯元素,元素先後沒有換行符。
  • inline-block:行內塊元素。
  • list-item:此元素會做爲列表顯示。
  • table相關:此元素會被顯示爲表格或表格元素。
  • flex:彈性盒子。
  • run-in:此元素會根據上下文做爲塊級元素或內聯元素顯示。

下面咱們將對inline-blockflexrun-in這幾個屬性作詳細講解。佈局

inline-block

inline-blockfloatflex並稱實現元素行內顯示的「三巨頭」,相比較flex的豐富屬性,inline-block就略顯樸素,使用也十分簡單,看起來彷佛徹底不值得對它進行詳細介紹,但不知道大家在使用的時候是否也踩過那些inline-block的坑,因此這裏咱們來說講inline-block的必坑指南post

避坑指南一:行內元素間隙

咱們先來看一個例子:學習

<div class="content">
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
</div>

.content {
  background-color: yellow;
  width: 350px;
  height: 100px;
}
.cell {
  display: inline-block;
  width: 100px;
  height: 50px;
  background-color: red;
}
複製代碼

實現的效果:

咱們會發現,幾個行內元素之間出現了的空隙,這個空隙其實是由於咱們的HTML書寫致使的,咱們編寫代碼時輸入空格、換行都會產生空白符。而瀏覽器是不會忽略空白符的,對於多個連續的空白符瀏覽器會自動將其合併成一個,因此就產生了所謂的間隙。 想要解決這個間隙,咱們能夠給父元素設置 font-size:0

<div class="content">
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
</div>

.content {
  background-color: yellow;
  font-size: 0;
  width: 350px;
  height: 100px;
}
.cell {
  display: inline-block;
  width: 100px;
  height: 50px;
  background-color: red;
}
複製代碼

效果:

避坑指南二:高度塌陷,對齊問題

這個問題,是在開發的時候偶然碰見的,話很少說,先看看這兩個例子:

<div class="content">
  <div class="cell">有內容</div>
  <div class="cell"></div>
  <div class="cell">有內容</div>
</div>

.content {
  background-color: #eee;
  font-size: 0;
  width: 350px;
  height: 100px;
}
.cell {
  display: inline-block;
  width: 100px;
  height: 50px;
  font-size: 16px;
  background-color: #666;
  color: #fff;
}
複製代碼

效果:

在這個例子裏,咱們發現有字的行內塊元素和沒有字的行內塊元素顯示不在同一高度。而後咱們再看另外一個例子:

<div class="content">
  <div class="cell">有內容</div>
  <div class="cell" id="spec">有內容</div>
  <div class="cell">有內容</div>
</div>

.content {
  background-color: #eee;
  font-size: 0;
  width: 350px;
  height: 100px;
}
.cell {
  display: inline-block;
  box-sizing: border-box;
  width: 100px;
  height: 50px;
  line-height: 50px;
  border-radius: 50px;
  margin: 5px;
  font-size: 16px;
  text-align: center;
  background-color: #fff;
  color: #333;
}
.active {
  border: 2px solid #E20000;
  color: #E20000;
}

let spec = document.getElementById("spec");
let flag = false;
spec.addEventListener("click", () => {
  flag = !flag;
  if (flag) {
    spec.classList.add('active')
  } else {
    spec.classList.remove('active')
  }
});
複製代碼

效果:

咱們會發現,當中間的元素添加了邊框後,三個行內元素都發生了上下抖動,那是不是由於他們的高度發生了變化呢?那麼咱們就來測量一下:

測量結果顯示,這三個元素的高度同樣,並無發生改變,那麼到底是什麼緣由致使了行內元素高度塌陷、上下抖動的呢?

其實形成這一結果的是vertical-align屬性。inline-block做爲行內塊元素,也遵循行內元素的vertical-align垂直對齊方式,vertical-align的取值有如下幾種:

  • baseline:將元素的基線與父元素的基線對齊。
  • sub:將元素的基線與其父元素的下標基線對齊。
  • super:將元素的基線與其父代的上標 - 基線對齊。
  • text-top:將元素的頂部與父元素的字體頂部對齊。
  • text-bottom:將元素的底部與父元素的字體的底部對齊。
  • middle:將元素的中間與基線對齊加上父元素的x-height的一半。
  • top:將元素的頂部和其後代與整行的頂部對齊。
  • bottom:將元素的底部和其後代與整行的底部對齊。
  • <length>:將元素的基線對準給定長度高於其父元素的基線。
  • <percentage>:像<長度>值,百分比是line-height屬性的百分比。

在默認狀況下,會根據baseline進行定位,文字的定位不一樣,最終致使了整個塊元素的高度塌陷。想要解決這一問題,咱們只需將vertical-align設置爲top,以下: 狀況一:

<div class="content">
  <div class="cell">有內容</div>
  <div class="cell"></div>
  <div class="cell">有內容</div>
</div>

.content {
  background-color: #eee;
  font-size: 0;
  width: 350px;
  height: 100px;
}
.cell {
  display: inline-block;
  vertical-align: top;
  width: 100px;
  height: 50px;
  font-size: 16px;
  background-color: #666;
  color: #fff;
}
複製代碼

狀況二:

<div class="content">
  <div class="cell">有內容</div>
  <div class="cell" id="spec">有內容</div>
  <div class="cell">有內容</div>
</div>

.content {
  background-color: #eee;
  font-size: 0;
  width: 350px;
  height: 100px;
}
.cell {
  display: inline-block;
  vertical-align: top;
  box-sizing: border-box;
  width: 100px;
  height: 50px;
  line-height: 50px;
  border-radius: 50px;
  margin: 5px;
  font-size: 16px;
  text-align: center;
  background-color: #fff;
  color: #333;
}
.active {
  border: 2px solid #E20000;
  color: #E20000;
}

let spec = document.getElementById("spec");
let flag = false;
spec.addEventListener("click", () => {
  flag = !flag;
  if (flag) {
    spec.classList.add('active')
  } else {
    spec.classList.remove('active')
  }
});
複製代碼

run-in

run-in這個屬性值是在css3中被引入的,官方對他的描述是:

此元素會根據上下文做爲塊級元素或內聯元素顯示。

這個說法讓人會有些摸不着頭腦,因此咱們直接來看個例子。

在設計文章樣式的時候,也許你遇到過須要在一行內顯示一個標題和一段內容的場景,若是使用h標籤和p標籤咱們可能獲得的是下面這種結果:

<div class="article">
  <h1>One Point.</h1><p>Here is the description.If a run-in element precedes a block level element, the run in element will behave structurally as if it has become the block level elements first inline child element.</p>
</div>
複製代碼

當咱們將 h標籤的display屬性變成 run-in時,結果就變成了這樣。

h1 {
  display: run-in;
}

<div class="article">
  <h1>One Point.</h1><p>Here is the description.If a run-in element precedes a block level element, the run in element will behave structurally as if it has become the block level elements first inline child element.</p>
</div>
複製代碼

爲了更好的理解run-in,咱們把它和float,inline-block的佈局效果作比較:

h1 {
  float: left;
}

<div class="article">
  <h1>One Point.</h1><p>Here is the description.If a run-in element precedes a block level element, the run in element will behave structurally as if it has become the block level elements first inline child element.</p>
</div>
複製代碼

當使用float的時候,咱們發現左邊的標題會佔據多行,這和咱們的預期顯然有些差距。

h1 {
  display: inline-block;
}

<div class="article">
  <h1>One Point.</h1><p>Here is the description.If a run-in element precedes a block level element, the run in element will behave structurally as if it has become the block level elements first inline child element.</p>
</div>
複製代碼

當使用inline-block的時候,當內容有多行,標題和內容不能在一行顯示,如今咱們就可以明白 run-in究竟作了什麼:

  • 當該元素的下文是block時,該元素將表現爲inline-block
  • 當該元素的下文是inline-block時,該元素將表現爲block

雖然這個屬性看起來十分便利,可是這個屬性已經被大多數瀏覽器捨棄了,這也是爲何咱們平時聽到的不是特別多的緣由,瀏覽器認爲run-in破壞了HTML的表現,這些樣式上的實現,應該經過CSS去調節。 因此對於這個屬性,你們作個瞭解就能夠啦。

Flex box

Flex box多是目前用來作自適應用的最多的佈局方式了,Flex使用的豐富,也爲開發者提供了更便捷更可靠的佈局。

容器屬性

flex-direction

決定主軸的方向(即項目的排列方向)。取值:

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

flex-wrap

決定了子元素如何換行。取值:

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

flex-flow

是flex-direction屬性和flex-wrap屬性的簡寫形式,默認值爲row nowrap。

justify-content

決定了項目在主軸上的對齊方式。取值:

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

align-items

決定了項目在交叉軸上如何對齊。取值:

  • flex-start:交叉軸的起點對齊。
  • flex-end:交叉軸的終點對齊。
  • center:交叉軸的中點對齊。+
  • baseline: 項目的第一行文字的基線對齊。
  • stretch(默認值):若是項目未設置高度或設爲auto,將佔滿整個容器的高度。

align-content

決定了多根軸線的對齊方式。若是項目只有一根軸線,該屬性不起做用。取值:

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

子元素屬性

order

決定項目的排列順序。數值越小,排列越靠前,默認爲0。

flex-grow

決定項目的放大比例,默認爲0,即若是存在剩餘空間,也不放大。

flex-shrink

決定項目的縮小比例,默認爲1,即若是空間不足,該項目將縮小。

flex-basis

決定在分配多餘空間以前,項目佔據的主軸空間(main size)。瀏覽器根據這個屬性,計算主軸是否有多餘空間。它的默認值爲auto,即項目的原本大小。

flex

是flex-grow, flex-shrink 和 flex-basis的簡寫,默認值爲0 1 auto。後兩個屬性可選。

align-self

容許單個項目有與其餘項目不同的對齊方式,可覆蓋align-items屬性。默認值爲auto,表示繼承父元素的align-items屬性,若是沒有父元素,則等同於stretch。

注意點

  • 設爲 Flex 佈局之後,子元素的float、clear和vertical-align屬性將失效。

Float 浮動

在Flex box被普遍使用之前,咱們常常會利用float來實現塊元素行內兩端顯示,它的使用也十分簡單,float屬性有如下幾種取值:

  • none:默認值,沒有浮動效果。
  • left:元素浮動到父元素左側。
  • right:元素浮動到父元素右側。
  • inherit:規定應該從父元素繼承 float 屬性的值。

float自己沒有什麼難度,可是設置了float會致使父元素的沒法被撐開,margin失效,因此清除float也就成了開發必備知識。

清除浮動

原始效果:

<div class="content">
  <div class="cell spe1">塊1</div>
  <div class="cell spe2">塊2</div>
</div>

.content {
  background-color: #eee;
  font-size: 0;
  width: 350px;
}
.cell {
  font-size: 16px;
  background-color: #666;
  color: #fff;
}
.spe1 {
  width: 80px;
  height: 20px;
  float: left;
}
.spe2 {
  width: 80px;
  height: 30px;
  float: right;
}
複製代碼

方法一:設置空元素

<div class="content">
  <div class="cell spe1">塊1</div>
  <div class="cell spe2">塊2</div>
  <div class="clr"></div>
</div>

.clr {
  clear: both;
}
複製代碼

方法二:after僞元素

.content:after {
  content: '';
  display: block;
  visibility: hidden;
  clear: both;
}
複製代碼

該方法也是利用clear:both來清除浮動,與方法一的區別在於,方法一添加了一個clear元素,而這一個是在元素內部增長一個相似於clear的效果,其中有幾個注意點:

  • content:能夠爲空,也能夠取任意值。
  • display:必須設置爲block,不然在FF/chrome/opera/IE8下不能正常起做用。
  • visibility:設置爲hidden是爲了容許瀏覽器渲染它,可是不顯示出來。

方法三:利用overflow:hidden屬性

.content {
  overflow: hidden;
}
複製代碼

經過設置overflow達到清除浮動效果,其原理是建立了一個BFC,有關BFC的知識,咱們會在後面章節裏詳細介紹。

最終效果:

position 定位

position屬性決定了某個元素的定位方式,它的取值有如下幾種:

  • static:該關鍵字指定元素使用正常的佈局行爲,即元素在文檔常規流中當前的佈局位置。
  • relative:該關鍵字下,元素先放置在未添加定位時的位置,再在不改變頁面佈局的前提下調整元素位置(所以會在此元素未添加定位時所在位置留下空白)。
  • absolute:元素會被移出正常文檔流,並不爲元素預留空間,經過指定元素相對於最近的非 static 定位祖先元素的偏移,來肯定元素位置。絕對定位的元素能夠設置外邊距(margins),且不會與其餘邊距合併。
  • fixed:元素會被移出正常文檔流,並不爲元素預留空間,而是經過指定元素相對於屏幕視口(viewport)的位置來指定元素位置。元素的位置在屏幕滾動時不會改變。打印時,元素會出如今的每頁的固定位置。
  • sticky:元素根據正常文檔流進行定位,而後相對它的最近滾動祖先(nearest scrolling ancestor)和 containing block (最近塊級祖先 nearest block-level ancestor),包括table-related元素,基於top, right, bottom, 和 left的值進行偏移。偏移值不會影響任何其餘元素的位置。

在這些屬性裏,其中relative咱們稱之爲相對定位,absolute爲絕對定位,fixed爲固定定位,sticky爲粘性定位,而這幾個定位又能夠區分爲Normal flow(常規流)Unnormal Flow(很是規流)

Normal flow(常規流)

屬於常規流的取值:

  • static
  • relative

常規流具有如下特性:

  • 盒一個接着一個排列;
  • 在塊級格式化上下文裏面, 元素豎着排列;
  • 在行內格式化上下文裏面, 元素橫着排列;
  • 對於靜態定位(static positioning),position: static,盒的位置是常規流佈局裏的位置;
  • 對於相對定位(relative positioning),position: relative,盒偏移位置由這些屬性定義top,bottom,leftandright。即便有偏移,仍然保留原有的位置,其它常規流不能佔用這個位置。

常規流裏的元素屬於格式上下文(formatting context),塊元素和行內元素表現不一樣會產生快格式上下文和行內格式上下文,也就是咱們常說的BFCIFC

BFC (Block Formatting Context)

BFC的建立方法:

  • 根元素或其它包含它的元素。
  • 浮動 (元素的float不爲none)。
  • 絕對定位元素 (元素的position爲absolute或fixed)。
  • 行內塊inline-blocks(元素的 display: inline-block)。
  • 表格單元格(元素的display: table-cell,HTML表格單元格默認屬性)。
  • overflow的值不爲visible的元素。
  • 彈性盒flex boxes(元素的display: flex或inline-flex)。

BFC的本質就是建立一個隔離的空間,他的具體效果以下:

  1. 內部的盒會在垂直方向一個接一個排列(能夠看做BFC中有一個的常規流)。
  2. 處於同一個BFC中的元素相互影響,可能會發生margin collapse。
  3. 每一個元素的margin box的左邊,與容器塊border box的左邊相接觸(對於從左往右的格式化,不然相反),即便存在浮動也是如此。
  4. BFC就是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面的元素,反之亦然。
  5. 計算BFC的高度時,考慮BFC所包含的全部元素,連浮動元素也參與計算。
  6. 浮動盒區域不疊加到BFC上。

對於上述效果,除了1和3,彷佛都讓人有些摸不着頭腦,那麼就讓咱們經過幾個例子來仔細研究一下。

案例一:margin collapse

首先咱們來了解一下什麼是外邊距摺疊(margin collapse)。 在CSS中,兩個或多個毗鄰的普通流中的盒子(多是父子元素,也多是兄弟元素)在垂直方向上的外邊距會發生摺疊,這種造成的外邊距稱之爲外邊距摺疊。

那麼何時外邊距會發生摺疊呢?發生摺疊須要知足這幾種狀況:

  • 都屬於普通流的Block box且參與到相同的BFC中
  • 沒有被padding、border、clear和line box分隔開 都屬於垂直毗鄰盒子邊緣:
    1. 盒子的top margin和它第一個普通流子元素的top margin
    1. 盒子的bottom margin和它下一個普通流兄弟的top margin
    1. 盒子的bottom margin和它父元素的bottom margin
    1. 盒子的top margin和bottom margin,且沒有建立一個新的塊級格式上下文,且有被計算爲0的min-height,被計算爲0或auto的height,且沒有普通流子元素

下面讓咱們來看看代碼實例:

<div class="top"></div>
<div class="content">
  <div class="cell"></div>
  <div class="cell"></div>
</div>
<div class="foot">
  <div class="cell2"></div>
  <div class="spe"></div>
  <div class="cell2"></div>
</div>

.top {
  background-color: #60acfc;
  width: 100px;
  height: 50px;
}
.content {
  margin-top: 10px;
  background-color: #eee;
  width: 350px;
  margin-bottom: 10px;
}
.cell {
  margin-top: 20px;
  background-color: #5bc49f;
  height: 20px;
  margin-bottom: 30px;
}
.foot {
  background-color: #60acfc;
  width: 100px;
}
.spe {
  margin: 20px 0 30px;
}
.cell2 {
  height: 20px;
  background-color: #eee;
}
複製代碼

效果:

  • .content.cell的上邊距摺疊屬於第一條,最終.content.top之間的邊距爲20px。
  • .cell之間的邊距摺疊屬於第二條,最終.cell之間的邊距爲30px。
  • .cell.content的下邊距摺疊屬於第三條,最終.content.foot之間的邊距爲30px。
  • .spe本身的上下邊距摺疊屬於第四條,最終.spe佔據的間隔爲30px。

如今咱們知道了margin collapse發生的狀況,那咱們蓋如何避免邊距摺疊呢?方法有如下幾種:

  • 浮動元素不會與任何元素髮生摺疊,也包括它的子元素。
  • 建立了 BFC 的元素不會和它的子元素髮生外邊距摺疊。
  • 絕對定位元素和其餘任何元素之間不發生外邊距摺疊,也包括它的子元素。
  • inline-block 元素和其餘任何元素之間不發生外邊距疊加,也包括它的子元素。
  • 給常規流中的塊級元素添加padding、border、clear屬性。

案例二:BFC計算高度包含浮動盒

<div class="BFC">
  <div class="left"></div>
  <div class="right"></div>
</div>

.BFC {
  background-color: #eee;
}
.left {
  float: left;
  background-color: #60acfc;
  width: 100px;
  height:50px;
  opacity: 0.6;
}
.right {
  width: 150px;
  background-color: #5bc49f;
  height:30px;
}
複製代碼

在咱們沒有建立BFC的時候,父元素的高度不包含浮動元素高度。

.BFC {
  background-color: #eee;
  overflow: hidden;
}
複製代碼

建立BFC後,父元素就會加上浮動元素高度,這個就是咱們在以前提到的清除浮動的方法之一。

實例三:BFC內部不受浮動元素影響

<div class="BFC content">
  <div class="left"></div>
  <div class="right BFC">
    <div class="cell"></div>
    <div class="cell"></div>
  </div>
</div>

.BFC {
  overflow: hidden;
}
.content {
  background-color: #eee;
}
.left {
  float: left;
  background-color: #60acfc;
  width: 100px;
  height:50px;
  opacity: 0.6;
}
.right {
  width: 150px;
  background-color: #5bc49f;
  height:30px;
}
.cell {
  width: 20px;
  margin: 5px;
  background-color: #fff;
  height:20px;
  display: inline-block;
}
複製代碼

效果:

從這個例子,咱們就能夠理解,BFC佈局規則裏的第4和第6條:

  • BFC內部是一個獨立區域,不會受到外部元素的影響。
  • BFC外部的浮動不會和BFC發生重疊。

IFC (Inline Formatting Context)

IFC由inline元素構成,它的佈局規則是這樣的:

  • 高度由其包含行內元素中最高的實際高度計算而來。
  • IFC中的line box通常左右都貼緊整個IFC,可是會由於float元素而擾亂。float元素會位於IFC與與line box之間,使得line box寬度縮短。
  • 同個ifc下的多個line box高度會不一樣。
  • 水平的margin、padding、border有效,垂直無效。不能指定寬高。
  • 行框的高度由行高來決定。

那麼IFC通常有什麼用呢?

  • 水平居中:當一個塊要在環境中水平居中時,設置其爲inline-block則會在外層產生IFC,經過text-align則可使其水平居中。
  • 垂直居中:建立一個IFC,用其中一個元素撐開父元素的高度,而後設置其vertical-align:middle,其餘行內元素則能夠在此父元素下垂直居中。

Unnormal Flow(很是規流)

屬於很是規流的取值:

  • absolute
  • fixed
  • sticky

對於很是規流,由於他們脫離了正常的文檔流,因此他們不會對正常流的元素形成影響,不少時候咱們都會配合z-index使用,前兩種相信你們都不陌生,因此就再也不多作介紹啦,下面咱們來說講sticky

粘性定位(sticky)

粘性定位(sticky)能夠被認爲是相對定位和固定定位的混合。元素在跨越特定閾值前爲相對定位,以後爲固定定位。

<div class="content">
  <h1 class="title">我是一塊內容</h1>
  <div class="sticky"></div>
  <div class="main"></div>
</div>

.content {
  background-color: #eee;
}
.title {
  color: #333;
}
.sticky {
  position: sticky;
  top: 0px;
  background-color: #60acfc;
  width: 100px;
  height:50px;
}
.main {
  width:150px;
  height: 900px;
}
複製代碼

效果:

使用sticky佈局的時候有幾個注意點:

  • 父級元素不能有任何overflow:visible之外的overflow設置。
  • 父級元素設置和粘性定位元素等高的固定的height高度值,或者高度計算值和粘性定位元素高度同樣,沒有粘滯效果。
  • 同一個父容器中的sticky元素,若是定位值相等,則會重疊;若是屬於不一樣父元素,且這些父元素正好緊密相連,則會鳩佔鵲巢,擠開原來的元素,造成依次佔位的效果。
  • sticky定位,不只能夠設置top,基於滾動容器上邊緣定位;還能夠設置bottom,也就是相對底部粘滯。若是是水平滾動,也能夠設置left和right值。
  • z-index無效。

VFC

VFC,也就是Visual formatting context,虛擬格式上下文,他有BFCIFCGFCFFC這幾種類型,在前文中,咱們已經介紹了BFCIFC,這裏再簡單介紹下GFCFFC

GFC

GFC(GridLayout Formatting Contexts),"網格佈局格式化上下文",當爲一個元素設置display值爲grid的時候,此元素將會得到一個獨立的渲染區域。

咱們能夠經過在網格容器(grid container)上定義網格定義行(grid definition rows)和網格定義列(grid definition columns)屬性各在網格項目(grid item)上定義網格行(grid row)和網格列(grid columns)爲每個網格項目(grid item)定義位置和空間。

那麼GFC有什麼用呢,和table又有什麼區別呢?首先一樣是一個二維的表格,但GridLayout會有更加豐富的屬性來控制行列,控制對齊以及更爲精細的渲染語義和控制。

FFC

FFC(Flex Formatting Contexts),"自適應格式化上下文",display值爲flex或者inline-flex的元素將會生成自適應容器(flex container)。 因此當咱們使用flex佈局的時候,咱們就建立了一個FFC。

總結

至此,有關CSS佈局和定位的知識就結束了,文中若有解釋不到位的地方,歡迎你們評論指正。

參考連接:

W3C-Visual formatting model

Flex 佈局(阮一峯)

學習 BFC

相關文章
相關標籤/搜索