0の値の場合に短い単位を採用するという処理は単純に実装できるが、0でない値の場合はそれなりに面倒くさい。単純に考えれば愚直に単位の変換を行い一番短いものを採用するという形で良いが、それだとかなりコストがかかるだろう。つまり変換すると短くなるケースをある程度想定しなければならない。

時間

時間はs単位とms単位のどちらで書いてもあまり長さは変わらない。s単位の方が単位自体は短いものの、s単位で時間を指定する場合は概ね小数点を書く必要があるので、その優位点はほぼないと言って良いだろう。ただ場合によってはs単位の方が短くなる可能性がある。それはms単位を使った値の末尾が0の場合だ。

.test {
  transition-duration: 210ms;
}

は、

.test {
  transition-duration: .21s;
}

の方が1文字短い。末尾の0を省略できるというわけだ。00で終わっていると、なんと2文字も短くなる。

例外としては10msのようにs単位にすると小数点だけでなく桁埋めの0が必要になるケースだ。この場合はms単位のままでも長さは変わらないので、処理するのは無駄ということになる。ms単位の値が3桁以上、かつ0で終わる場合に限って変換すれば良いだろう。

角度

角度はrad単位とturn単位は短くなる可能性はあまりない(後述)。deg単位は小数点が必要なく、概ね短くなりやすいので、これまた変換する必要はない。つまり短くなる可能性が高いのはgrad単位だけになる。

grad単位は400で一周する。つまり400grad360degと等しいわけだ。小数の場合は変換すると問題が起こりそうなので、実際には整数の値を持つgrad単位のことだけを考えれば良いだろう。短くなるパターンを頭の中だけで考えてみるのも難しいので、愚直に調査することにした。以下はdeg単位に変換した方が短くなった場合のみ列挙するコードだ。

i / 400 * 360という計算式だとi70の時に62.99999999999999を返してしまうので、先にきれいに割れる除算をし、それを乗算するようにしている。

var deg;
var grad;

for (var i = 0; i <=400; i++) {
  grad = i + "grad";
  deg = (i * (360 / 400)) + "deg";

  if (deg.length < grad.length) {
    console.log(grad, deg);
  }
}
$ node test.js
10grad 9deg
20grad 18deg
...
390grad 351deg
400grad 360deg

つまりgrad単位の値が10の倍数の時、deg単位でも整数になり、単位の短さのおかげで1文字短くなるようだ。

例外はこちらにもある。それは360deg1200gradのような場合だ。この場合はturn単位を使うと1turnなり3turnなり書けるため、何文字かの節約になる。

ベースが円周率であるrad単位ではどう書かれていてもどう計算しても小数点以下が多くなるので、うまく短くなることはないだろう。turn単位に関しては.25turn90degへと短く変換できる。小数点以下3桁までに限って整数のdeg単位に変換できる場合はそうする、というのが良さそうだ……と、ここまで考えてturn単位はサポートが怪しい(Android 2辺りが危険)ことがわかった。先の整数のパターンも含めて、このturn単位へ変換するのはまずいようだ。


どちらも効果が高いものではないが、普通に書いてしまう600msなどを.6sへ変換してくれるのはそれなりに意義はあるだろう。CSSを書くにあたっては常にms単位やdeg単位を使い、安全に短くするのはツールに任せるというのは論理的に正しい処世術であるはずだからだ。

もう少し寝かせたらCSSWringへ取り込むことにした。多少、想定が甘いところがあるようなので、もう少し見守ってやる必要がありそうだ。