ReactとCSS
Reactを少しずつ使い始めていて、コンポーネント指向でコードを書いていけるところが自分の経験だとDelphiのような感じでとても良い。 JavaScriptとHTML(JSX)を1つのスクリプトにまとめることができたのは良いのだけど、そうするとやはりCSSも一緒にまとめたくなってくる。
それでReactとCSSについていくらか調べてみた。ちなみにElectronで動作すれば良いので、Blinkのことしか考えていない。
CSS in JS
そもそもReactでCSSは普通どういう風に書くのか調べてみた。
ひとつのやり方ではあるけども、style属性に一つ一つ指定していく方法。 辛くない?疑似要素は?疑似クラスは?継承してもらいたいプロパティとかもあるんだけどな〜
scoped CSS
せっかくコンポーネントにするのだし、CSSもコンポーネントに閉じたところでのみ適用されて欲しいと思ってscoped CSSについて調べた。
てっきりBlinkにはstyleタグのscoped属性がすでに実装されていると思っていたのだけど、Firefoxしか実装していないみたいだ。 記事にもあるとおり、Blinkで同様のことをするにはShadow DOMを使用する必要がある。
Shadow DOM
Shadow DOMについて深い理解があるわけではなかったので、調べてみた。
templateタグで楽はできそうだけど、JavaScriptでShadow DOMを生成・追加するためのコードを書く必要があるみたいだ。 Reactと組み合わせて使うにはまだ自分のReactの理解力が低すぎて作れない……
ReactStyle
他の解決策〜と思って調べてみたらReactStyleというのを見つけた。
疑似要素〜疑似クラス〜という感じだ。
Radium
こちらはReactStyleと違って(一部の?)疑似クラスとメディアクエリが使える。
Radiumはスタイルのマージが簡単にできて
const CSS = {
base: {
height: '100px',
width: '100px',
},
div: {
backgroundColor: 'blue',
height: '150px',
},
};
const Component = React.createClass(Radium.wrap({
render() {
return (<div style={[CSS.base, CSS.div]}></div>);
},
}));
という風に配列を指定するとできる。
ChromeのReact Developer Toolsで見たらタグ名がUnknownになっていてびっくりした。
Radium.wrap()
内に書いたJSXだからなのか、displayNameが出力されないみたいなのでdisplayNameを自分で指定する必要がある。
ReactShadow
ReactでShadow DOMは扱えないのか調べてみたらmixinがあった。
正真正銘のShadow DOMでcssDocuments
やcssSource
のプロパティ名が示すようにscoped CSSの目的で使うみたいだ。
ただ、出力されるHTMLが若干変な感じ。React.createClass()
で生成したコンポーネントがShadow DOMとして追加されるのだけど、
それの直後にscriptタグが追加される。scriptタグの中身はコンポーネントと全く同じ。
つまり、Shadow DOMとscriptタグにそれぞれ同じコンポーネントが追加される。
ちゃんとソースコードを読んでいないので勘なのだけど、Reactがscriptタグ内にあるコンポーネントを変更して、 ReactShadowがその変更をShadow DOM内にあるコンポーネントに同期させている感じなのかな。
とりあえずRadiumを使ってみている。ReactShadowもscriptタグが気にならければ良いんじゃないかなと思う。
そういえばscoped CSSとShadow DOMを使ってのスタイル当てというのは若干異なるような気がした。 Shadow DOMって通常だと外側のスタイルが当たらないんじゃなかったっけ。
簡単に扱えるネイティブのscoped CSSが欲しいなあ。一意のidかclassを付加してセレクタの最初にそれを書けばscoped CSSっぽくなるかな。