transformで文字がにじむ仕組み
transformで要素を動かしたり拡大したりすると、ブラウザはその要素を独立したレイヤーに切り出してGPUで合成することがあります。このとき、要素の位置がピクセルの境界にぴったり合わないと、文字の輪郭が複数のピクセルにまたがって描かれ、半透明にぼかしたようににじみます。
とくにscaleで拡大すると、もとの解像度のまま引き伸ばされるため、文字がぼやけやすくなります。translateで小数のピクセル分だけ移動した場合も、同様ににじみが出ることがあります。
scaleによる拡大とにじみ
ホバー時にカードを少し大きくする演出などでscale(1.05)のような指定をすると、その瞬間だけ文字がにじむことがあります。これは、拡大後のサイズに合わせて再レンダリングするのではなく、すでに描いた内容を引き伸ばすために起こります。
対処の一つは、拡大の演出をscaleではなく、最初から大きめに描いておいて縮小状態を初期値にする方法や、文字を含まない装飾部分だけをscaleで動かす方法です。文字そのものを拡大縮小の対象から外すと、にじみを避けやすくなります。
症状別チェック表
transformやscaleを使った要素の文字がにじむは、症状を分けずに直そうとすると原因探しが長引きます。まず「自分だけで起きるのか」「全員で起きるのか」「特定ブラウザだけか」「差し替え後だけか」を切り分けます。
確認順序を固定すると、相対パス、ファイル名、キャッシュ、認証、外部読み込みのどこで止まっているかが見えます。修正後はローカル確認だけで終わらせず、実際の共有URLで再表示して、相手と同じ条件で直ったことを確認します。
- 自分だけ表示されない: キャッシュ、ログイン状態、ブラウザ拡張、端末幅を確認する
- 全員で表示されない: ファイル構成、相対パス、大文字小文字、アップロード漏れを見る
- 一部だけ崩れる: CSS/画像/JSごとに読み込みエラーを分ける
- 差し替え後だけ古い: URL、キャッシュ、更新対象ファイルの取り違えを確認する
座標を整数に保つ・合成レイヤーを整理する
translateで動かす場合は、移動量を整数ピクセルに保つとにじみにくくなります。中央寄せでtranslate(-50%, -50%)を使うと要素サイズによっては小数になるため、要素の幅・高さを偶数にする、あるいはGridやFlexboxの中央寄せに置き換えると安定します。
また、will-changeやtransformで作られた合成レイヤーが残り続けると、にじみが固定化することがあります。アニメーションが終わったらwill-changeを外す、不要な3D変換を避けるなど、合成レイヤーを必要なときだけに絞ると改善します。
にじみを切り分けて直す手順
次の順で確認すると原因を絞り込めます。
- にじむ要素にscaleがかかっていないか確認し、文字部分を対象から外せないか検討する
- translateの移動量が小数になっていないか確認し、整数に揃える
- 中央寄せのtranslate(-50%,-50%)はFlex/Gridの中央寄せに置き換えられないか試す
- 要素の幅・高さを偶数にして半端な座標を避ける
- アニメーション終了後にwill-changeや不要な合成レイヤーを解除する
- 複数ブラウザの実機で、にじみが解消したか見比べる
ブラウザ差を共有URLで見比べる
文字のにじみは、ブラウザやOS、DPRによって出方が変わります。あるブラウザでは気にならないのに、別の環境でははっきりにじむ、ということが起こるため、複数環境での確認が重要です。
検証版をチームに見てもらうなら、ギガサイト便にHTMLやZIPをドロップして共有URLを発行すると、各自が手元のブラウザでにじみの有無を確かめられます。同じURLのまま中身を差し替えられるので、transformの値を調整するたびに見比べてもらえます。確認用ページにはnoindexが付いて検索結果に出ず、社外の協力者に見せる場合はメール認証や会社ドメイン認証を併用して相手を限定できます。
よくある質問
transformを使わずに同じ動きを実現できますか。
位置調整であればFlexboxやGridの中央寄せ、marginの調整で代替できる場合があります。ただしアニメーション性能の面ではtransformが有利なので、にじみが問題になる文字部分だけを対象から外し、装飾はtransformで動かす、といった使い分けが現実的です。
scaleで拡大した文字をくっきりさせる方法はありますか。
scaleは既存の描画を引き伸ばすため根本的にくっきりさせるのは難しいです。最初から大きいフォントサイズで描き、初期状態を縮小しておく、もしくは文字以外をscaleの対象にするほうが鮮明さを保てます。
will-changeを付けたままにすると何が起きますか。
will-changeは合成レイヤーを前もって確保しますが、付けたままだとメモリを消費し続け、にじみが固定化することもあります。アニメーションの直前に付与し、終わったら解除する運用にすると副作用を抑えられます。
特定のブラウザだけでにじみます。原因は何ですか。
サブピクセルレンダリングやGPU合成の挙動はブラウザやOSで異なるため、環境差でにじみの出方が変わります。座標を整数に保つ、合成レイヤーを減らすといった基本対処をしたうえで、問題が出る環境を実機で確認しながら調整するのが確実です。
原因が分からないときはどこから確認すべきですか?
まず自分だけの問題か全員の問題かを分けます。次にシークレットウィンドウ、別ブラウザ、スマホで確認し、ファイル構成・相対パス・キャッシュ・認証設定を順に見ます。