CSS FlexBox布局中如何自动调整图像大小并保持纵横比?

149

我使用了CSS的弹性盒布局,如下所示:

enter image description here

如果屏幕变小,它会变成这样:

enter image description here

问题是图像没有按原始图像的纵横比重新调整大小。

是否可能使用纯CSS和弹性盒布局使图像在屏幕变小时自适应调整大小?

以下是我的HTML代码:

<div class="content">
  <div class="row"> 
    <div class="cell">
      <img src="http://i.imgur.com/OUla6mK.jpg"/>
    </div>
    <div class="cell">
      <img src="http://i.imgur.com/M16WzMd.jpg"/>
    </div>
  </div>
</div>

我的 CSS:

.content {
    background-color: yellow;    
}

.row {
    display: -webkit-box;
    display: -moz-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;

    -webkit-box-orient: horizontal; 
    -moz-box-orient: horizontal;
    box-orient: horizontal;
    flex-direction: row;

    -webkit-box-pack: center;
    -moz-box-pack: center;
    box-pack: center;
    justify-content: center;

    -webkit-box-align: center;
    -moz-box-align: center;
    box-align: center;  
    align-items: center;

    background-color: red;

}

.cell {
    -webkit-box-flex: 1;
    -moz-box-flex: 1;
    box-flex: 1;
    -webkit-flex: 1 1 auto;
    flex: 1 1 auto; 

    padding: 10px;
    margin: 10px;

    background-color: green;
    border: 1px solid red;
    text-align: center;

}
10个回答

134

8
如果屏幕变小,高度尺寸的调整也是可能的吗?请予以确认。 - Michael
@confile 这取决于你的代码布局,但你可以尝试在 img 的 CSS 中添加 height:100%; - Omega
2
使用height: 100vh即可,不要使用height: 100%。高度的样式总是很棘手。 - gdbj
1
为什么这被标记为正确答案?难道Omega已经将其转化为浏览器的默认行为了吗?http://jsfiddle.net/89dtxt6s/221/ - Whip

101

我来这里是为了寻找我的图像扭曲的答案。不太确定上面的操作正在寻找什么,但我发现添加align-items: center对我很有帮助。阅读文档,如果您直接弯曲图像,则覆盖此设置是有意义的,因为align-items: stretch是默认设置。另一个解决方案是先用

包装您的图像。

.myFlexedImage {
  display: flex;
  flex-flow: row nowrap;
  align-items: center;
}

21
我来这里是为了寻找解决我的图像失真问题的答案。我也因同样的原因来到这里,你的解决方案帮助了我(被标记为实际解决方案的内容对我没有任何帮助)。 - Wagner Danda da Silva Filho
1
这也帮助了我,有人能解释一下为什么这样行得通吗? - Jerry B. no.1 intern
1
这对我来说是正确的答案。max-width: 100%;不能解决高度问题(高度仍然稍微被拉伸)。在我的情况下,我使用了align-items: flex-start;因为我不想让图像在容器中垂直居中,但它仍然有效,因为它覆盖了默认的align-items: stretch;以下是可用于覆盖的所有align-items属性值的列表:https://www.w3schools.com/cssref/css3_pr_align-items.asp - Kyle Vassella
尝试了很多方法,但是在父元素上使用align-items:center是唯一有效的方法。 - Micros
这应该是采纳的答案。在拉伸方面,align-content 对我无效,但 align-items 有用,两者有不同的功能。这个 Stack Exchange 清楚地解释了它们之间的区别:https://dev59.com/L14c5IYBdhLWcg3wyMwB - John Ernest

68

你可能想尝试一下最新、最简单的CSS3功能:

img { 
  object-fit: contain;
}

它保留了图片的比例(就像使用背景图片技巧时那样),在我的情况下,对于同样的问题效果很好。

但要注意,IE浏览器不支持此功能(详情请参见此处)。

如果您希望指定特定的宽高比,可以将其与aspect-ratio属性结合使用。

img { 
  object-fit: contain;
  aspect-ratio:2/1;
}

6
请记住,父对象必须是一个Flex容器。 - Lokinou
1
我尝试过这个,在 flex div 中完美运行。 - Rémy Kaloustian
谢谢!我已经寻找这个很长时间了,我无法相信它不更受欢迎,我一直在遇到这个问题并使用解决方法。 - Vincent

12

我建议查看background-size选项以调整图像大小。

如果您将其设置为背景图像,而不是在页面中放置图像,则可以设置:

background-size: contain

或者

background-size: cover

这些选项在缩放图像时考虑了高度和宽度。这可适用于IE9和所有其他较新的浏览器。


它与图片的对象适合性相同。 - mevsme

