CSS
vue.js
ElementUI

Vue.js + ElementUIでscopedのCSSが想定通りにならない

TL;DR

  • こんな記事読む前に ここにたどり着くべきだった → ElementUI に Scoped CSS が適用されない問題対応策
  • ドキュメントをもっとよく読みましょう

  • ElementUI側で作るやつに対してscopedはあまりにも無力

  • .el-button とか .el-form-item__content とかにスタイルを当てたいときはglobalなCSSを書く

以下覚書。

前置き

コードは全部それっぽいものを書いてるだけなので鵜呑みにしないように。

現象

願望: 「.el-form-item__content に対してスタイルを当てたいけど、この画面コンポーネントだけにしたい」

該当のコード

sample.vue
<template>
  <el-form-item label="sample col">
    <el-input v-model="col" />
  </el-form-item>
</template>

<style lang="sass" scoped>
  .el-form-item__content 
    background-color: red 
</style>

結果: 何も起きなかった
ちなみに、scopedを外すと全画面に適用される。その結果は求めていないので調査することに。

調査

コンパイルエラーが起きていないということはどこかに定義したCSSがあるだろうと思って探す。<head>内の<style>に案の定居た。

生成されたHTML

<html>
  <head>
    <style>
      .el-form-item__content[data-v-xxxxxxxx] {
        background-color: red;
      }
    </style>
  </head>
  <body>
    <div class="el-form-item__content">
      <div class="el-input">
        <input type="text" rows="2" class="el-input__inner">
      </div>
    </div>
  </body>
</html>

なんかdata属性ついてた。

そもそもscopedとは

Vueをよく分かっていないままCSSの修正だけをしていたので特にドキュメントを見たりもしていなかったのだけど、改めてscopedについて確認したらドキュメントがあった。

ドキュメント(日本語)
ドキュメント(英語)

その 画面 コンポーネントだけ、というのをdata-v-なんちゃらで対応してるっぽい。div的な何かを定義したらドキュメント通りにdata属性がついてきたので、あきらめることにした。
もうちょっと調べたらElementUIの要素をコンパイルするときにdata属性も付与するようにできたのかもしれないけど時間と知識の都合により断念。

対応

globalなスタイルを当てて対応する

sample.vue
<template>
  <el-form-item label="sample col" class="__red">
    <el-input v-model="col" />
  </el-form-item>
</template>

<style lang="sass">
  .el-form-item.__red
    .el-form-item__content 
      background-color: red 
</style>

結論

雑な流れ

  • CSSとしては .el-input__label[data-v-xxxxx] を探す
  • Vue側で書いてるhtmlにはdata属性がつく (<input data-v-xxx />)
  • ElementUI謹製HTMLにはない(<input class="el-input__inner" />)

scopedでスコープ付きにするとElementUIのコンポーネントから出来上がる要素に対してスタイルを指定することはできないっぽいのでglobalなCSSで対応することにした。