关于html:更改高度时保持图像宽高比

Maintain image aspect ratio when changing height

使用css flex box模型,如何强制图像保持其纵横比?

JS小提琴:http://js fiddle.net/xlc2le0k/2/

请注意,图像会拉伸或收缩以填充容器的宽度。很好,但是我们可以让它拉伸或收缩高度来保持图像比例吗?

HTML

1
2
3
4
    <img src="http://www.placebacon.net/400/300" alt="Bacn">
    <img src="http://www.placebacon.net/400/300" alt="Bacn">
    <img src="http://www.placebacon.net/400/300" alt="Bacn">
    <img src="http://www.placebacon.net/400/300" alt="Bacn">

CSS

1
2
3
4
5
6
.slider {
    display: flex;
}
.slider img {
    margin: 0 5px;
}


对于img标记,如果定义了一侧,则会调整另一侧的大小以保持纵横比,并且默认情况下,图像会扩展到其原始大小。

使用这个事实,如果您将每个img标记包装成DIV标记,并将其宽度设置为父DIV的100%,那么高度将根据您想要的纵横比而定。

http://jsfiddle.net/0o5tpbxg/

1
2
3
4
5
6
7
8
9
10
* {
    margin: 0;
    padding: 0;
}
.slider {
    display: flex;
}
.slider .slide img {
    width: 100%;
}


为了防止图像在flex父对象的任意轴上拉伸,我找到了一些解决方案。

您可以尝试在图像上使用对象匹配,例如

1
object-fit: contain;

http://jsfidle.net/ykw3sfjd/

或者您可以添加灵活的特定规则,在某些情况下可能会更好地工作。

1
2
align-self: center;
flex: 0 0 auto;


不需要添加包含的分区。

css"Align items"属性的默认值是"Stretch",这会导致图像被拉伸到其原始高度。将css"Align items"属性设置为"flex start"可以解决您的问题。

1
2
3
4
.slider {
    display: flex;
    align-items: flex-start;  /* ADD THIS! */
}


Most of images with intrinsic dimensions, that is a natural size, like a jpeg image. If the specified size defines one of both the width and the height, the missing value is determined using the intrinsic ratio... - see MDN.

但据我所知,如果将图像设置为具有当前灵活的方框布局模块级别1的直接灵活项,则无法按预期工作。

请参阅这些讨论和错误报告可能相关:

  • flexbug 14-Chrome/flexbox内部大小调整未正确实现。
  • firefox bug 972595-flex容器应该使用"flex basis"而不是"width"来计算flex项的内部宽度。
  • 铬问题249112-在flexbox,允许内在长宽比通知主要尺寸计算。

作为解决方法,您可以用等包装每个

J小提琴

1
2
3
4
5
6
7
8
9
10
11
12
.slider {
  display: flex;
}

.slider>div {
  min-width: 0; /* why? see below. */
}

.slider>div>img {
  max-width: 100%;
  height: auto;
}
1
2
3
4
  <img src="https://picsum.photos/400/300?image=0" />
  <img src="https://picsum.photos/400/300?image=1" />
  <img src="https://picsum.photos/400/300?image=2" />
  <img src="https://picsum.photos/400/300?image=3" />

4.5 Implied Minimum Size of Flex Items

To provide a more reasonable default minimum size for flex items,
this specification introduces a new auto value as the initial
value of the min-width and min-height properties defined in
CSS 2.1.

或者,您可以使用css table布局,这样您将得到与flexbox相似的结果,它可以在更多的浏览器上工作,甚至对于ie8也是如此。

J小提琴

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.slider {
  display: table;
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
}

.slider>div {
  display: table-cell;
  vertical-align: top;
}

.slider>div>img {
  max-width: 100%;
  height: auto;
}
1
2
3
4
  <img src="https://picsum.photos/400/300?image=0" />
  <img src="https://picsum.photos/400/300?image=1" />
  <img src="https://picsum.photos/400/300?image=2" />
  <img src="https://picsum.photos/400/300?image=3" />


我最近一直在玩flexbox,我通过实验和下面的推理来解决这个问题。然而,事实上,我不确定这到底是不是真的发生了。

如果实际宽度受柔性系统影响。所以当元素的宽度达到父元素的最大宽度后,在CSS中设置的额外宽度将被忽略。然后将宽度设置为100%是安全的。

因为img标签的高度是从图像本身派生出来的,所以将高度设置为0%可以做些什么。(这是我不清楚的地方……但对我来说应该解决它是合理的)

演示

(记得先在这里看到的!)

1
2
3
4
5
6
7
8
.slider {
    display: flex;
}
.slider img {
    height: 0%;
    width: 100%;
    margin: 0 5px;
}

仅适用于Chrome


我也有同样的问题。使用"灵活对齐"使元素居中。您需要使用align-items: center而不是align-content: center。这将保持纵横比,而对齐内容将不保持纵横比。


实际上,我发现图像标签的容器需要有一个高度才能保持图像的比例。例如>

1
.container{display:flex; height:100%;} img{width:100%;height:auto;}

然后在HTML中,容器将包装标签图像

1
<img src="image.jpg" alt="image" />

这适用于IE和其他浏览器