CSSにデータを埋め込む方法を考えてみた(CSS2KB)

ここ最近 DOM + CSS + JavaScriptWidget を作ってます。タブとかスライダーとかです。
Wiget の見栄えを切り替える方法(テーマ)も実装してますが、CSS とテーマ情報を格納するファイルが、別々のファイル(CSS + js)に分かれてしまうので、どうにかしてこれらを一元管理できないもんかと考えてました。

今日は、list-style-image: や background-image: の URL(QueryString) に定数を埋め込む方法を思いついたので、その説明です。

list-style-image: url(1dot.gif?key=val) の key=val が取り出せるか試してみる

<!doctype html><html><head><title></title>
<style>
.widget { list-style-image: url(1dot.gif?key=val;key2=val2;key3=val3); }
</style>
<script src="uu.js"></script>
<script src="uu.css.js"></script>
<script>
function uuboot(uu) {
  var node = uu.id("widget-info");

  if (node) {
    uu.puff(uu.qs(uu.trim.url(uu.css(node).listStyleImage))); // {"key":"val","key2":"val2","key3":"val3"}
  }
}
</script>
</head><body>
<div id="widget-info" class="widget"></div>
</body></html>

IE, Opera, Safari, Google ChromeCSS に埋め込んだ情報 { key: "val", key2: "val2", key3: "val3" } を取得できました。
background-image: でも同様に取得できます。

ポイント
  • 1dot.gif は実在する 1px の透明な画像。実在しないと getComputedStyle().listStyleImage が "none" になってしまう。
  • div 要素でも、list-style-image: の値は保持されている(当然といえば当然)
  • 文脈に不要な要素 <div id="widget-info" class="widget"></div> が邪魔なら、動的に生成してパラメタ取得後に削除すればOK(リフローも発生しない)
<!doctype html><html><head><title></title>
<style>
.widget { background: url(1dot.gif?key=val;key2=val2;key3=val3); } /* 今回は background で */
</style>
<script src="uu.js"></script>
<script src="uu.css.js"></script>
<script>
function uuboot(uu) {
  var p, qs;

  uu.body(p = uu.p("class,widget")); // <p class="widget"> を作成し <body> に追加
  qs = uu.qs(uu.bgimg(p)); // background-image から QueryString を取得しパース
  uu.node.sub(p); // <body> から <p class="widget"> を削除

  uu.puff(qs); // qs を JSON {"key":"val","key2":"val2","key3":"val3"} で表示
}
</script>
</head><body></body></html>

えーと

  • ググっても見つけられなかったけど、既出のアプローチなのかも
    • 誰でもすぐ思い付きそうなアイデアだもんね
  • data: スキームを工夫すれば、ダミーの画像(1dot.gif)が不要になるかも
  • IE には URL の長さが 2k までという制限 がある
  • QueryString に利用できない文字(# +?=;&等)は、encodeURIComponent と decodeURIComponent の組み合わせで回避
    • または、uu.codec.js の URLSafe64(base64の亜種)でイケル

何がうれしいか

  • CSS に定数を大量に埋め込むことができる。
    • list-style-image と background-image を同時に使うと 2k + 2k = 4k のデータが埋め込める。
      • 識別子(ID や クラス)を複数用意すれば、データ量の制限も無くなる。
  • キャッシュされる(うれしくない場合もありそうだけど)

名前が無いと時々困る

CSS に 2kB 単位でデータをぶちこむ」から CSS2KB なんてどうだろう?