3
在第二张图片中,看起来您想让图片填满框,但是您创建的示例确实保持了宽高比(宠物看起来正常,不胖不瘦)。
我不知道您是否将那些图片作为示例进行了photoshop处理,或者第二张图片也是“应该是”(您说过是),就像第一个示例一样,您说“应该是”。
不管怎样,我必须假设:
如果“图像没有保持宽高比”,并且您向我展示了一个保持像素宽高比的图像,我必须假设您正在尝试完成“裁剪”区域(绿色内部)的宽高比,同时保持像素宽高比。也就是说,您想通过放大和裁剪图像来填充单元格。
如果这是您的问题,那么您提供的代码并没有反映“您的问题”,而是您的起始示例。
考虑到前面两个假设,如果盒子的高度是动态的,那么你需要使用背景图片来完成,而不是实际的图片。可以使用"background-size: contain"或这些技术(通过使用以百分比为单位的智能填充限制裁剪或在任何位置设置最大尺寸)。http://fofwebdesign.co.uk/template/_testing/scale-img/scale-img.htm 唯一可以使用图片的方法是忽略第二个图片,并且单元格具有固定高度,幸运的是,根据您的示例图像,高度保持不变!
因此,如果容器的高度不变,并且您想保持图像的正方形,则只需将图像的最大高度设置为已知值(减去填充或边框,具体取决于单元格的box-sizing属性)。
像这样:
<div class="content">
  <div class="row">    
      <div class="cell">    
          <img src="http://lorempixel.com/output/people-q-c-320-320-2.jpg"/>
      </div>
      <div class="cell">    
          <img src="http://lorempixel.com/output/people-q-c-320-320-7.jpg"/>
      </div>
    </div>
</div>

和 CSS:

.content {
    background-color: green;
}

.row {
    display: -webkit-box;
    display: -moz-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;

    -webkit-box-orient: horizontal; 
    -moz-box-orient: horizontal;
    box-orient: horizontal;
    flex-direction: row;

    -webkit-box-pack: center;
    -moz-box-pack: center;
    box-pack: center;
    justify-content: center;

    -webkit-box-align: center;
    -moz-box-align: center;
    box-align: center;  
    align-items: center;

}

.cell {
    -webkit-box-flex: 1;
    -moz-box-flex: 1;
    box-flex: 1;
    -webkit-flex: 1 1 auto;
    flex: 1 1 auto;
    padding: 10px;
    border: solid 10px red;
    text-align: center;
    height: 300px;
    display: flex;
    align-items: center;
    box-sizing: content-box;
}
img {
    margin: auto;
    width: 100%;
    max-width: 300px;
    max-height:100%
}

http://jsfiddle.net/z25heocL/

您的代码无效(开放标签代替了关闭标签,因此它们输出嵌套单元格而不是同级单元格,他在有问题的代码中使用了您图片的截图,并且flex box未将单元格保持在同一行,而是以列的形式呈现两个示例(您设置了“行”,但是损坏的代码将一个单元格嵌套在另一个单元格中导致内部存在一个flex),最终作为列工作。我不知道您想要实现什么,以及如何编写该代码,但我猜测您想要的是这样的。

我还将display:flex添加到单元格中,以便图像居中(我认为可以在所有这些标记中使用display:table)


你似乎完全不知道我是如何回答这个问题的。那个jsfiddle中的所有html和css都是提问者(@confile)提供的。只要读一下问题,你就会明白。我的解决方案只有一行简单的css代码img {max-width:100%;},而且提问者在一年前就已经接受了我的答案,因为它提供了所要求的解决方案。祝你们好运,在未来请尽量正确地阅读问题,然后给出相应的答案,谢谢。 - Omega

2

HTML:

<div class="container">
    <div class="box">
        <img src="http://lorempixel.com/1600/1200/" alt="">
    </div>
</div>

CSS:

.container {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: stretch;

  width: 100%;
  height: 100%;

  border-radius: 4px;
  background-color: hsl(0, 0%, 96%);
}

.box {
  border-radius: 4px;
  display: flex;
}

.box img {
  width: 100%;
  object-fit: contain;
  border-radius: 4px;
}

1
这是我在灵活的网格中处理不同图像(大小和比例)的方法。最初的回答:

.images {
  display: flex;
  flex-wrap: wrap;
  margin: -20px;
}

.imagewrapper {
  display: flex;
  justify-content: center;
  align-items: center;
  width: calc(50% - 20px);
  height: 300px;
  margin: 10px;
}

.image {
  display: block;
  object-fit: cover;
  width: 100%;
  height: 100%; /* set to 'auto' in IE11 to avoid distortions */
}
<div class="images">
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/800x600" />
  </div>
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/1024x768" />
  </div>
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/1000x800" />
  </div>
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/500x800" />
  </div>
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/800x600" />
  </div>
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/1024x768" />
  </div>
</div>


0

你可以很容易地使用网格来做到这一点:

display: grid;
grid-template-columns: auto auto;
justify-content: space-between;

0

为您的单元格div设置50%或特定数字的宽度。 对于img标签,将宽度设置为100%。 这样,宽度将始终为100%,高度将相应更改,保持纵横比不变。


-8
我正在使用jQuery或vw来保持比例。
jQuery
function setSize() {
    var $h = $('.cell').width();
    $('.your-img-class').height($h);
}
$(setSize);
$( window ).resize(setSize); 

vw

 .cell{
    width:30vw;
    height:30vw;
}
.cell img{
    width:100%;
    height:100%;
}

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