all, initial, unsetでCSSのリセットと継承回避をする

追記(2018年4月13日):紹介した機能の実装が進みました(Can I use:allプロパティinitialunset)。

一方で文中で取り上げたScoped Stylesheetsは仕様から削除されてしまいました。


このエントリはCSS Property Advent Calendar 2013の10日目のものです。
すみませんすみません日付勘違いしてました。ほんと申し訳ありません……

今回はradial-gradient()のMixin…は作りません。プロパティじゃないしね。ふつうのプロパティと値についてご紹介しようかと。

CSS Cascading & Inheritanceのall, initial, unset

Firefox 27あたりからallプロパティとunset値なんてものが実装されました。CSSCascading and Inheritanceモジュールで定義されてるんですが、これを使うとスタイルを局所的にリセットできます。実装したMozillaのCameronのエントリが詳しいです。

allは「すべてのプロパティ(※ただしdirectionunicode-bidiを除く)」を指します。すべて(※)です。これから定義・実装されるプロパティもすべてallになります(※)。ターンAみたいですね。

initial, unsetCSSワイドな値です。initialは初期値(を指定値にする)値で、結構前からいろんなブラウザで実装されています。inheritというのもあります。これは継承値を指定値かつ算出値にするものです。unsetというのはその間の子で、継承するプロパティ(font-sizeやらcolorやら)についてはinherit, そうでないものにはinitialという扱いになります。unsetユースケースがいまいちわからず、昔何かで読んだ気がするのですが忘れました。とりあえず次に進みます。

スタイルをリセットしたい?

スタイルをリセットしたい場合って、今のところそんなあるようなないようなですが、かなり個人的な背景からそう思うときは多々あります。

たとえば、HTMLとCSSの講演スライド。スライド作成ソフトと比べるとまだあんま良くないと思っているのですが、スライド中にWebコンテントを直接埋め込める利点があります。とくにHTMLやCSSについてお話させてもらうので、実際のコンテンツを埋め込めると楽です。

埋め込みというと、外部コンテンツを<iframe>で読み込むという手もありますが、複数ファイル作るのが面倒な例などは、インラインで直接書きたいものです。

<div class="example">
  <!-- サンプルコードがここに入る -->
</div>

とはいえ、ここで面倒なのが、div.example内のコンテンツが親のスタイルを継承してしまうこと。スライドのスタイルは10-feet UIといいますか、背景と前景のコントラストをなるべくとる、文字は大きくするなど、デスクトップスクリーンとはまた違う流儀があります。サンプルがどんなものかにもよりますが、そういったスタイルが継承されると上書きすることが面倒です。サンプルはシンプルにゼロから始めたい。ここでallinitialが役立ちます。

<div class="example">
  <style scoped>
    * { all: initial }
  </style>
  <!-- サンプルコードがここに入る -->
</div>

<style scoped>を入れてdiv.exampleだけに対応するスタイルを書けるようにします。そして最初でall: initialでスタイルをキャンセルすることにより、div.exampleが親からのスタイルを継承しないようにします。

親のスタイルを一部継承したい場合はall: unsetでもいいかもしれません。

displayinlineになるのがだるいですね…プロパティごとにinitialのがいいかもなあ。

Scoped Stylesheetsの危機

HTML+CSSなスライドで例をインラインで書きたい、というあまりにもニッチなユースケースですが、all, initial unsetの便利さをお分かりいただけたでしょうか。無理かなあ。

さて、実装が進めば素敵なHTML+CSSなスライドライフをおくれそうですが、現在Scoped Stylesheetsを消さないかという話が出ていたりします。もともとHTML5でat riskな機能で、現在もFirefoxでしかリリースされてません。そんな中blink-devで削除しないという話がでてしまい、あまりいい具合ではありません。Hixieは制作者の要望が大きいことを述べていますが、大きく反対しているわけでもなく、しばらく放置されそう。HTML5からは削除されるかな。

<style scoped>を使わずとも、スコープさせたい要素の親にidでもふってやればいいのですが、サンプルコードまわりをひとまとめにしときたいんだよなあ。