首页 > 解决方案 > 调整不同纵横比的图像大小以适应 div 而不拉伸它

问题描述

我正在制作一个投资组合网站,我正在尝试制作一个简单的图像浏览器。我有一个容器 div,其大小相对于浏览器窗口的大小。我希望该 div 能够包含不同纵横比的图像和固定高度的标题以及相对于图像宽度的宽度。我不希望 div 拉伸以包含图像,我想调整图像大小(您可以在下图中看到我的意思)。

这里的问题说明

我试图使用 javascript 来计算图像的大小,但失败了,因为在实际加载元素之前我无法计算元素的大小。这就是我尝试这样做的方式(不考虑标题栏):

var divAspectRatio = containerDiv.offsetHeight/containerDiv.offsetWidth;
var imageAspectRatio = image.offsetHeight/image.offsetWidth;
if(divAspectRatio>imageAspectRatio){
  image.style.height = content_in.offsetHeight;
}else{
  image.style.width = content_in.offsetWidth;
}
captionDiv.style.width = image.offsetWidth;

我如何使它工作?

标签: javascripthtmlcss

解决方案


所需的布局需要一些计算,因为放置宽高比大于容器宽高比的图像与不放置的图像不同。另外需要注意的是,标题区域只需要与显示的图像一样宽,但具有固定的高度。

imgs 被包裹在一个“innerdiv”中,它也将包含标题。在加载图像的纵横比时,会找到并存储为 CSS 变量。其他 CSS 变量是预先设置的 - 请参阅此片段的头部以了解可以选择的那些。其余的计算在 CSS 中完成。

window.onload = function () {
  const imgs = document.querySelectorAll('.container .innerdiv .img');
  imgs.forEach(img => {
    img.parentElement.style.setProperty('--imgratio', img.naturalWidth / img.naturalHeight);
    img.parentElement.classList.add(( (img.naturalWidth / img.naturalHeight) > getComputedStyle(img).getPropertyValue("--containerratio") ) ? 'wider' : 'thinner');
  });
}
* {
  padding: 0;
  margin: 0;
}
.container {
/* SET THE NEXT 4 VARIABLES TO WHAT YOU REQUIRE */
  --unit: 1vmin; /* the basic unit - must be fixed e.g. vmin, px, ch not % */
  --containerw: 40; /* width of a container in these units */
  --containerratio: 1.5; /* the ratio of width to height */
  --captionh: 4vmin; /* height of a caption including its units (which must be fixed e.g. vmin, px, em */
  
  --containerh: calc(var(--containerw) / var(--containerratio));
  
  display: inline-block;
  width: calc(var(--containerw) * var(--unit));
  height: calc(var(--containerh) * var(--unit));
  position: relative;
  border: solid;
}

.innerdiv {
  display: inline-block;
  position: absolute;
  top: 0;
  left: 0;
}

.innerdiv.thinner {
  width: calc(var(--imgratio) * ((var(--containerh) * var(--unit)) - var(--captionh)));
  height: 100%;
  left: 50%;
  transform: translateX(-50%);
}

.innerdiv.wider {
  width: 100%;
  height: calc((var(--containerw) / var(--imgratio)) * var(--unit) + var(--captionh));
  top: 50%;
  transform: translateY(-50%);
}

.img {
  width: 100%;
  height: auto;  
}

.caption {
  font-size: 2vmin;
  background-color: yellow;
  text-align: center;
  width: 100%;
  height: var(--captionh);
  position: absolute;
  top: calc(100% - var(--captionh));
  left: 0;
}
<div class="container">
  <div class="innerdiv">
    <img class="img" src="https://picsum.photos/id/1016/200/300">
    <div class="caption">CAPTION</div>
  </div>
</div>
<div class="container">
  <div class="innerdiv">
    <img class="img" src="https://picsum.photos/id/1016/500/200">
    <div class="caption">CAPTION</div>
  </div>
</div>
<div class="container">
  <div class="innerdiv">
    <img class="img" src="https://picsum.photos/id/1016/300/300">
    <div class="caption">CAPTION</div>
  </div>
</div>


推荐阅读