CSS中的object-fit:contain;会保持原始图像的宽度在布局中。

11

我正在尝试在一些Flexbox容器中使用object-fit:contain使我的图像具有响应性,虽然图像确实会重新调整大小,但布局似乎仍保持原始图像大小,导致出现滚动条。

使用Chrome Dev Tools检查图像的宽度显示宽度仍为1024(但高度已适当缩小)。

(我从Auto Resize Image in CSS FlexBox Layout and keeping Aspect Ratio?获得了灵感来到达这一点)

我是否缺少其他CSS属性?

JSFiddle: https://jsfiddle.net/w6hgqf18/1/

problem

html,
body {
  margin: 0;
  height: 100%;
}

.page {
  height: 100%;
  display: flex;
}

.main-container {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
}

.half-containers {
  flex: 0 1 50%;
  overflow: auto;
  box-sizing: border-box;
  border: 0.5px solid red;
  display: flex;
}

.page-header {
  flex: 0 0 auto;
  background-color: #dcdcdc;
}

.page-footer {
  flex: 0 0 auto;
  background-color: #dcdcdc;
}

img {
  object-fit: contain;
}
<div class="page">
  <div class="main-container">
    <div class="page-header">
      This is a header
    </div>
    <div class="half-containers">
      <img src='https://i.imgur.com/tqQvuFr.jpg' />
    </div>
    <div class="half-containers">
      <img src='https://i.imgur.com/tqQvuFr.jpg' />
    </div>
    <div class="page-footer">
      This is a footer
    </div>
  </div>
</div>


1
不是重复的问题,实际上我的问题使用了我从这些答案中获得的信息:https://dev59.com/1WEi5IYBdhLWcg3wndZw - dangel
2
我同意,这不是重复的问题。那里没有解释object-fit为什么会表现出这样的行为。这不是关于自动调整图像大小的问题,这已经在这里完成了。这是关于“为什么object-fit会表现出这种行为”的问题。 - Temani Afif
2个回答

13

你所拥有的是合乎逻辑的,你只需要理解object-fit的工作原理。让我们从一个更简单的例子开始:

.box {
  width:300px;
  height:300px;
  border:1px solid;
}
img {
 width:100%;
 height:100%;
 object-fit:contain;
}
<div class="box">
  <img src="https://picsum.photos/300/200?image=1069">
</div>

如您所见,我使用了一个300x200的图像,将其拉伸到300x300的框内,因此我打破了它的比例,如果您检查图像的宽度/高度,您会发现它的尺寸仍然是300x300(应用object-fit之前的尺寸)。
规范中可以看出:

object-fit属性指定如何适应被替换元素的内容由其使用的高度和宽度建立的框中。

基本上,我们视觉上改变图像的内容,使其适合图像所建立的空间。object-fit不会改变图像的大小,但使用该大小作为参考来更改其内部内容。
让我们使用50%来举同样的例子:

.box {
  width:300px;
  height:300px;
  border:1px solid;
}
img {
 width:50%;
 height:50%;
 object-fit:contain;
}
<div class="box">
  <img src="https://picsum.photos/300/200?image=1069">
</div>

现在这个图像的尺寸为150x150,我们会在里面应用包含效果来改变内容。
所有的值都会按照相同的逻辑进行处理。

.box {
  width:300px;
  height:300px;
  border:1px solid;
}
img {
 width:50%;
 height:50%;
}
<div class="box">
  <img src="https://picsum.photos/300/200?image=1069" style="object-fit:contain;">
</div>
<div class="box">
  <img src="https://picsum.photos/300/200?image=1069" style="object-fit:cover;">
</div>


在你的示例中,你遇到了相同的问题。没有使用object-fit属性,图片将会像下面这样:

html,
body {
  margin: 0;
  height: 100%;
}

.page {
  height: 100%;
  display: flex;
}

.main-container {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
}

.half-containers {
  flex: 0 1 50%;
  overflow: auto;
  box-sizing: border-box;
  border: 0.5px solid red;
  display: flex;
}

.page-header {
  flex: 0 0 auto;
  background-color: #dcdcdc;
}

.page-footer {
  flex: 0 0 auto;
  background-color: #dcdcdc;
}

img {
  /*object-fit: contain;*/
}
<div class="page">
  <div class="main-container">
    <div class="page-header">
      This is a header
    </div>
    <div class="half-containers">
      <img src='https://i.imgur.com/tqQvuFr.jpg' />
    </div>
    <div class="half-containers">
      <img src='https://i.imgur.com/tqQvuFr.jpg' />
    </div>
    <div class="page-footer">
      This is a footer
    </div>
  </div>
</div>

