LoginSignup
3

More than 3 years have passed since last update.

posted at

updated at

Organization

CSSだってJavaScriptの値が欲しい!

インターン先でreact + typescript + scssのお仕事をしている @haduki1208 と申します。
最近reactよりscssを多く書いてる気がします。割と楽しいです。

TL;DR

  • CSS変数をインラインスタイルで書く
  • var()で読み込む

CSSでJavaScriptの値を取得する

趣味で「任意の大きさ・色・向きを指定できる矢印アイコン:arrow_up::arrow_right::arrow_down::arrow_left:」を作っていた時に

:thinking:「CSSでJavaScriptの値を取得できないのか?」

と思ったのでやってみました。

cssにattr()という関数がありますが、content属性でしか動作しないようです。
今回はheight, width, background-color, rotateに任意の値を使いたいのですがダメです。微妙な仕様ですね。

環境

  • typescript + react + scss および typescript + react + styled-components
  • chromeで動作確認
  • 動いたコードをcodepenに移植(codepenを使ってみたかった :heart: )

ソースコード

See the Pen Arrow01 react + ts + scss by haduki1208 (@haduki1208) on CodePen.

最初に作った矢印アイコンのソースコードです。

このコードの弱点は以下になります。

  1. size, color, rotateの1つでも違う値を使いたい場合、新たにclassnameを作成しなければならない
  2. tsxとscssの両ファイルに変更を加える必要がある
  3. mixinを使っているため、トランスパイル後のcssの容量が大きくなる

1番、2番は面倒くさいです。
これらを全て解消してみます。

変更後のソースコード

See the Pen Arrow02 react + ts + scss by haduki1208 (@haduki1208) on CodePen.

CSS カスタムプロパティ (変数)を使いました。

ポイントは以下になります。

  1. style属性に指定したオブジェクトは、インラインスタイルに変換される
  2. インラインスタイルで記述されているため、CSS変数が他の要素に影響しない
  3. typescript環境の場合、React.CSSPropertie型以外のオブジェクトを代入するため「as any」する必要がある

これでscssを編集せず色々なアイコンを作ることができます!

おまけ styled-componentsに置き換えたソースコード

こんなことするなら、最初からstyled-componentsにすれば良いじゃないと思った人もいらっしゃるでしょう。
僕は今までstyled-componentsを使ったことがなかったので、勉強のため置き換えをしてみました。

See the Pen Arrow03 react + ts + styled by haduki1208 (@haduki1208) on CodePen.

なんて素晴らしいライブラリなのでしょう。
scss、インラインスタイル、as any 全て消え去りました。
(ついでにwebpack.config.jsからstyle-loader, css-loader, sass-loader, postcss-loaderも消え去りました)

styled-componentsに惚れてしまいそうです。

感想

react + scssで開発をしているプロジェクトでJavaScripの変数を取得したくなった時はこの方法で解決できそうです。

既にscssで開発しているプロジェクトでは、styled-componentsに移行するにも時間がかかってしまうので、もしcssからjavascriptの値を使いたくなったら、ご検討ください。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
3