在 Flexbox 中居中和缩放图像
Posted
技术标签:
【中文标题】在 Flexbox 中居中和缩放图像【英文标题】:Centering and Scaling an Image in a Flexbox 【发布时间】:2015-10-05 19:47:58 【问题描述】:如果容器内的 am <img>
(尺寸未知)设置为display:flexbox
,是否可以满足以下条件:
-
如果图像的原生宽度小于容器的宽度,则它在容器内水平居中。
-
如果图像的原生高度小于容器的高度,则它与容器垂直居中。
-
如果图像的原生宽度大于容器的宽度,则图像将缩放到容器的宽度。
-
如果图像的原生高度大于容器的高度,则图像将缩放到容器的高度。
我注意到 Chrome 和 Firefox 处理 flexbox 子图像的方式存在很大差异。 Chrome 到达一半,但垂直挤压图像。 Firefox 到了一半,但水平挤压图像:Codepen
body,
html
width: 100%;
height: 100%;
margin: 0;
padding: 0;
.Container
height: 100%;
width: 100%;
background: red;
display: flex;
justify-content: center;
align-items: center;
img
max-height: 100%;
max-width: 100%;
<div class="Container">
<img src="http://d13rap2ac6f4c9.cloudfront.net/image_assets/quarry_medium.jpg?1410945487">
</div>
这是我能得到的最接近的Codepen,它在 4 上失败了。:
body,
html
width: 100%;
height: 100%;
margin: 0;
padding: 0;
.Container
height: 100%;
width: 100%;
background: red;
display: flex;
justify-content: center;
align-items: center;
.ImageWrapper
max-height: 100%;
max-width: 100%;
img
max-height: 100%;
max-width: 100%;
width: 100%;
height: auto;
<div class="Container">
<div class="ImageWrapper">
<img src="http://d13rap2ac6f4c9.cloudfront.net/image_assets/quarry_medium.jpg?1410945487">
</div>
</div>
我知道这种行为以前如果没有 javascript 是不可能的,但我很惊讶使用 flexbox 似乎无法实现。
注意:我不是在寻找 JavaScript 解决方案或在现代浏览器中无法运行的解决方案。
针对 David Mann 的回答,这里是前面使用 object-fit
Codepen 的示例。
body,
html
width: 100%;
height: 100%;
margin: 0;
padding: 0;
.Container
height: 100%;
width: 100%;
background: red;
display: flex;
justify-content: center;
align-items: center;
img
max-height: 100%;
max-width: 100%;
object-fit: contain;
<div class="Container">
<img src="http://d13rap2ac6f4c9.cloudfront.net/image_assets/quarry_medium.jpg?1410945487">
</div>
这是使用polyfill 的Codepen。在 IE10 中似乎可以正常工作,但在 IE11 中出现故障。
【问题讨论】:
我认为您的演示运行良好(在 Chrome 中测试),我认为问题是,图像不会在屏幕调整大小时按比例缩放(宽度在 Chrome 中没有按比例增长)但是当您调整窗口大小然后让页面重新加载,它可以很好地缩放。调整窗口大小时,你真的需要它来缩放吗? @KiiroSora09 不幸的是,Firefox 并非如此,即使在页面重新加载时也会挤压图像。 抱歉,我现在没有 Firefox。也许您可以将 flex 与 object-fit 结合起来(来自下面大卫的回答)。因此对象适合将在现代浏览器上运行,并在 IE 11 上回退到 flex。 @KiiroSora09 是的。我认为这可能是要走的路。 除了我suggested在@Pedr下面的其他方法之外,您可以将容器设置为flex-direction: column;
works 在 Chrome 上很好,但在 Firefox 上不太好(当您使视口短于图像的固有高度,纵横比发生变化)。我已经多次看到类似的问题 - 关于将图像设置为直接弹性项目的问题,但是,仍然没有很好的答案,这个 answer 是我见过的最接近的,希望它有所帮助。
【参考方案1】:
CSS 正在迎头赶上。它还没有最大的support,但object-fit: contain
完全符合您的要求(编辑 11/17:Edge 现在有部分支持,使 IE11 成为唯一不支持的浏览器)。只需将其放入 img 的 css 规则中,然后将 max-width: 100%
和 max-height: 100%
更改为 width: 100%
和 height: 100%
。这是codepen。
.Container
height: 100vh;
width: 100vw;
background: red;
display: flex;
justify-content: center;
align-items: center;
img
height: 100%;
width: 100%;
object-fit: contain;
body
margin: 0;
<div class="Container">
<img src="https://unsplash.it/2000/1500">
</div>
如果 IE 缺乏对 object-fit
的支持是一个交易破坏者,那么有一个 javascript polyfill 支持它。以下是来自css-tricks 的更多信息。
background-image
也可以达到同样的效果,但感觉有点作弊。
只需将此添加到.Container
:
background-image: url(http://d13rap2ac6f4c9.cloudfront.net/image_assets/quarry_medium.jpg?1410945487);
background-size: contain;
background-repeat:no-repeat;
background-position: center;
然后完全删除img标签。效果是一样的,但.Container
中没有实际元素。需要注意的是,使用这种方法display: flex
甚至不需要。
这是此方法的另一个 codepen。
.Container
height: 100vh;
width: 100vw;
background: red;
background-image: url(https://unsplash.it/2000/1500);
background-size: contain;
background-repeat: no-repeat;
background-position: center;
body
margin: 0;
<div class="Container">
</div>
这里的support 好多了,还有更多可以玩的东西。再一次,这是来自 css-tricks 的 almanac entry
【讨论】:
哇!我不知道这样的事情存在!我希望我们尽快得到更好的支持。 谢谢。我什至不知道这一点,但它目前还不能使用。 polyfill doesn't even work in IE11. 我在问题中添加了一个使用object-fit
的示例。
哇,我还没有看到 IE11 的这个问题。我正在考虑将 polyfill 用于我正在从事的项目。很高兴我找到了一个可接受的解决方法,而不是使用它。遗憾的是它不涉及 IE 的object-fit
,否则我会在这里发布。
刚刚在 IE10 和 IE11 中测试过,似乎工作正常:codepen.io/anon/pen/VLBwVG【参考方案2】:
方法一:使用 CSS 表格单元格,请看以下演示。
div
border: 1px solid red;
width: 100px;
height: 100px;
display: table-cell;
text-align: center;
vertical-align: middle;
img
max-width: 100%;
max-height: 100%;
vertical-align: middle;
<div><img src="//dummyimage.com/75x50" /></div>
<div><img src="//dummyimage.com/50x75" /></div>
<div><img src="//dummyimage.com/300x200" /></div>
<div><img src="//dummyimage.com/200x300" /></div>
<div><img src="//dummyimage.com/200x200" /></div>
方法 2: 使用内联块,请参阅下面的注释。
div
border: 1px solid red;
width: 100px;
height: 100px;
display: inline-block;
text-align: center;
vertical-align: top;
div:before
content: "";
height: 100%;
display: inline-block;
vertical-align: middle;
img
max-width: 100%;
max-height: 100%;
vertical-align: middle;
<div><img src="//dummyimage.com/75x50" /></div>
<div><img src="//dummyimage.com/50x75" /></div>
<div><img src="//dummyimage.com/300x200" /></div>
<div><img src="//dummyimage.com/200x300" /></div>
<div><img src="//dummyimage.com/200x200" /></div>
补充说明:在父容器内有空的时候设置font-size:0;
,如果里面有文字内容,再在容器内重置为font-size:16px;
左右。关注此以获取更多信息 - https://***.com/a/5078297/483779
【讨论】:
以上是关于在 Flexbox 中居中和缩放图像的主要内容,如果未能解决你的问题,请参考以下文章
CSS:Firefox/Internet Explorer 中 flexbox 的图像缩放问题