CSS
WebComponents
scoped-css
More than 3 years have passed since last update.

JavaScriptの激変は、CSSコーダー(?)にとっても対岸の火事ではありません。むしろ、変態的な職人的な方法論を捨て去らなきゃならないのは、CSSも同じ。

それはともかく、Scoped CSSについて整理しつつメモしてみます。※2015年初頭の状況として


なにこれ?

Scoped CSSはDOMの中に<style scoped>タグを配置すると、そのDOMの内側にだけに限定されるCSSが書けるというものです。アイデア自体はしばらく前から存在するものの、Firefoxにのみ実装され、Chromeについては実装が止まっています。経緯を追うと、Web ComponentsのShadow DOMのCSSがscoped相当になるため「重複機能」と判断され、ペンディングになっている気配です。(ChromeとしてはWeb Componentsの仕様固めが優先)


なにが嬉しいのか


  • コンポーネントのCSS記述が簡潔になる

  • CSSをコンポーネント内に書くことの効率性


  • OOCSSBEMとさようなら〜

それだからこそ、Web Componentsに取り込まれているわけですが、対応できればAngularやReactでもCSSを書くのが楽になります。Web Componentsにさっさと昇華するのか、Scoped CSSとして日の目を見るのかはさておき、考え方自体は今後のCSSで標準になるでしょう。真面目な話、CSSの方法論がどんがらがっしゃんする寸前の2015年です。

SMACSS使いなら、(CSSの)モジュールに分けていたはずですが、それぞれのコンポーネント内に記述を移し、basethemeだけメインのCSSに残せばOK。移行はそれほど難しくないはず。BEMな人なら「__」の前(ブロック)を書く必要がなくなるといえば通じるでしょうか?


Polyfills

ブラウザ対応が限られる一方、案外Polyfillは充実しています。


Polymerの場合

Shadow DOMのPolyfillの一部として、Scopedが使えるようになっています。

<polymer-element name="x-foo">

<template>
<style>
div { ... }
:host { ... }
</style>
...

は、下記のように解釈されます。:hostがタグ名に置き換わります。

<polymer-element name="x-foo">

<template>
<style>
x-foo div { ... }
x-foo { ... }
</style>
...


Riot.jsに提案中 (2015年2月現在)

ほぼ、Polymerと同じですが、Mozillaにしたがって:scopeを使っています。

<my-tag>

<h3>{ opts.title }</h3>

<style scoped>
:scope { display: block; border: 2px }
h3 { color: blue }
</style>

</my-tag>

は、下記のように解釈されます。

<my-tag>

<h3>{ opts.title }</h3>

<style>
my-tag { display: block; border: 2px }
my-tag h3 { color: blue }
</style>

</my-tag>

※追記 2015/2/25: プルリクエスト送りました。

※追記 2015/2/27: マージされました。

Riot 2.0

v2.0.12 - With scoped CSS support...


結語

オブジェクト指向CSSとか、CSSに無茶な要求が多い昨今、問題の多くはCSSがDOMから遠すぎるところにありました。その点、Scoped CSSを使うと、「DOMにスタイルをベタ書き」するのに近いことができます。コンポーネントとの組み合わせが最強ですね。

水平分業が進みすぎたWeb界隈に、垂直統合の嵐が吹き荒れてますが、CSSから考えるときはScoped CSSがその最初の一手になりそうです。