せめてWebKitに実装されてからとか思ってたけど、CSS Image Values and Replaced Content Module Level 3がLast Callになったのでいい機会ということにしてelement()関数についてエントリを書く。element()関数は任意のIDを引数に取ることができ、その要素を画像として参照できるというなかなかの荒業な関数。具体的には画像のサムネイルを簡単に作成できるとかそういうものをイメージするとわかりやすいと思う。

Demo: Filmstrip View

いわゆる「フィルムストリップ」のようなものを作るデモだけど、element()はまだFirefox 4以降でしかサポートされていないので、ChromeやSafariなどでは意図した通りに動かない。Firefoxなら下に並んだサムネイルをクリックすると大きな画像が表示される。切り替えやアニメーションについてはelement()の力ではなく、:target擬似クラスの力なので特に解説はしない。

element()では既に書いたようにIDで参照する。

.test {
  background-image: element(#foo);
  background-size: contain;
}

Firefoxでも完全な実装ではなく、背景でしか使えないように制限されているので、今のところはこういった使い方になるだろう(list-style-imagecontentプロパティーで使えるようになると便利そう)。サムネイル化する場合に限らずそのままのサイズで表示しようということはまずないと思うので、background-sizeプロパティーを使ってサイズを調整してやると良い。containで納まるように調節してくれるはずなので、大体はこれだけで意図した通りに表示されるだろう(勿論.testへの幅と高さの指定は必要)。

ただレンダリングされていない要素は参照しても表示されない。

#foo {
  display: none;
}

.test {
  background-image: element(#foo);
  background-size: contain;
}

displayに限らず、visibilityheightプロパティーで見えなくしても同様に表示されない。デモではどうやっているかというと、positionプロパティーで見えない位置に吹っ飛ばすことによって元画像は隠すがサムネイルは見えるようにしている。

#foo {
  position: absolute;
  top: -100%;
}

.test {
  background-image: element(#foo);
  background-size: contain;
}

つまりレンダリングはされるものの見えないような状態を工夫すれば良いわけで、ネガティブ・マージンなどでも可能。

参照先、つまり引数に指定したIDを持つ要素は画像である必要は無いので、Webページ全体のプレビューを右に表示するなどということもできる。表示しているエリアをハイライトするような感じになれば実用性は有りそうだけど、CSSだけでうまくやる方法は思いつかなかった。描画エリア内のみを覆う白いレイヤーを最背面に配置して、他は暗くするとかやってみたけどelement()で作られた画像は全部白くなってしまった。実装の不備かそういう仕様なのかはわからない。単に表示するだけのもの、例えば印刷プレビュー的なものなら結構簡単に作れるんじゃないかと思う(CSSを丸ごと差し替えるだけ)。

さっさと他のブラウザも実装しろやみたいな。あとこの関数名の検索ビリティの低さは異常なので、どうにかならなかったのかとかちょっと思ってる。

追記

最後にちょっと書いたWebページのプレビューで表示しているところをハイライトはbackground-attachment: fixedでいけると@xl1blueが考えてくれた。思いつかなかった。なんかに使えそう。