點燈坊

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

使用 calc() 實現固定 Margin 的 RWD

Sam Xiao's Avatar 2021-02-16

為了實現 RWD,我們會將 widthmargin 都改用 % 而非 px,但這會造成 margin 隨 Browser 寬度改變,若要 margin 固定而 width 依舊使用 %,則要借數 calc() 根據固定 margin 動態計算 width

Version

Tailwind CSS 2.0.3

Flexbox

margin000

Item 的 widthmargin 都使用 % 看似完美。

margin001

當 browser 的 width 縮減時,可明顯發現 item 的 margin 也隨之改變。

<template>
  <div class="flex flex-wrap w-11/12 m-auto">
    <div class="w-1/6 m-1/12">1</div>
    <div class="w-1/6 m-1/12">2</div>
    <div class="w-1/6 m-1/12">3</div>
  </div>
</template>

<style scoped>
.m-1\/12 {
  margin: 8.333333%;
}
</style>

第 2 行

<div class="flex flex-wrap w-11/12 m-auto">
  • flex:使用 Flexbox
  • flex-wrap:設定當各 item 總 width 超越 parent width 時會自動換行,可避免總 width 計算錯誤而不知
  • w-11/12:以 % 設定 box width
  • m-auto:自動調整 margin 水平置中

第 3 行

<div class="w-1/6 m-1/12">1</div>
  • w-1/6:以 % 設定 item width
  • m-1/12:以 m-1/12 使用 % 設定 item margin,燒後會建立此 utility

第 10 行

.m-1\/12 {
  margin: 8.333333%;
}

建立 m-1/12 utility:

  • margin: 8.333333%:以 % 設定 margin

widthmargin 都改成 % 可完美配合 RWD,其唯一缺點是 margin 會隨 browser 改變而改變,實務上通常希望 margin 為固定值

calc()

margin002

Item 間的 margin 改成固定 10px,看起來與使用 % 一樣。

margin003

但 browser 的 width 縮減時,可明顯發現 item 的 margin 仍然固定為 10px

<template>
  <div class="flex flex-wrap w-11/12 m-auto">
    <div class="w-col-3 m-10px">1</div>
    <div class="w-col-3 m-10px">2</div>
    <div class="w-col-3 m-10px">3</div>
  </div>
</template>

<style scoped>
* {
  --column: 3;
  --margin: 10px;
}

.w-col-3 {
  width: calc(100% / var(--column) - 2 * var(--margin));
}

.m-10px {
  margin: var(--margin)
}
</style>

10 行

* {
  --column: 3;
  --margin: 10px;
}
  • --column: 3:設定 column 個數
  • --margin: 10px:設定 margin 為 10px

15 行

.w-col-3 {
  width: calc(100% / var(--column) - 2 * var(--margin));
}

建立 w-col-3 utility:

  • width: calc(100% / var(--column) - 2 * var(--margin)):width 改用 calc() 動態計算,處以 --column 並減去左右 --margin2 倍,如此 width 會自動隨著 RWD 改變 width 而變且 margin 為定值

19 行

.m-10px {
  margin: var(--margin)
}

建立 m-10px utility:

  • margin: var(--margin):使用 --margin 設定 margin

@apply

margin004

改用 @apply 將重複 utility 抽出。

<template>
  <div class="flex flex-wrap w-11/12 m-auto">
    <div class="col-3">1</div>
    <div class="col-3">2</div>
    <div class="col-3">3</div>
  </div>
</template>

<style scoped>
* {
  --column: 3;
  --margin: 10px;
}

.w-col-3 {
  width: calc(100% / var(--column) - 2 * var(--margin));
}

.m-10px {
  margin: var(--margin)
}

.col-3 {
  @apply w-col-3 m-10px;
}
</style>

第 3 行

<div class="col-3">1</div>

由於每個 column 的 utility 都相同,因此抽出 col-3 class。

23 行

.col-3 {
  @apply w-col-3 m-10px;
}

使用 @apply 將所有 utility 整合成單一 class。

Conclusion

  • CSS function 也能搭配 Tailwind 使用,只是 Tailwind 精髓在於 utility,因此可藉由 calc() 建立 w-col-3 utility 之後,再於 HTML 組合
  • 若 HTML 發現有重複的 utility,可再使用 @apply 將重複 utility 組合成新 utility,以利將來維護