CSS アスペクト比を変えないで画像貼り付け

画像
こんな画像があるとする。これを正方形のエリアに特に何も考えずに貼り付ける(次)。

画像

縦横300pxのボックス要素に高さ・幅それぞれ100%指定で画像を貼り付けた。

1
2
3
<div style="width:300px; height:300px">
<img src="/images/example.webp" style="width:100%; height:100%;" alt="画像" />
</div>

横長の画像を正方形に無理やり押し込めたので当然ながら横方向が潰れた(アスペクト比が狂った)変な画像になる。不自然すぎるのでワザとでなければ一番ダメな表示方法といえる。

画像

縦横300pxのボックス要素に幅AUTO・高さ100%指定で画像を貼り付けた。

1
2
3
<div style="width:300px; height:300px;">
<img src="/images/example.webp" style="width:auto; height:100%;" alt="画像" />
</div>

アスペクト比は正しいが横長の画像を正方形に収めると画像の上下(上の例では画像の下側)に無駄なエリアが出来るのと画像がとても小さく見えるので迫力がなくなる。

じゃあ、高さは100%で画像の左右を切り取ってアスペクト比を崩さないようにすりゃいいじゃんってなるんだけど、以前はCSSだけでは結構面倒だった。今はかなり簡単になっているけど意外に使われていないかなというのがこの記事。
で、お約束っちゃあお約束だがIEはここから下の全てが正常に表示されない。

画像

縦横300pxのボックス要素にoverflow: hidden;で溢れた部分を非表示化、高さ100%・幅AUTO指定で画像を貼り付けた。

1
2
3
<div style="width:300px; height:300px; overflow: hidden;">
<img src="/images/example.webp" style="width:auto; height:100%;" alt="画像" />
</div>

これだと元画像の左端しか表示されない筈。

画像

つまり親要素側のoverflow:hiddenを外すと実際にはこうなっている。

画像

縦横300pxのボックス要素にoverflow: hidden;で溢れた部分を非表示化、高さ100%・幅AUTO指定で画像を貼り付けた。その時、画像側にposition:relativeとright:121pxつまり right:calc(本来の画像表示幅 - 表示幅300px) / 2を追加して画像の中央が表示されるようにする。

1
2
3
<div style="width:300px; height:300px; overflow: hidden;">
<img src="/images/example.webp" style="width:auto; height:100%; position:relative; right:calc((543px - 300px) / 2);" alt="画像" />
</div>

画像

親要素側のoverflow:hiddenを外すとこんな感じに切り抜いている。

ここまでは以前からあった方法だけどちょっと面倒くさい。
そこでCSS3で追加されたobject-fit。
で、Edgeはここから下は全て正常に表示されない。

画像
画像を縦横300pxで表示。object-fit:coverを追加。これだけ。

<img src="/images/example.webp" style="width:300px; height:300px; object-fit: cover;" alt="画像" />
自動的に画像の真ん中が表示されるのはありがたいが、逆に画像中の任意の位置を指定したいならobject-positionを追加する。

画像
画像の右端を表示してみた。object-position: 100% 0%;  (左右の位置, 上下の位置)

<img src="/images/example.webp" style="width:300px; height:300px; object-fit: cover; object-position: 100% 0%;" alt="画像" />

ところで、object-fitがcover以外の値だとどうなるか。(以下)

画像
object-fit: fill
アスペクト比を変更して指定範囲に合わせて表示する。この記事2番めの画像(ダメな例)と同じ。

<img src="/images/example.webp" style="width:300px; height:300px; object-fit: fill;" alt="画像" />

画像
object-fit: contain
指定範囲に画像全体が表示される。つまり指定範囲に画像全体が入るまで拡大・縮小される。

<img src="/images/example.webp" style="width:300px; height:300px; object-fit: contain;" alt="画像" />

画像
object-fit: none
画像を拡大縮小させないで指定範囲に表示させる。

<img src="/images/example.webp" style="width:300px; height:300px; object-fit: none;" alt="画像" />

画像
object-fit: scale-down
containかnoneのどちらか小さい方の要素が表示される。

<img src="/images/example.webp" style="width:300px; height:300px; object-fit: scale-down;" alt="画像" />

cssに馴染みがなくても使えるほど簡単で素晴らしいと思うのだが、例によって世紀の糞ブラウザ(IE,Edge)が対応していないのでそこだけ注意。というか、そのせいで普及してないのだろうけど。

スマホのブラウザでさえ表示できるものがPCのブラウザでできないってホントIE,Edgeは終わってるとしか言いようがない。