object-fit
和 object-position
是我最近最喜欢的两个 CSS 属性。它们让开发人员可以控制 img
或 video
内部的内容,类似于我们可以使用 background-position
和 background-size
来操作 background
的内容。
object-fit
。
首先,让我们深入了解 此属性定义了元素(例如 img
)如何响应其内容框的宽度和高度。使用 object-fit
,我们可以告诉内容以各种方式填充该框,例如“保持该纵横比!”或“拉伸并尽可能多地占用空间!”
以下是一个示例

此图像为 400px x 260px。如果我们像这样设置该图像的样式…
img {
width: 200px;
height: 300px;
}
…那么最终会导致奇怪的扭曲,因为该图像被压缩以适合该容器
查看 CodePen 上 Robin Rendle (@robinrendle) 制作的 1b15cf30a6226d9f419b4f765458a059。
我们的 img
的内容将占用我们更改其高度和宽度时创建的新框内的所有可用空间,从而破坏其原始纵横比。
为了在填充空间的同时保留图像的纵横比,我们可以使用 object-fit
.cover {
object-fit: cover;
}
查看 CodePen 上 Robin Rendle (@robinrendle) 制作的 7080df9cb7158c0860b8a66db9667a7d。
左侧的图像是我们原始的图像,右侧的图像剪掉了图像的侧面,现在保留了我们的纵横比!在该尺度上,这可能看起来不像一个特别有趣的进展,但一旦我们开始设计更逼真的界面,object-fit
的强大功能就会显现出来。
让我们看另一个例子
查看 CodePen 上 CSS-Tricks (@css-tricks) 制作的 WrBzey。
这里我们有两个图像,我们希望它们填充浏览器窗口宽度的一半(这样它们并排放置)和高度的 100%。我们可以借助视口单位来实现这一点
img {
height: 100vh;
width: 50vw;
}
问题是,当我们调整浏览器大小,我们也会改变图像的纵横比,这会导致各种奇怪的问题。相反,我们希望像在前面的演示中一样保留它们的纵横比,我们可以使用完全相同的方法来实现这一点。object-fit: cover
来拯救!
查看 CodePen 上 CSS-Tricks (@css-tricks) 制作的 YwbeoG。
再次尝试调整浏览器大小。没有纵横比怪异之处,对吧?如果我们有尺寸不同的图像,这也有非凡的帮助,因为它们实际上会被其边界框裁剪。
cover
只是 object-fit
的许多值之一,您可以在 年鉴条目 上了解有关更多值的详细信息,但到目前为止,这是我在日常界面开发中发现最实用的值。
object-position
。
让我们继续我最喜欢的东西:我们将通过使用与之前相同的图像并使用这些样式来进行设置
img {
background: yellow;
height: 180px;
object-fit: none;
}
这里需要注意两点:我们需要声明图像的尺寸,以便 object-position
正确工作,并且我们还需要将 object-fit
设置为 none
,这样图像就可以被推来推去,而不是像默认情况下那样填充整个框。当您看到 img
上 object-fit
的默认值为 fill
时,即使您没有声明它,这一点就更有意义了。
说到默认值,object-position
在没有值的情况下水平和垂直居中所有对象
img {
background: yellow;
height: 180px;
object-fit: none;
object-position: 50% 50%; /* even if we dont declare this the image will still be centered */
}
第一个值将图像向左或向右移动,第二个值将图像向上或向下移动。我们可以在这里试验这些值
查看 CodePen 上 Robin Rendle (@robinrendle) 制作的 Object position。
我们甚至可以将图像推入其内容框内,这样我们就可以看到我们之前设置的 background-color
。
但这有什么用?好问题!好吧,在最近的一个项目中,我发现图像的特定部分需要移到中心,以便吸引读者的注意力。我们不需要加载新图像,因此在这种情况下不需要 <picture>
元素,我们只需要将图像稍微移动一下。
除了移动图像的焦点,我不确定此属性在实际意义上还有什么其他用途。但我一直在使用 object-position
来展示如何隐藏图像的某些部分,然后在单击时显示这些部分,就像在这个演示中一样
查看 CodePen 上 Robin Rendle (@robinrendle) 制作的 SVG sprite with object-position。
我还没有尝试过如何或为什么你可能将它用于 <video>
元素。也许是覆盖所有边缘的全屏视频?在这些属性方面,还有很多东西要学习和探索。
支持情况如何?
总的来说,非常好!
object-fit
除了 IE/Edge 之外,所有浏览器都支持。而 object-position
除了 Safari 和 IE/Edge 之外,所有浏览器都支持。
我不知道这个属性的存在!它看起来非常有用,所以我必须尝试一下。
我也是刚接触这些属性,并且非常兴奋地在当前项目中尝试使用它们!
不错。我前几天发布了关于 object-fit 的文章,其中包括 IE 的简单回退(IE 完全不支持它)。
https://pawelgrzybek.com/image-tag-vs-background-property/
我发现 Firefox 对 object-fit 的处理有点乱,当与 2d/3d 转换结合使用时。请查看以下示例,其中 Firefox 中的 object-fit 导致突然压缩,然后是转换,最后是不压缩:http://codepen.io/davecranwell/pen/XXwbPQ
有人知道解决方案吗?
Firefox 包裹器 1 中的 img 问题是
height: 100%;
声明。如果您将其替换为height: auto;
,问题就会解决。但是,图像的位置会从居中更改为 hacks 在底部的样式。object-position 用例
缩放!提供一个过大的图像,默认情况下它会缩小到您设置的大小。在悬停时,设置“object-fit: none”,并使用 JS 将 object-position 设置为与图像内鼠标位置对应的百分比 - 立即获得缩放功能!
真是个超级酷的主意!我在任何地方都没见过,所以我在实践中快速制作了一个演示
http://s.codepen.io/robinrendle/debug/d65ccca115fdd4def0171019939635c3
不过,从“object-fit: fill”到“object-fit: none”的动画效果会很酷,这样您就能看到一个漂亮的缩放效果,尽管我想不出一个简单的方法来解决这个问题,因为属性不可动画。
和往常一样… 操蛋的 IE
同意。如果 IE 不支持,我不会说浏览器支持是“相当不错” - 毕竟,大多数实际世界都在使用 IE。如果只有 IE8 不支持它,那么我会说,浏览器支持非常好。
我个人非常想用最新的 CSS 和 JS 来构建我的所有网站,无论 IE 或 Safari 是否支持这些功能,但对于我的客户来说这是行不通的。因此,目前为了关键的布局,我将不得不坚持使用 Uncle Dave’s Ol’ Padded Box 的变体来模拟 `object-fit`。
(顺便说一句,`object-fit: contain` 对将未知尺寸的图像放入已知尺寸的框中(例如带平铺图标)非常有用。这可以通过 Uncle Dave’s Padded Box 来完成,但前提是你知道图像的纵横比。)
太棒了,我一定会用这个。
这是一个很酷的功能,但是支持得还不够好,无法满足我的标准。而且我找到的唯一 polyfill 是 已弃用… :(
是的,太糟糕了。我开始使用一些 JS 将 `img.object-fit` 转换为父容器的背景图像,这样你就可以使用 `background-size` 代替。这比直接粘贴 polyfill 需要更多的配置,但目前来说足够了!
以下内容也适用于 `srcset`
(测试不足)
我刚刚完成了一个 1kb 的 `object-fit` polyfill,用于在图像上 bfred-it/object-fit-images,它在 IE9+ 上运行良好(可能更低,但目前尚未测试)。
`object-fit` 的唯一真正的“缺陷”是它不支持 IE 和 Edge,不幸的是,这不是一个小缺陷。这是一个很棒的属性,但是如果你的客户使用这两者之一,即使只是为了检查他的网站,他也会看到乱七八糟的图像。
人们仍然可以使用带有 url 的 `background`,然后将 `background-size` 设置为 `cover` 来“适应”图像,但不幸的是,你无法完美地复制 `object-fit`(确定图像的大小以设置 div 的大小有点麻烦)。
我们只能希望 MS 团队会在他们 Edge 浏览器的下一个版本中使这个属性工作(因为 IE 即将停止使用)。
太好了,一旦我们有了支持,它将简化现在解决此问题的繁琐技术。
.container {
position: relative;
overflow: hidden;
width: 400px;
height: 300px;
}
video {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%); // ie9
min-width: 100%;
min-height: 100%;
}
使用 top: 0; 和 translateX(-50%) 等来调整定位。
对于那些哀悼 object-fit polyfill 消失的人来说…
object-fit:cover 的一个变通方法已经开发出来。
https://medium.com/@primozcigler/neat-trick-for-css-object-fit-fallback-on-edge-and-other-browsers-afbc53bbb2c3#.igtqmicog
Chrome 在正确显示此页面上的图像方面非常普通。我在 Chrome 47.0.2526.80、Firefox 44.0.2 和 Internet Explorer 11 上打开了页面,只有 Firefox 正确显示了内容。Chrome 和 IE 都将图像拉伸到看起来不自然的格式。
Robin,当你想要缩放容器的宽度、高度或两者,但不缩放图像时,`object-position` 会很有用。因此,图像会被裁剪。
有时缩放图像会使细节变得太小,因此裁剪是一个更好的选择。
很棒的文章,很棒的 CSS 属性。再也不用一直使用 `background-size/background-position` 了。几周前,我在检查 muzli Chrome 扩展程序时偶然发现了这些属性。很棒的发现。
我一定会查一下,但是对于最后一个 codepen,我认为可能出了问题,位置,不应该应该是 `0 0`、`50% 0` 和 `100% 0` 吗,因为水平方向没有偏移?