coder's log

コーダー日誌

[CSS]正方形ではない画像を正方形のエリアに表示する+正円も

公開日:2019/11/01

ちょっと何言ってるかわからない・・・とは言わないで。

正方形にこだわらなくてもいいんですけど、とにかく正方形枠内に画像を表示させるデザインがあったとします。
で、実際に表示させる画像は縦長、横長、正方形が混在していて、縦横比率(アスペクト比)もまちまちなので、下のように縦横比を保ったまま縦方向か横方向に目一杯表示させ、枠内の中央に配置させる要件です。

  • object-fitプロパティに対応していない古いバージョンのブラウザ(IE11含む)では、画像が枠内いっぱいに表示されます。IE以外かつobject-fitプロパティに対応しているブラウザで御覧ください。
  • ここで使用している画像は以下を参照。画像の使用はリンク先の利用規約に従ってください(日本語の説明がないので以下の記事も参考にしてください)。

画像を正方形にトリミングして提供していただくのが一番良いのでしょうが、毎日どころか数時間おき、数分おきに更新されるようなサイトでは、いちいちトリミングするのも現実的ではなかったりします。
ニュースサイトの報道写真やECサイトの商品写真のサムネイルなどを想像してもらうとわかりやすいかと思います。

ニュースサイトはjsonなどのデータを自動でテンプレートに流し込んで表示させていたりします。
データの中に画像の縦横サイズが入っていたりもしますが、いちいち判定しなくても表示できたらいいですよね。

まずは画像を正方形にする

widthとheihgt両方に300pxといった数値を絶対指定すれば、正方形にはなるんですが・・・。
問題はレスポンシブ対応にしたいときです。

親要素に対して幅を30%にしたいとか、そういう場合、heightにも30%を設定したところで正方形になるとは限りません(親要素が正方形で、他の要素に影響されたりしないなどの条件が整えば正方形になるでしょうけども)。

  • IEのようにobject-fitプロパティに対応していないブラウザでは上のように見えていると思います。

htmlは以下のような構造になっています(長くなるのでliは1個に省略しています)。
親要素>imgという構造になっていれば、使用タグの制限は特にありません。

<ul class="img_fit">
    <li>
        <p><img src="画像ファイルのパス" alt="画像の説明"></p>
        <div>コンテンツ</div>
    </li>
</ul>

cssは以下のような感じです。
ulのflexboxやliの幅などの設定は省略しています。

.img_fit > p{ position: relative; }
.img_fit > p::before{
    display: block;
    content: '';
    padding-top: 100%;
}
.img_fit > p > img{
    position: absolute;
    top: 0;
    width: 100%;
    height: 100%;
    border: solid 1px #999;
}

ポイントはimgの親要素のbefore疑似要素にpadding-top: 100%を設定している点とimgのwidthとheightに100%を設定している点でしょうか。
さらにpositionによる位置調整をしていますが、これで親要素の幅に合わせてimgの表示領域が正方形を維持したまま可変できます。

marginやpaddingに%を設定したとき、親要素の幅が基準になるということがミソらしいです。
下のリンクが詳しいので、参考にしてみてください。

object-fitで画像をフィットさせる

ここまでくれば、あとはimgにobject-fit: containを追加するだけです。
object-fitは背景画像を設定するときに使うbackground-sizeのような感じでimgの設定ができます。

.img_fit > p > img{
    object-fit: contain;
    background:#ddd;
}

空いた部分が寂しい感じがするのであれば、背景を入れてみるのも良いかもしれません。

ここで設定したcontain以外にも値があります。
下のリンクが詳しいので、参考にしてみてください。IEでも同様の表示にする方法もあります。

例えば、object-fitをcoverにして、border-radius: 100%を追加すると、下のように正円にトリミングされたみたいになります。

.img_fit > p > img{
    object-fit: cover;
    border-radius: 100%;
}
更新記録
  • 2019/11/17 画像とリンク先がマッチしていなかったのを修正

Top

go to homeindex