實用的 Web 佈局技巧:Flex 主軸上的自動外邊距

問題描述

先來看一個需求場景:css

圖片描述

上圖中須要實如今水平方向上子元素之間、子元素和父容器邊框之間的間距要相等。html

實現的方法有不少,咱們這裏要討論的是:如何簡潔地使用 Flex 佈局來實現?
我這裏採用的方法是:使用自動的外邊距在主軸上對齊。佈局

自動的外邊距在主軸上對齊

咱們先來看一下 MDN 關於這個的解釋:flex

... 自動的外邊距會佔據所有的多餘的空間——在一個塊上設置自動的左右外邊距可使它居中。兩邊儘量佔據多的空間,塊就被置於中間位置了。

這很好理解:自動外邊距將平分所有的剩餘空間。下面就來嘗試下這個方案吧,代碼以下:spa

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>
.container {
  display: flex;
  align-items: center;
  box-sizing: border-box;
  border: 2px dashed #7cb305;
  width: 600px;
  height: 200px;
  margin: auto;
}


.item {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 0 auto;
  width: 100px;
  height: 100px;
  background: #722ed1;
  border-radius: 50%;
  color: #fff;
  font-size: 22pt;
}

而後看一下效果:code

圖片描述

貌似有點不對。仔細看看子元素之間的間距比到邊框的大,大概是子元素到邊框的兩倍,跟咱們預期的效果有差別。
按照 MDN 的解釋來看,自動的外邊距會等分剩餘空間,但爲何會出現上圖的狀況呢?下面來談一下個人理解。htm

主軸剩餘空間「分配權重」與子元素自動外邊距的關係

這個分配權重關係沒有在 MDN 上找到相關解釋,純粹是我的看法,咱們能夠這樣來理解:blog

  • 若是一個子元素在主軸的一個區域(或方向)上聲明瞭 margin-*: auto,那麼這個空間的分配權重 + 1
  • 若是另一個子元素也在一樣的區域(或方向)上有自動外邊距的聲明,那麼分配權重再 + 1
  • 在這些聲明瞭自動外邊距的區域上,剩餘空間根據分配權重來劃分間距大小

首先,這個理解顯然是能夠知足 MDN 上的解釋。而後咱們再來看看上圖的狀況怎麼解釋:圖片

  • 咱們把 子元素1 的左邊區域命名爲 間距區域1子元素1 的右邊區域命名爲 間距區域2
  • 子元素1 的左邊和右邊都有自動外邊距,那麼 間距區域1的權重 = 1間距區域2的權重 = 1
  • 子元素2 的左邊和右邊都有自動外邊距,那麼 間距區域2的權重 = 1 + 1 = 2
  • 最後 間距區域1的權重間距區域1的權重 就是 1:2 的關係
  • 其餘區域依次類推,最後根據權重劃分間距區域大小

而後依據這種理解咱們來調整下代碼,只須要在每一個相隔的區域上聲明一次自動外邊距就行了:get

  • 首先咱們把 .item 這個樣式上的 margin 去掉
  • 而後只在 html 的 子元素1子元素3 上設置 style="margin: 0 auto"

調整後以下:

<div class="container">
  <div class="item" style="margin: 0 auto">1</div>
  <div class="item">2</div>
  <div class="item" style="margin: 0 auto">3</div>
</div>
.container {
  display: flex;
  align-items: center;
  box-sizing: border-box;
  border: 2px dashed #7cb305;
  width: 600px;
  height: 200px;
  margin: auto;
}


.item {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100px;
  height: 100px;
  background: #722ed1;
  border-radius: 50%;
  color: #fff;
  font-size: 22pt;
}

OK,問題解決了
根據這個理解還有一種設置也能夠達到一樣效果:

<div class="container">
  <div class="item" style="margin-left: auto">1</div>
  <div class="item" style="margin: 0 auto">2</div>
  <div class="item" style="margin-right: auto">3</div>
</div>

以上代碼已放到 codepen 上:https://codepen.io/deepfunc/pen/BembyQ

相關文章
相關標籤/搜索