今だからこそ使いたい!主要ブラウザで標準化された拡大レベル調整用のプロパティ「zoom」を使ってみよう

こんにちは、ユアサです。
今回は使い所が色々あり便利そうだった、古くからあるプロパティzoomについてまとめたいと思います。

なぜわざわざこの話?

お恥ずかしながら自分は最近になってこのプロパティの存在を知りまして、話を聞いたり調べたりしたところ、どうやらまだIEが主流ブラウザだった時代に使われていたこともしばしばあったそうですね。
しかしこの古のプロパティは長らく主要ブラウザで対応されず、これ自体の使用が非推奨だったようです。なんとも不遇。

そんなzoomですが、Baseline2024においてついに主要ブラウザで使用可能になりました。Can i useでどのような具合か見てみます。

zoomプロパティの使用可能ブラウザ

当たり前ですが一応問題ないですね。ひとまず標準化したばかりなので動作の様子を伺いながらの使用が良さそう、といったところでしょうか。
実際に触ってみてなかなか使い勝手が良かったので、備忘録も兼ねて(毎回備忘録を兼ねている気もしますが)このzoomの仕様について記事にする流れに至りました。

zoomの主な使い方

ご存知の方の方が多いかと思いますが、zoomは要素の拡大レベルを調整できるプロパティです。現在のサイズを参照する割合での調整になるので、直感的に拡大・縮小のサイズを決めることができます。
zoomを付与する前後のセクションを作成してみたので、試しに動作を見てみます。

See the Pen zoom-tutorial by felly (@felly00505) on CodePen.

今回はzoomの値を0.75として付与してみました。いわゆる1倍サイズの表記だとzoom: 1;あるいはzoom: 100%;(または初期値であるzoom: normal;でも可)となるので、今回の場合は0.75倍(zoom: 75%;でも再現可)のサイズに縮小されました。

上記コードの表示を見て分かる通り、付与された要素とその中の子要素全てに影響します。特定の子要素だけ調整したい場合はその子要素にのみ付与すればOKです。

transformのscaleとの棲み分け

要素の拡大・縮小でおそらくメジャーに使用されているのはtransformプロパティのscaleかと思いますが、実はzoomとは挙動が異なります。
実際に見ていただいた方が早いと思うのでコードをご覧ください。

See the Pen zoom-tf_scale by felly (@felly00505) on CodePen.

それぞれどのような挙動をするのか分かりやすくするため、各親要素にグレーの枠を設けました。どちらも0.75倍サイズを想定していますが、一目瞭然でその違いが分かるかと思います。
どちらも元のサイズを参照した0.75倍であることには違いないのですが、transform: scale();が他のレイアウトに影響を与えず縮小するのに対し、zoomは要素そのもののサイズを縮小(他のレイアウトに影響を与えて縮小)しています。

ここが結構注意しておきたいポイントで、それぞれの挙動には使い所がはっきりと分かれています。

zoomの場合は仕様としてページのレイアウト前に計算をして調整するので、レスポンシブ対応する際にレイアウトの調整としてうってつけです。しかし例えばホバー時のアニメーションのような場合に使用してしまうと、全体のレイアウトのがたつきが生じてしまい視認性が悪くなります(そもそもレイアウトの再計算になってしまうのでアニメーションが効きません)。

レイアウトの変化に干渉しないtransform: scale();zoomとは真逆なので、まさにアニメーションなどの場面で適正があります。

See the Pen Untitled by felly (@felly00505) on CodePen.

同じようで実は全然違うこれらのプロパティは、適切に使用する場面がはっきり分かれているというわけですね。

zoomの計算結果の注意点

zoomプロパティはページのレイアウト前に計算しますが、この特徴を把握していないと期待通りの計算がされないパターンがあります。

See the Pen Untitled by felly (@felly00505) on CodePen.

上記コードではそれぞれ

  • 具体的な数値指定のサイズ(px単位で指定されている要素の大きさに対するzoom
  • フォントの大きさ(rem単位で指定されているフォントの大きさに対するzoom
  • %指定のサイズ(%単位で指定されている要素の大きさに対するzoom

の3つの条件でzoomプロパティがどのように計算結果を出すかを表しています。それぞれのzoomはどれもそれぞれの大きさに対する1.5倍サイズで調整したい狙いがあるとします。

まず具体的な数値指定のサイズにおけるzoomは、指定してある100pxを参照にしてその1.5倍のサイズで調整しているので狙い通りと言えるでしょう。

続いてrem指定のフォントの大きさにおけるzoomはどうでしょうか。1remと指定しているとはいえrem自身も結局デフォルトのフォントの大きさを参照している相対的な単位なので、zoomで計算できるのか何とも言えない気もします。
しかし上記コードの表示を見ると分かりますが、1remで参照しているデフォルトの大きさである16pxに対しての1.5倍サイズ、つまり24pxのサイズに拡大できているようです。こちらも狙い通りですね。

最後に%指定のサイズにおけるzoomですが、これは少し挙動が違うように見えます。
zoomを付与する前後の違いを分かりやすくするために敢えて横幅だけ%指定しましたが、表示を見る限りzoomが効いてそうなのはpx指定した縦幅のみです。横幅の50%は1.5倍されて75%になって欲しかったのですが、なぜ横幅だけ反映されないのでしょうか。

zoomは計算値・使用値の結果を描画直前で拡大・縮小します。前者2つの条件と違い、最後の条件であるwidth: 50%;はレイアウト計算に使う数値として持っていないのでzoomで1.5倍ができなかった、という流れになります。

まとめ

zoomプロパティの主な仕様についてご紹介しました。個人的には割合計算で調整される特徴が飲み込みやすく使いやすそうだったので、色々練習してみて使用感を確かめてみたいと思います。

arms inc. Engineers' Blogの次回の更新は5月14日(水)になります。