CSS Programming Advent Calendar 2012の20日目の記事でCSS Maskingについて書きました。
その中でAndroidには不具合があるんだよね…っていうのを最後の方で紹介したとき、
参考としてリンクしていたのは@mattari_pandaさんが書いた Android4でmask-imageとアニメーションを同時に設定するとマスクしなくなる というデモでした。
でもよく調べてみたらそれだけじゃなかったんです。
検証するにあたって書いたデモはこれです。
以下の内容はReadmeと一部被ります。
Androidでの症状
mask-imageとanimationを同時に設定するとマスクしなくなる(Android4のみ)
症状が出るのは3つ目のドロイド君です。
mask-imageとanimationを同時に設定した場合はアニメーション対象のプロパティに関係なくマスクが効かなくなります。
mask-imageとtransitionは同時に設定してもマスクが維持されます。
mask-imageの効果がかかる要素にtransformプロパティをアニメーションさせるスタイルが指定されているとマスクしなくなる
5番目のmask+transform、6番目のmask+transition(bgcolor)は正常に動くが、
7番目のmask+transition(transformX)だとマスクが切れます。
同様に、mask-imageを指定した要素の子要素にtransition(bgcolor)を設定した12番目は正常に動くが、
transition(transform:scale)を設定した11番目はマスクが切れます。
transition(transform)またはanimation(transform)でマスクが切れるとマスクを使っている他の要素にも影響を及ぼす
Android2.3の場合はtransitionが終わったらマスクが復活するが、Android4の場合は復活しない。
道連れにする範囲は2.3は後に続く要素のみ、4は前後関係なく道連れにします。
ただこのとき、2番目のドロイド君のマスクは切れなかったので何かしら条件があるのかもしれません。
デモは各ドロイド君をsectionに入れているので、DOM構造は関係なしでレンダリング中のマスクすべてを道連れにすると考えた方がよさそう。
-webkit-backface-visibilityとtransformが設定された要素があるとマスクが切れる
transformだけ、backface-visibilityだけ設定された要素がある場合は変化なしだが、
両方セットした要素があるとマスクが切れる。
対策というか回避策
mask-imageの効果がかかる要素にtransformプロパティを使用する場合は、transitionやanimationを併用しない
mask-imageを設定している要素だけでなく、その影響を受ける子要素もだめです。
mask-imageの効果がかかる要素にtransitionやainmationを使用するなら、transform以外のプロパティにする
translateXならleftにするとか。
Androidでちらつくのをあきらめる
backface-visibilityとtransformの不具合は、mask-imageをとるかちらつきを押さえるおまじないをとるか、という感じ。
Canvasにする
アニメーションが重要なのであればCanvasにした方が手っ取り早いかもしれません。
Androidを買おうとしている人を見かけたら、iPhoneを勧める
既にAndroidを買っちゃった人でもiPhoneを見せたら乗り換えてくれるかも。
mask-image+border-radius
mask-imageを設定している要素にborder-radiusを使用した場合にもマスクされません。
Androidの不具合の多さは今に始まったことじゃないけどまあ酷いもんですね。