點燈坊

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

使用 Vue 改變 Component CSS Variable

Sam Xiao's Avatar 2021-02-04

若有數值在 CSS 重複出現,我們可將其抽成 CSS Variable,將來只需維護一處即可;若能將 JavaScript Variable 與 CSS Variable 結合,則可使用 JavaScript 動態改變 CSS。

Version

Vue 2.6.11

HTML

css000

同時顯示兩張 320x200 的圖片。

<template>
  <div>
    <img src="https://picsum.photos/320/200/?random=10">
    <img src="https://picsum.photos/320/200/?random=11">
  </div>
</template>

<img> 根據原圖大小顯示,並未指定任何寬高。

CSS

css001

雖然原圖為 320x200,經過 CSS 改以 160x100 顯示。

<template>
  <div>
    <img class="img1" src="https://picsum.photos/320/200/?random=10">
    <img class="img2" src="https://picsum.photos/320/200/?random=11">
  </div>
</template>

<style scoped>
.img1 {
  width: 160px;
  height: 100px;
}

.img2 {
  width: 160px;
  height: 100px;
}
</style>

第 9 行

.img1 {
  width: 160px;
  height: 100px;
}

.img2 {
  width: 160px;
  height: 100px;
}

img1img2 同時都改以 160x100 顯示。

CSS Variable

css002

兩張圖依然以 160x100 顯示。

<template>
  <div>
    <img class="img1" src="https://picsum.photos/320/200/?random=10">
    <img class="img2" src="https://picsum.photos/320/200/?random=11">
  </div>
</template>

<style scoped>
* {
  --image-width: 160px;
  --image-height: 100px;
}

.img1 {
  width: var(--image-width);
  height: var(--image-height);
}

.img2 {
  width: var(--image-width);
  height: var(--image-height);
}
</style>

第 9 行

* {
  --image-width: 160px;
  --image-height: 100px;
}

將重複的 160px100px 抽成 ---image-width--image-height

14 行

.img1 {
  width: var(--image-width);
  height: var(--image-height);
}

.img2 {
  width: var(--image-width);
  height: var(--image-height);
}

img1img2 重複使用 --image-width--image-height

Vue

css003

兩張圖再使用 Vue 改成 80x50

<template>
  <div>
    <img :style="rootStyle" class="img1" src="https://picsum.photos/320/200/?random=10">
    <img :style="rootStyle" class="img2" src="https://picsum.photos/320/200/?random=11">
  </div>
</template>

<style scoped>
* {
  --image-width: 160px;
  --image-height: 100px;
}

.img1 {
  width: var(--image-width);
  height: var(--image-height);
}

.img2 {
  width: var(--image-width);
  height: var(--image-height);
}
</style>

<script>
let rootStyle = function() {
  return {
    '--image-width': this.imageWidth + 'px',
    '--image-height': this.imageHeight + 'px'
  }
}

export default {
  data: () => ({
    imageWidth: 80,
    imageHeight: 50,
  }),
  computed: {
    rootStyle
  }
}
</script>

第 3 行

<img :style="rootStyle" class="img1" src="https://picsum.photos/320/200/?random=10">
<img :style="rootStyle" class="img2" src="https://picsum.photos/320/200/?random=11">

rootStyle computed 綁定到 <img>

26 行

let rootStyle = function() {
  return {
    '--image-width': this.imageWidth + 'px',
    '--image-height': this.imageHeight + 'px'
  }
}

imageWidthimageHeight 綁定到 --image-width--image-height

Conclusion

  • <script scoped> 之賜,我們可在 * {} 內定義 CSS variable 而不必使用 :root {}
  • 必須每個 element 都使用 rootStyle computed 綁定才改變 CSS variable