[css]:hoverで拡大するときにボケたりカクついたりを防ぐ

ある意味で転換期なのだという理解。

今までの形(といっていいのか?)

例として。

<div class="img"><img src="https://placehold.jp/150x150.png" alt="test"></div>

こんなのがあったとして、カーソルを合わせたら中の画像が中央起点で拡大するように以下の感じでcssを組んだとする。

.img{
    width: 150px;
    height: 150px;
    position: relative;
    overflow: hidden;
}
.img img{
    width: 150px;
    height: auto;
    margin-top: -75px;
    margin-left: -75px;
    display: block;
    position: absolute;
    top: 50%;
    left: 50%;
    transition: width 0.5s;
}
.img img:hover{
    width: 170px;
}

動くんだけど、画像がジャギったりボケたり、動きがカクついたりする。環境によるかもしれないけどWindows10のChromeだとそうなる。

transformを使う

transformでも同様の動作は組めて、そうするとカクつきが解消される。された。

.img{
    width: 150px;
    height: 150px;
    position: relative;
    overflow: hidden;
}
.img img{
    width: 100%;
    height: auto;
    display: block;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
    transition: transform 0.5s;
}
.img img:hover{
    transform: translate(-50%,-50%) scale(1.1,1.1);
}

サイズ変更はscaleだけど、translateも使えばmarginで実数値を使った調整をしなくてよくなるから便利。実数で指定していくのはめんどくさいからね。

だけど画像が荒れるのはそのままだったりする。

will-changeを使う

will-changeっていうのは処理の予約みたいなもんで、アポ無しよりもアポ取ったほうがいいよねをHTML上でやる。例えとして合ってるかわからないけど。とりあえず、いい感じになるやつ。

will-change - CSS: カスケーディングスタイルシート | MDN
CSS の will-change プロパティは、どのような要素の変更が予測されているかブラウザーに助言します。ブラウザーは要素が実際に変更される前に、最適化をセットアップすることができます。

この場合拡大するのはimgなので、imgに書く。transformで変化させるからtransformを指定する。

.img img{
    width: 100%;
    height: auto;
    display: block;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
    transition: transform 0.5s;
    will-change: transform;
}

これで画像の荒れがなくなる。

応用というか

:hoverに限らずkeyframesでも同様なので、同じ感じに組めばいい。

まとめというか

カーソルを当てたときにコンテンツが変化すると、カーソル自体が変化するだけに比べてクリック要素だと分かりやすくなったりする。だけど、スマホとかタブレットだと直接タップするから、カーソルを合わせる概念がないんで、:hoverで素敵なギミックを仕込んでも意味がない。長押ししてたら:hover扱いになったりするけど右クリック的な動作になるし、ほぼ死んだも同然。

程々にするのがいいと思う。

コメント

タイトルとURLをコピーしました