JavaScriptの激変は、CSSコーダー(?)にとっても対岸の火事ではありません。むしろ、変態的な職人的な方法論を捨て去らなきゃならないのは、CSSも同じ。
それはともかく、Scoped CSSについて整理しつつメモしてみます。※2015年初頭の状況として
なにこれ?
Scoped CSSはDOMの中に<style scoped>
タグを配置すると、そのDOMの内側にだけに限定されるCSSが書けるというものです。アイデア自体はしばらく前から存在するものの、Firefoxにのみ実装され、Chromeについては実装が止まっています。経緯を追うと、Web ComponentsのShadow DOMのCSSがscoped
相当になるため「重複機能」と判断され、ペンディングになっている気配です。(ChromeとしてはWeb Componentsの仕様固めが優先)
- 仕様: whatwg.org
- ブラウザ対応状況: Can I use?
- Mozilla Developer Network
なにが嬉しいのか
それだからこそ、Web Componentsに取り込まれているわけですが、対応できればAngularやReactでもCSSを書くのが楽になります。Web Componentsにさっさと昇華するのか、Scoped CSSとして日の目を見るのかはさておき、考え方自体は今後のCSSで標準になるでしょう。真面目な話、CSSの方法論がどんがらがっしゃんする寸前の2015年です。
SMACSS使いなら、(CSSの)モジュールに分けていたはずですが、それぞれのコンポーネント内に記述を移し、base
やtheme
だけメインのCSSに残せばOK。移行はそれほど難しくないはず。BEMな人なら「__」の前(ブロック)を書く必要がなくなるといえば通じるでしょうか?
Polyfills
ブラウザ対応が限られる一方、案外Polyfillは充実しています。
- Vanilla JavaScript polyfill for scoped style
- jQuery Scoped CSS plugin
- Polymer: Handling scoped styles
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: マージされました。
v2.0.12 - With scoped CSS support...
結語
オブジェクト指向CSSとか、CSSに無茶な要求が多い昨今、問題の多くはCSSがDOMから遠すぎるところにありました。その点、Scoped CSSを使うと、「DOMにスタイルをベタ書き」するのに近いことができます。コンポーネントとの組み合わせが最強ですね。
水平分業が進みすぎたWeb界隈に、垂直統合の嵐が吹き荒れてますが、CSSから考えるときはScoped CSSがその最初の一手になりそうです。