點燈坊

失くすものさえない今が強くなるチャンスよ

深入探討 align-items stretch

Sam Xiao's Avatar 2021-03-02

Flexbox 的 align-items 預設為 stretch,這也使得 Flexbox 可自動 stretch 子層 item 使其等高。

Version

CSS 3

No Wrap

stretch000

在沒有換列下,儘管子層 item 都沒有定義 height,但 Flexbox 會使每個子層 item 自動等高。

<template>
  <div class="box">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
  </div>
</template>

<style scoped>
.box {
  display: flex;
  width: 100%;
  height: 500px;
}

.item {
  width: 250px;
  margin: 10px;
}
</style>

12 行

.box {
  display: flex;
  width: 100%;
  height: 500px;
}

設定父層 box 的 style:

  • display: flex:設定子層使用 Flexbox
  • width: 100%:設定父層 box width
  • height: 500px:設定父層 box height

18 行

.item {
  width: 250px;
  margin: 10px;
}

設定子層 item 的 style:

  • width: 250px:設定子層 item width
  • margin: 10px:設定子層 item margin

重點在於子層 item 沒有設定 height

若父層 box 設定 height,而子層 item 不設定 height,且沒有設定 wrap,因為 align-items 預設為 stretch,所以各 item height 會自動 stretch 成與父層等高,這是改用 Flexbox 後的一大特性。

Wrap

stretch001

在自動換列下,儘管子層 item 都沒有定義 height,但 Flexbox 會使每個 item 自動等高。

<template>
  <div class="box">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
  </div>
</template>

<style scoped>
.box {
  display: flex;
  flex-wrap: wrap;
  width: 100%;
  height: 500px;
}

.item {
  width: 250px;
  margin: 10px;
}
</style>

12 行

.box {
  display: flex;
  flex-wrap: wrap;
  width: 100%;
  height: 500px;
}

設定父層 box 的 style:

  • display: flex:設定子層使用 Flexbox
  • flex-wrap: wrap:當各子層 item 總 width 超越父層 box width 時自動換列,也是啟動 flex line 的開關
  • width: 100%:設定父層 box 的 width
  • height: 500px:設定父層 box 的 height

19 行

.item {
  width: 250px;
  margin: 10px;
}

設定子層 item 的 style:

  • width: 250px:設定子層 item 的 width
  • margin: 10px:設定子層 item 的 margin

注意子層 item 並沒有設定 height

當父層 box 使用 flex-wrap: wrap 時,因為會換列產生兩條 flex line,由於子層 item 沒設定 height,且 align-items 預設為 stretch,因此子層 item 的 height 會自動 stretch 成與 flex line 的 height 等高。

Same Height

stretch002

子層 item 一樣沒有設定 height,且 item 1 因為 content 較多而撐出較高的 height,會發現 item2 與 item 3 會自動與 item 1 等高。

<template>
  <div class="box">
    <div class="item">1 2 3 4 5</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
  </div>
</template>

<style scoped>
.box {
  display: flex;
  flex-wrap: wrap;
  width: 100%;
  height: 500px;
}

.item {
  width: 250px;
  margin: 10px;
  font-size: 5rem;
}
</style>

19 行

.item {
  width: 250px;
  margin: 10px;
  font-size: 5rem;
}

設定子層 item 的 style:

  • font-size: 5rem:為了讓 content 撐起 height 效果明顯,特別將 font size 變大

若其中有一列因為 content 而改變 height,則一整列都會自動等高

align-items: center

stretch003

父層 box 使用 align-items: center 後,子層 item 不再自動 stretch 與 flex line 等高,而是根據 content 自動調整 height。

紅色部分為 flex line,可明顯看出 align-items: center 使得子層 item 自動垂直置中於 flex line。

<template>
  <div class="box">
    <div class="item">1 2 3 4 5</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
  </div>
</template>

<style scoped>
.box {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  width: 100%;
  height: 500px;
}

.item {
  width: 250px;
  margin: 10px;
  font-size: 5rem;
}
</style>

12 行

.box {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  width: 100%;
  height: 500px;
}

設定父層 box 的 style:

  • flex-wrap: wrap:使用換列啟動 flex line
  • align-items: center:由於明確指定 align-itemscenter,因此子層 item 喪失了 align-items: stretch,子層 item 不再自動 stretch 成 flex line 高度,而是由 content 決定,也因為子層 item 與 flex line 高度不同,因此 align-items: center 有其用武之地而垂直置中

Conclusion

  • Flexbox 只所以會讓子層 item 自動 stretch 等高,關鍵在於 align-items 預設為 stretch,但只要將 align-items 改成其它值,就會立即喪失等高功能
  • flex-wrap: wrap 為啟動 flex line 關鍵,若為 nowrap 則自動 stretch 成外層 box 等高;若為 wrap 則自動 stretch 成 flex line 等高

Reference

MDN, align-items