图片根据容器的大小自适应

前言

开发中,经常会遇到让图片自适应容器大小的场景,有时候图片尺寸和比列是不确定的。若只是简单的把图片的长和高设置为100%,可能会出现图片失真的情况。以下几种方法可实现图片根据容器的大小自适应。

图片1.png

第一种:通过max-width和max-height

将图片的 max-width 和 max-height 设置成100%

.img-box__img1 {
  max-width: 100%;
  max-height: 100%;
}

这个方法最为简单,但有一个缺点是,当图片尺寸较小或容器过大时,图片的长边和短边都无法填满容器,如下图所示:

图片2.png

第二种:通过背景图的方式

图片以背景图的形式展示,利用 background-size 属性,将其设置为 contain,在保持图片宽高比的前提下缩放图片,保证把图片扩展至最大尺寸,以使其宽度和高度完全适应内容区域。

.img-box__img2 {
  width: 100%;
  height: 100%;
  background: url('https://img11.360buyimg.com/da/s800x800_jfs/t1/114578/23/16885/259767/5f51b88eE470cb092/6edf1a51c836efc3.jpg') no-repeat center/contain;
}

backgrount-image 没有任何语义,导致搜索引擎不会识别背景图也不会抓取背景图,不利于搜索引擎优化;且背景图会在页面加载完成之后才开始加载。
_注:图片以背景图形式展示还是以 img 标签形式展示?

  • img标签有alt和title等属性,有利于搜索引擎识别图片;若图片想让搜索引擎抓取到,比如广告图、产品图或logo,建议使用img标签;
  • 仅作为页面装饰效果的图片,比如小图标之类的,建议使用 backgrount-image

第三种:通过 padding-bottom 的方式

在css中,当padding-top、padding-bottom、margin-top 或 margin-bottom 取值为百分比的时候,参照的是父元素的宽度。

<div class="img-box">
    <div class="img-box__inner">
      <img
        class="img-box__img3"
        src="https://img11.360buyimg.com/da/s800x800_jfs/t1/114578/23/16885/259767/5f51b88eE470cb092/6edf1a51c836efc3.jpg" alt="京东房产" />
    </div>
</div>
.img-box__inner {
  position: relative;
  padding-bottom: 100%;
  width: 100%;
  height: 0;
  overflow: hidden;
}
.img-box__img3 {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 100%;
}

采用 padding-bottom 的方式,当图片的高度过大时,若是容器的高度固定,且设置为 overflow: hidden,图片会被裁剪,如下图所示:

图片3.png

想要实现的效果,其实是:

图片3.png

_注:
对于图片等资源,加载是需要时间的,可以通过 padding-bottom 提前占位,避免图片被撑开的过程中,出现闪烁的现象。

第四种: 利用css3属性 -> object-fit

object-fit 属性指定元素的内容应该如何去适应指定容器的高度与宽度,可适用于img和video标签。设置object-fit: contain,可实现图片保持原有尺寸比例,内容被缩放。

.img-box__img4 {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

第五种: 通过 js 根据容器的大小重新设置图片的大小

大概思路是,通过 js 分别获取容器与图片的宽和高,算出容器和图片的大小比例,根据比例值,重新设置图片的大小

// 第五种: 通过 js 根据容器的大小重新设置图片的大小
var imgBox = document.getElementById('imgBox')
var imgDom = document.getElementById('img5')
var imgBoxWidth = imgBox.offsetWidth // 获取容器的宽度
var imgBoxHeight = imgBox.offsetHeight // 获取容器的高度
var img = new Image()
img.src = imgDom.src
img.onload = function () {
    var imgWidth = this.width
    var imgHeight = this.height
    var wRatio = imgBoxWidth / imgWidth
    var hRatio = imgBoxHeight / imgHeight
    var fitRatio = hRatio < wRatio ? hRatio : wRatio // 得出容器的大小与图片大小的比例
    var w = Math.round(imgWidth * fitRatio)
    var h = Math.round(imgHeight * fitRatio)
    imgDom.style.width = w + 'px'
    imgDom.style.height = h + 'px'
    imgDom.style.display = 'block'
}

这五种方法的完整代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    .img-box {
      position: relative;
      display: flex;
      align-items: center;
      justify-content: center;
      margin: 20px auto;
      width: 400px;
      height: 400px;
      background-color: #00a495;
      overflow: hidden;
    }
    /*第一种:通过max-width和max-height*/
    .img-box__img1 {
      max-width: 100%;
      max-height: 100%;
    }
    /*第二种:通过背景图的方式*/
    .img-box__img2 {
      width: 100%;
      height: 100%;
      background: url('https://img11.360buyimg.com/da/s800x800_jfs/t1/114578/23/16885/259767/5f51b88eE470cb092/6edf1a51c836efc3.jpg') no-repeat center/contain;
    }
    /*第三种:通过 padding-bottom 的方式*/
    .img-box__inner {
      position: relative;
      padding-bottom: 100%;
      width: 100%;
      height: 0;
      overflow: hidden;
    }
    .img-box__img3 {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      width: 100%;
    }
    /*第四种*/
    .img-box__img4 {
      width: 100%;
      height: 100%;
      object-fit: contain;
    }
    .img-box__img5 {
      display: none;
    }
  </style>
</head>
<body>
<div class="img-box">
  <img
    class="img-box__img1"
    src="https://img11.360buyimg.com/da/s800x800_jfs/t1/114578/23/16885/259767/5f51b88eE470cb092/6edf1a51c836efc3.jpg" alt="京东房产" />
</div>
<div class="img-box">
  <div class="img-box__img2"></div>
</div>
<div class="img-box">
  <div class="img-box__inner">
    <img
      class="img-box__img3"
      src="https://img11.360buyimg.com/da/s800x800_jfs/t1/114578/23/16885/259767/5f51b88eE470cb092/6edf1a51c836efc3.jpg" alt="京东房产" />
  </div>
</div>
<div class="img-box">
  <img
    class="img-box__img4"
    src="https://img11.360buyimg.com/da/s800x800_jfs/t1/114578/23/16885/259767/5f51b88eE470cb092/6edf1a51c836efc3.jpg" alt="京东房产" />
</div>
<div class="img-box" id="imgBox">
  <img
    class="img-box__img5"
    id="img5"
    src="https://img11.360buyimg.com/da/s800x800_jfs/t1/114578/23/16885/259767/5f51b88eE470cb092/6edf1a51c836efc3.jpg" alt="京东房产" />
</div>
</body>
<script type="text/javascript">
	// 第五种: 通过 js 根据容器的大小重新设置图片的大小
	var imgBox = document.getElementById('imgBox')
	var imgDom = document.getElementById('img5')
	var imgBoxWidth = imgBox.offsetWidth // 获取容器的宽度
	var imgBoxHeight = imgBox.offsetHeight // 获取容器的高度
	var img = new Image()
	img.src = imgDom.src
	img.onload = function () {
		var imgWidth = this.width
		var imgHeight = this.height
		var wRatio = imgBoxWidth / imgWidth
		var hRatio = imgBoxHeight / imgHeight
		var fitRatio = hRatio < wRatio ? hRatio : wRatio // 得出容器的大小与图片大小的比例
		var w = Math.round(imgWidth * fitRatio)
		var h = Math.round(imgHeight * fitRatio)
		imgDom.style.width = w + 'px'
		imgDom.style.height = h + 'px'
		imgDom.style.display = 'block'
	}
</script>
</html>

原文:https://yolkpie.net/2020/11/01/图片根据容器的大小自适应/

posted @ 2021-03-01 18:33  yolkpie  阅读(678)  评论(0编辑  收藏  举报