CSS
JavaScript
ShadowDOM
reactjs

Reactのスタイル問題にShadow DOMを使うという選択肢

More than 1 year has passed since last update.

といっても今のところChromeアドオンやElectronくらいでしか使えませんが。

BEMとかCSS ModulesとかCSS in JSとかで非常に心が疲れたので、
Shadow DOMに安寧の地を求めることにしました。

ReactでShadow DOMを使う

別に難しいことするわけではなく、ReactShadowを使うだけです。

hello.jsx
import React from 'react';
import ShadowDOM from 'react-shadow';

export default class Hello extends React.Component {
  render() {
    return (
      <ShadowDOM>
        <h1>Hello, World!</h1>
      </ShadowDOM>
    );
  }
}

タグで囲むだけでそれ以下の要素がShadow DOMになってCSS空間が分割されます。

スタイルの適用

スタイルはSassで書きたい勢なので、
webpackのraw-loaderとsass-loaderでSassをCSS文字列として読み込ませて、

webpack.config.js
    loaders: [
      {
        test: /\.scss$/,
        loaders: ['raw-loader', 'sass-loader']
      }
      ...
    ]

styleタグに放り込んで終わり。

hello.jsx
import React from 'react';
import ShadowDOM from 'react-shadow';
import css from './style.scss';

export default class Hello extends React.Component {
  render() {
    return (
      <ShadowDOM>
        <div>
          <style>{css}</style>
          <h1>Hello, World!</h1>
        </div>
      </ShadowDOM>
    );
  }
}

...Polymerかな?

感想

大して使ってないですが、今のとこはいい感じ。

Shadow DOMによって新たなCSSの適用単位が生まれるので、
ReactコンポーネントとCSSコンポーネントは1対1なのか問題をある程度解決できるかもね。

追記

iframeを使えば同じことできるので、Shadow DOM非対応のブラウザでも使えます。

iframeではContent Security Policyのchild-src 'none'に引っかかるかと思ってたけど、
src属性使わず外からいじる分にはセーフっぽい。