添加object-fit不会改变其大小,只会改变我们看到的内容:

html,
body {
  margin: 0;
  height: 100%;
}

.page {
  height: 100%;
  display: flex;
}

.main-container {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
}

.half-containers {
  flex: 0 1 50%;
  overflow: auto;
  box-sizing: border-box;
  border: 0.5px solid red;
  display: flex;
}

.page-header {
  flex: 0 0 auto;
  background-color: #dcdcdc;
}

.page-footer {
  flex: 0 0 auto;
  background-color: #dcdcdc;
}

img {
  object-fit: contain;
}
<div class="page">
  <div class="main-container">
    <div class="page-header">
      This is a header
    </div>
    <div class="half-containers">
      <img src='https://i.imgur.com/tqQvuFr.jpg' />
    </div>
    <div class="half-containers">
      <img src='https://i.imgur.com/tqQvuFr.jpg' />
    </div>
    <div class="page-footer">
      This is a footer
    </div>
  </div>
</div>

现在,另一个问题是您的图像宽度为1024px,由于min-width限制,flex项目不会超出其内容大小进行拉伸,因此您需要添加min-width:0以获得所需效果。这样做后,您将不再有溢出问题,然后您的图像将包含在弹性布局定义的区域内。

html,
body {
  margin: 0;
  height: 100%;
}

.page {
  height: 100%;
  display: flex;
}

.main-container {
  flex: 1 1 0;
  display: flex;
  min-width: 0; /*added*/
  flex-direction: column;
}

.half-containers {
  flex: 0 1 50%;
  overflow: auto;
  box-sizing: border-box;
  border: 0.5px solid red;
  display: flex;
}

.page-header {
  flex: 0 0 auto;
  background-color: #dcdcdc;
}

.page-footer {
  flex: 0 0 auto;
  background-color: #dcdcdc;
}

img {
  object-fit: contain;
  min-width: 0; /*added*/
}
<div class="page">
  <div class="main-container">
    <div class="page-header">
      This is a header
    </div>
    <div class="half-containers">
      <img src='https://i.imgur.com/tqQvuFr.jpg' />
    </div>
    <div class="half-containers">
      <img src='https://i.imgur.com/tqQvuFr.jpg' />
    </div>
    <div class="page-footer">
      This is a footer
    </div>
  </div>
</div>

你也可以通过考虑 background-imagebackground-size:contain 来获得相同的输出,在这种情况下,你不再需要担心 min-width 的限制,因为没有更多的内容了。

html,
body {
  margin: 0;
  height: 100%;
}

.page {
  height: 100%;
  display: flex;
}

.main-container {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
}

.half-containers {
  flex: 0 1 50%;
  overflow: auto;
  box-sizing: border-box;
  border: 0.5px solid red;
  display: flex;
  background:url(https://i.imgur.com/tqQvuFr.jpg) center/contain no-repeat;
}

.page-header {
  flex: 0 0 auto;
  background-color: #dcdcdc;
}

.page-footer {
  flex: 0 0 auto;
  background-color: #dcdcdc;
}
<div class="page">
  <div class="main-container">
    <div class="page-header">
      This is a header
    </div>
    <div class="half-containers">
    </div>
    <div class="half-containers">
    </div>
    <div class="page-footer">
      This is a footer
    </div>
  </div>
</div>


好的回答。我只希望我们能够强制 img 更新其固有大小(在这种情况下为宽度),以反映缩小的内容,这样就不会有额外的“填充”。 - TealShift

1
你可以使用 div 包裹 img 标签,并设置 width: 100%,将图片的 height 设为 100%,无需使用 object-fit

html,
body {
  margin: 0;
  height: 100%;
}

.page {
  height: 100%;
  display: flex;
}

.main-container {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
}

.half-containers {
  flex: 0 1 50%;
  overflow: auto;
  box-sizing: border-box;
  border: 0.5px solid red;
  display: flex;
}

.page-header {
  flex: 0 0 auto;
  background-color: #dcdcdc;
}

.page-footer {
  flex: 0 0 auto;
  background-color: #dcdcdc;
}


.img-container {
  width: 100%;
}

img {
  height: 100%;
}
<div class="page">
  <div class="main-container">
    <div class="page-header">
      This is a header
    </div>
    <div class="half-containers">
      <div class="img-container">
        <img src='https://i.imgur.com/tqQvuFr.jpg' />
      </div>
    </div>
    <div class="half-containers">
      <div class="img-container">
        <img src='https://i.imgur.com/tqQvuFr.jpg' />
       </div>
    </div>
    <div class="page-footer">
      This is a footer
    </div>
  </div>
</div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接