style属性でzoomを指定すると特定の状況でzoomが無効になる

Advent Calendar
CSS

CSS 珍百景 Advent Calendar 20145日目のエントリ。

こちらでの再現ブラウザは Google Chrome 39.0.2171.71 と iOS 7.1.2 Mobile Safari。状況を詳しく説明すると、外部 CSS ファイル、及び style タグで zoom プロパティがすでに設定してある要素に対して、CSS で指定されている zoom 値と同じ値を style 属性で指定すると zoom が効かなくなるというもの。

style 属性で指定する zoom 値を変更できるデモを用意した。テキストエリアに数字を入れて隣の add ボタンを押すとその下の要素にstyle="zoom: N"が付与されるようになっている。背景に 50px ごとのグリッドになっている画像を敷いたので、倍率が少しわかりやすいと思う。ページを開いた時の初期表示では CSS 側のzoom: 2;が効いているはず。

DevTools を開いて要素の style 属性を確認しながら、まずは数値を 2 にして add ボタンと remove ボタンを押してみて欲しい。zoom が style 属性でつくと拡大が無効になり、消すと拡大されるのがわかると思う。add したのに大きくならない。remove したのに大きくなる。同値での上書きなので表示サイズは変化しないでそのままになるはずだ。数値を 2 以外(2.0001 なども可)にすれば動作は期待通りになる。同じ値の操作の時のみ、珍事が起きる。

少々重いがGif アニメを用意したので、再現できない人はこちらを見てほしい。

そもそも同じ値を style 属性で指定するシチュエーションなんてほぼない。業務で端末の画面サイズから倍率を算出して上書きする必要があって、JS 実装のミスで必要がない端末でも上書きがかかったところ、拡大されなくなっているのを見てこのバグに気づいた。IE11 では再現しなかったし、zoom プロパティ未実装の Firefox でも当然起こらない。

気づいたのは 2 つか 3 つバージョンが前の Chrome でだけど、iOS 7.1.2 Mobile Safari でも再現するのを見るに、もしかしたら Chrome が Blink になる前から Webkit の珍挙動として存在していたかもしれない。ちなみに、transform: scale();なら style 属性による上書きは問題なく行える。

zoom こわい。