下記のように、画像を決まったサイズ(今回であれば正方形)で表示させたいときのtipsです。
サーバー側で画像を生成するのではなく、どんな画像サイズがくるか分からない状況でフロント側で実装する場合を想定しています。
上記のような横長の画像を正方形にしたい場合、こうなります。
sample.css
/* 通常 */
.sample__img {
width: 400px;
height: 400px;
}
/* 外接リサイズ */
.sample__fit-img {
width: 400px;
height: 400px;
object-fit: cover;
}
widthとheightを指定しただけでは、画像がゆがんでしまいますね・・
上記のように object-fit: cover
をすると一発で外接リサイズが実現します。
ただ、対応しているブラウザが一部になります。
もっとブラウザ対応させたい!というときは background-size: cover
を使います。
sample.html
<div class="sample__fit-img"></div>
sample.css
.sample__fit-img {
background-image: url(https://cdn.pixabay.com/photo/2019/05/12/20/45/cat-4199084_960_720.jpg)
background-size: cover; /* 外接リサイズ */
background-repeat: no-repeat; /* リピートするか */
background-position: center; /* 位置 */
}
ちなみに上記の実装だと背景画像とみなされるので
印刷しようと思っても表示されないので注意。ブラウザ対応をとるか、どっちかですね・・!
こちらで同じような議論がされていて面白かったです。
* How do I prevent the error "Index signature of object type implicitly has an 'any' type" when compiling typescript with noImplicitAny flag enabled? - Stack Overflow
おまけ(VueでIE対応可能な外接リサイズ用のコンポーネントを作る)
ObjectFitImg.vue
<template>
<div :style="style" class="object-fit-img">
<span v-if="alt" class="object-fit-img__alt">{{ alt }}</span>
</div>
</template>
<script lang="ts">
import { Component, Vue, Prop } from 'vue-property-decorator';
interface ObjectFitStyle {
width: string;
height: string;
'background-image': string;
[key: string]: string | null;
}
@Component
export default class ObjectFitImg extends Vue {
@Prop({ required: true }) readonly src!: string;
@Prop({ required: true }) readonly alt!: string;
@Prop({ default: null }) readonly width!: string;
@Prop({ default: null }) readonly height!: string;
get style(): ObjectFitStyle {
const style: ObjectFitStyle = {
width: '',
height: '',
'background-image': ''
};
style.width = this.width ? `${this.width}px` : '';
style.height = this.height ? `${this.height}px` : '';
style['background-image'] = `url(${this.src})`;
return style;
}
}
</script>
<style lang="scss" scoped>
.object-fit-img {
background-repeat: no-repeat;
background-position: center;
background-size: cover;
&__alt {
visibility: hidden;
}
}
</style>
ここまで書いてなんですが、個人的にはIEを捨てて object-fit: cover
でいい気がします笑