點燈坊

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

綁定 CSS Variable

Sam Xiao's Avatar 2021-05-07

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

Version

Vue 3.0.11

Background Color

variable000

div 的背景色為 紅色。

<template lang='pug'>
.bar
</template>

<style scoped>
.bar {
  height: 30px;
  background: #f00;
}
</style>

第 6 行

.bar {
  height: 30px;
  background-color: #f00;
}

設定 bar style:

  • background-color: #f000:設定 div 的背景為紅色

Local CSS Variable

local002

div 背景一樣是紅色,但改用 CSS variable。

<template lang='pug'>
.bar
</template>

<style scoped>
.bar {
  height: 30px;
  --bgColor: #ff0000;
  background: var(--bgColor);
}
</style>

第 6 行

.bar {
  height: 30px;
  --bgColor: #ff0000;
  background: var(--bgColor);
}

設定 bar style:

  • --bgColor: #ff0000:以 -- 設定 bgColor
  • background: var(--bgColor):以 var() 使用 --bgColor

目前 --bgColor 只是 CSS scope 的 variable,JavaScript 並無法與之連動

Variable Binding

local003

div 背景一樣是紅色,但改用 Vue 的 variable binding。

<template lang='pug'>
.bar
</template>

<script setup>
ref: bgColor = '#f00'
</script>

<style scoped>
.bar {
  height: 30px;
  background: v-bind(bgColor);
}
</style>

10 行

.bar {
  height: 30px;
  background: v-bind(bgColor);
}

設定 bar style:

  • background: v-bind(bgColor):使用 v-bind()bgColor state 直接綁定到 background

第 6 行

ref: bgColor = '#f00'

在 Vue 定義 bgColor state 為 #f00

Change Color

variable001

Vue 綁定 CSS variable 後,最大的價值在於可以使用 JavaScript 改變之。

按下 Change Color 後,<div> 背景色從紅色變成綠色。

<template lang='pug'>
.bar
button(@click='onClick') Change Color
</template>

<script setup>
ref: bgColor = '#f00'

let onClick = () => bgColor = '#0f0'
</script>

<style scoped>
.bar {
  height: 30px;
  background: v-bind(bgColor);
}
</style>

第 9 行

let onClick = () => bgColor = '#0f0'

在 Vue 的 bgColor state 改成綠色,則 CSS variable 也會同步改成綠色。

如此就能以 JavaScript 邏輯改變 CSS variable,不再如以往只存在於 CSS scope,而無法與 JavaScript 連動

Point-free

local004

結果不變,但使用 Point-free 改寫。

<template lang='pug'>
.bar
button(@click='onClick') Change Color
</template>

<script setup>
import { ref } from 'vue'
import { write } from 'vue3-fp'
import { pipe, always } from 'ramda'

let bgColor = ref('#f00')

let onClick = pipe(
  always('#0f0'),
  write(bgColor),
)
</script>

<style scoped>
.bar {
  height: 30px;
  background: v-bind(bgColor);
}
</style>

13 行

let onClick = pipe(
  always('#0f0'),
  write(bgColor),
)

使用 pipe() 組合 onClick()

  • always('#0f0'):準備 #0f0
  • write(bgColor):寫入 bgColor state

Conclusion

  • 可將 CSS variable 之初始值都寫在 Vue 的 state 統一管理,避免初始值因寫在 <style> 內而忘記

  • Vue 3 使得 JavaScript 與 CSS variable 綁定變成異常簡單,HTML template 完全不變,不需使用 style binding 與 computed,只要在 <style> 使用 v-bind() 即可

Reference

Vue, SFC Style Variables