Vue.js で CSS 変数を使用する(Composition API サンプルコードあり)

📆August 24, 2020

Vue.js で CSS 変数を使う方法が分からなくて調べたのでそのメモです。ところどころ動作が分かってないところあったので、サンプルコードを書きながら検証してみました。

<template> 内で直接スタイルを当てるという方法もあるのですが、:after 疑似要素内で CSS 変数を使用したい場合はそうは行きません。(実際のプロジェクトでは、:after 疑似要素の background-imageprops で受け取った値を使うコンポーネントを作りたかった)ということで、いろいろググりながら実現方法が分かったので、最小構成でサンプルコードを書いてみました。

サンプルコード

ボタンを押すたびにアプリケーション内の状態が切り替わり background の画像が切り替わるサンプルです。

<template>
  <!-- [2] styles を bind する -->
  <div class="container" :style="styles">
    <div>
      <button @click="_onClickButton" class="button">ボタン</button>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, computed, reactive } from '@vue/composition-api'

const urls = [
  'https://blog.35d.jp/img/glitched-01.png',
  'https://blog.35d.jp/img/glitched-02.png',
  'https://blog.35d.jp/img/glitched-03.png',
]

type State = {
  index: number
}

export default defineComponent({
  setup() {
    const state = reactive<State>({ index: 0 })
    // [1] CSS 変数をキーバリューにした Object を作成
    const styles = computed<Object>(() => ({
      '--image-url': `url(${urls[state.index]})`,
    }))
    const _onClickButton = () => {
      state.index = (state.index + 1) % urls.length
    }

    return { _onClickButton, styles, state }
  },
})
</script>

<style>
.container {
  // [3] var(キー名) で CSS 変数として使用可能になる
  background-image: var(--image-url);
}
</style>

渡したいスタイルを詰め込んだオブジェクトを定義

 // [1] CSS 変数をキーバリューにした Object を作成
const styles = computed<Object>(() => ({
  '--image-url': `url(${urls[state.index]})`,
}))

このように、オブジェクトを作成します。キーは、カスタムプロパティの命名規則に従い、ハイフン2個を付けるルールになっています(ハイフン2個じゃないと動きません)。今回の例では、background-image のプロパティ用のオブジェクトを作成しました。

(参考) CSS カスタムプロパティ (変数) の使用

styles を bind する

  <!-- [2] styles を bind する -->
  <div class="container" :style="styles">

さきほど作成した styles オブジェクトを return することで、<template> 内で styles が見えるようになります。styles オブジェクトを、CSS を当てたい要素の :style に bind することで <style> 内でさきほど定義した CSS 変数として参照することができるようになります。

(参考)インラインスタイルのバインディング

CSS 変数を使用する

<style>
.container {
  // [3] var(キー名) で CSS 変数として使用可能になる
  background-image: var(--image-url);
}
</style>

bind した要素に付いているクラス内でしか、CSS 変数は使用できないので注意が必要です。

例によって、Nuxt.js でサンプルコードを書きました。GitHub でソースコード公開しています。2020/08/24 時点で、 Netlify にもデプロイしてあります(そのうち閉じる可能性もアリ)

https://github.com/35d/vue-css-variables-sample

https://festive-snyder-987a3d.netlify.app/

もっと良い書き方あったりしたら @___35d にこっそり教えて下さい。



🔖 NuxtJS