インターン先でreact + typescript + scssのお仕事をしている @haduki1208 と申します。
最近reactよりscssを多く書いてる気がします。割と楽しいです。
TL;DR
- CSS変数をインラインスタイルで書く
- var()で読み込む
CSSでJavaScriptの値を取得する
趣味で「任意の大きさ・色・向きを指定できる矢印アイコン」を作っていた時に
「CSSでJavaScriptの値を取得できないのか?」
と思ったのでやってみました。
cssにattr()という関数がありますが、content属性でしか動作しないようです。
今回はheight, width, background-color, rotateに任意の値を使いたいのですがダメです。微妙な仕様ですね。
環境
- typescript + react + scss および typescript + react + styled-components
- chromeで動作確認
- 動いたコードをcodepenに移植(codepenを使ってみたかった )
ソースコード
See the Pen Arrow01 react + ts + scss by haduki1208 (@haduki1208) on CodePen.
最初に作った矢印アイコンのソースコードです。
このコードの弱点は以下になります。
- size, color, rotateの1つでも違う値を使いたい場合、新たにclassnameを作成しなければならない
- tsxとscssの両ファイルに変更を加える必要がある
- mixinを使っているため、トランスパイル後のcssの容量が大きくなる
1番、2番は面倒くさいです。
これらを全て解消してみます。
変更後のソースコード
See the Pen Arrow02 react + ts + scss by haduki1208 (@haduki1208) on CodePen.
CSS カスタムプロパティ (変数)を使いました。
ポイントは以下になります。
- style属性に指定したオブジェクトは、インラインスタイルに変換される
- インラインスタイルで記述されているため、CSS変数が他の要素に影響しない
- 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の値を使いたくなったら、ご検討ください。