假设您在 CSS 中明确指定了图像的宽度。如果宽度以百分比或视口单位指定并且图像的高度设置为auto
,则调整浏览器窗口的大小将保持图像的纵横比。
但是,有时您的可用空间可能有限,需要限制图像的高度。现在调整浏览器窗口的大小肯定会弄乱它的纵横比。
许多与图像大小和纵横比相关的问题,包括我刚刚讨论过的问题,都可以使用CSS 的 object-fit和object-position属性来解决。
这些属性与大家比较熟悉的属性background-size
相似background-position
。因此,即使您以前从未听说过它们,也不会很难理解它们的工作原理。
这两个属性都适用于替换元素。但是,为了简洁起见,在本文中,我将使用术语图像而不是替换元素。
为什么使用object-fit
和object-position
? {#why-use-object-fit-and-object-position}
您可能想知道,当您可以使用background-size
和时,为什么还要使用这两个属性background-position
。实际上,至少有两个很好的理由。
首先,考虑一个场景,您的图像应该是文章的一部分。如果像介绍中描述的那样在 CSS 中设置图像尺寸,则调整浏览器窗口的大小会弄乱它的纵横比。在这种情况下,您会很想使用div
withbackground-size
和background-position
属性,因为仅使用img
标签是不够的。
此解决方案的问题是您应该始终尝试将您的内容和演示文稿分开。背景属性旨在用于演示目的。当您的图像实际上是内容的一部分时,使用object-fit
并object-position
与img
标签一起使用以达到相同的结果更有意义。
另一个原因是背景属性不能应用于视频,而object-fit
可以object-position
。因此,在显示视频时,object-fit
和object-position
是您唯一的选择。
object-fit
属性 {#the-object-fit-property}
此属性确定图像和视频等替换内容如何占用其内容框内的空间。它有五个可能的值:
-
fill
-
contain
-
cover
-
none
-
scale-down
使用此属性的语法如下所示:
.fit-image {
object-fit: fill|contain|cover|none|scale-down;
}
当设置为fill
时,图像的大小将完全适合内容框。在这种情况下,图像的高度等于盒子本身的高度。这也是object-fit
属性的初始值。看个例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>object-fit | Web前端之家www.jiangweishan.com</title>
<style>
body {
text-align: center;
padding-bottom: 20px;
}
h2 {
margin-top: 50px;
}
figure {
position: relative;
display:inline-block;
margin:0;
}
figcaption {
position: absolute;
top: 10px;
left: 10px;
background: black;
color: white;
padding: 5px 10px;
}
.first {
width: 260px;
height: 200px;
background: red;
}
.second {
width: 260px;
height: 400px;
background: yellow;
}
.fill {
object-fit: fill;
}
</style>
</head>
<body>
<h1>The <code>object-fit</code> Property : Fill</h1>
<h2>At Dimensions : 260px*200px</h2>
<figure>
<img class="first" src="http://t.imgbox.com/j8aQ81zq.jpg" />
<figcaption>Original</figcaption>
</figure>
<figure>
<img class="first fill" src="http://t.imgbox.com/j8aQ81zq.jpg" />
<figcaption><code>fill Mode</code></figcaption>
</figure>
<h2>At Dimensions : 260px*400px</h2>
<figure>
<img class="second" src="http://t.imgbox.com/j8aQ81zq.jpg" />
<figcaption>Original</figcaption>
</figure>
<figure>
<img class="second fill" src="http://t.imgbox.com/j8aQ81zq.jpg" />
<figcaption><code>fill Mode</code></figcaption>
</figure>
</body>
</html>
该值contain
调整图像大小,使图像适合其内容框,同时仍保持其纵横比。这有两个目的。它避免了图像失真,同时将图像保持在内容框内。如果图像没有完全覆盖内容框,您可能设置的背景颜色会填满剩余空间。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>object-fit | Web前端之家www.jiangweishan.com</title>
<style>
body {
text-align: center;
}
h2 {
margin-top: 50px;
}
figure {
position: relative;
display:inline-block;
margin:0;
}
figcaption {
position: absolute;
top: 10px;
left: 10px;
background: black;
color: white;
padding: 5px 10px;
}
.first {
width: 260px;
height: 200px;
background: red;
}
.second {
width: 260px;
height: 400px;
background: yellow;
}
.contain {
object-fit: contain;
}
</style>
</head>
<body>
<h1>The <code>object-fit</code> Property: contain</h1>
<h2>At Dimensions : 260px*200px</h2>
<figure>
<img class="first" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/motorcycle.jpg" />
<figcaption>Original</figcaption>
</figure>
<figure>
<img class="first contain" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/motorcycle.jpg" />
<figcaption><code>contain Mode</code></figcaption>
</figure>
<h2>At Dimensions : 260px*400px</h2>
<figure>
<img class="second" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/motorcycle.jpg" />
<figcaption>Original</figcaption>
</figure>
<figure>
<img class="second contain" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/motorcycle.jpg" />
<figcaption><code>contain Mode</code></figcaption>
</figure>
</body>
</html>
contain
在您不知道图像的尺寸但仍希望它适合在已知宽度的容器内的情况下,该值可能很有用。
如果您希望图像完全填充其内容框内的空间并仍保持其固有纵横比,则应使用该cover
属性。在这种情况下,图像以这样一种方式缩放,即图像的较小边完美地适合包含框。然后裁剪溢出框的图像的任何部分。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>object-fit | Web前端之家www.jiangweishan.com</title>
<style>
body {
text-align: center;
}
h2 {
margin-top: 50px;
}
figure {
position: relative;
display:inline-block;
margin:0;
}
figcaption {
position: absolute;
top: 10px;
left: 10px;
background: black;
color: white;
padding: 5px 10px;
}
.first {
width: 260px;
height: 200px;
background: red;
}
.second {
width: 260px;
height: 400px;
background: yellow;
}
.cover {
object-fit: cover;
}
</style>
</head>
<body>
<h1>The <code>object-fit</code> Property : cover</h1>
<h2>At Dimensions : 260px*200px</h2>
<figure>
<img class="first" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/motorcycle.jpg" />
<figcaption>Original</figcaption>
</figure>
<figure>
<img class="first cover" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/motorcycle.jpg" />
<figcaption><code>cover Mode</code></figcaption>
</figure>
<h2>At Dimensions : 260px*400px</h2>
<figure>
<img class="second" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/motorcycle.jpg" />
<figcaption>Original</figcaption>
</figure>
<figure>
<img class="second cover" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/motorcycle.jpg" />
<figcaption><code>cover Mode</code></figcaption>
</figure>
</body>
</html>
要显示具有其固有尺寸的图像并忽略在包含框上设置的任何高度或宽度值,您可以使用none
. 在这种情况下,图像不会调整大小。但是,如果图像的任何部分位于其包含框之外,则它将被裁剪。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>object-fit | Web前端之家www.jiangweishan.com</title>
<style>
body {
text-align: center;
}
h2 {
margin-top: 50px;
}
figure {
position: relative;
display:inline-block;
margin:0;
}
figcaption {
position: absolute;
top: 10px;
left: 10px;
background: black;
color: white;
padding: 5px 10px;
}
.first {
width: 260px;
height: 200px;
background: red;
}
.second {
width: 260px;
height: 400px;
background: yellow;
}
.none {
object-fit: none;
}
</style>
</head>
<body>
<h1>The <code>object-fit</code> Property: none</h1>
<h2>At Dimensions : 260px*200px</h2>
<figure>
<img class="first" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/motorcycle.jpg" />
<figcaption>Original</figcaption>
</figure>
<figure>
<img class="first none" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/motorcycle.jpg" />
<figcaption><code>none Mode</code></figcaption>
</figure>
<h2>At Dimensions : 260px*400px</h2>
<figure>
<img class="second" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/motorcycle.jpg" />
<figcaption>Original</figcaption>
</figure>
<figure>
<img class="second none" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/motorcycle.jpg" />
<figcaption><code>none Mode</code></figcaption>
</figure>
</body>
</html>
我们的最终object-fit
值为scale-down
。顾名思义,它缩小了图像。这意味着它将调整大小,就好像它已被设置为none
或contain
基于哪个值导致更小的图像一样。换句话说,如果我们图像的任何尺寸都不大于其包含框的相应尺寸,none
则应用该值。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>object-fit | Web前端之家www.jiangweishan.com</title>
<style>
body {
text-align: center;
}
h2 {
margin-top: 50px;
}
figure {
position: relative;
display:inline-block;
margin:0;
}
figcaption {
position: absolute;
top: 10px;
left: 10px;
background: black;
color: white;
padding: 5px 10px;
}
.first {
width: 260px;
height: 200px;
background: red;
}
.second {
width: 260px;
height: 400px;
background: yellow;
}
.scale-down {
object-fit: scale-down;
}
</style>
</head>
<body>
<h1>The <code>object-fit</code> Property: scale-down</h1>
<h2>At Dimensions : 260px*200px</h2>
<figure>
<img class="first" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/motorcycle.jpg" />
<figcaption>Original</figcaption>
</figure>
<figure>
<img class="first scale-down" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/motorcycle.jpg" />
<figcaption><code>scale-down Mode</code></figcaption>
</figure>
<h2>At Dimensions : 260px*400px</h2>
<figure>
<img class="second" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/motorcycle.jpg" />
<figcaption>Original</figcaption>
</figure>
<figure>
<img class="second scale-down" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/motorcycle.jpg" />
<figcaption><code>scale-down Mode</code></figcaption>
</figure>
</body>
</html>
object-position属性
正如我们之前看到的,该cover
属性填充了包含框内的所有空间,同时仍然保留了图像的固有纵横比。默认情况下,图像也集中放置。在焦点位于中心的情况下,这将很好地为您服务。但是,如果图像的焦点不在中心怎么办?
酒店object-position
可以在这里为您提供帮助。它的工作原理就像background-position
. 下面的代码片段将图像的位置设置为左上角:
.zero-zero {
object-position: 0px 0px;
}
您可以使用百分比来代替以像素为单位指定尺寸。例如,object-position: 0% 0%
左上角和object-position: 100% 100%
右下角。当您不知道图像尺寸时,这会很有帮助。
当您的图像和它的包含框的纵横比相似时,设置object-position
似乎没有太大区别。但是,当纵横比明显偏离时,结果会有所改善。下面的 CodePen 演示说明了我的观点。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>object-fit | Web前端之家www.jiangweishan.com</title>
<style>
body {
text-align: center;
}
h2 {
margin-top: 50px;
}
figure {
position: relative;
display:inline-block;
margin:0;
}
figcaption {
position: absolute;
top: 10px;
left: 10px;
background: black;
color: white;
padding: 5px 10px;
}
.first {
width: 260px;
height: 200px;
background: red;
}
.second {
width: 260px;
height: 400px;
background: yellow;
}
.cover {
object-fit: cover;
}
.zero-zero {
object-position: 0% 0%;
}
</style>
</head>
<body>
<h1>The <code>object-position</code> Property</h1>
<h2>At Dimensions : 260px*200px</h2>
<figure>
<img class="first cover" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/sunset.jpg" />
<figcaption>Original</figcaption>
</figure>
<figure>
<img class="first cover zero-zero" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/sunset.jpg" />
<figcaption><code>Position: 0% 0%</code></figcaption>
</figure>
<h2>At Dimensions : 260px*400px</h2>
<figure>
<img class="second cover" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/sunset.jpg" />
<figcaption>Original</figcaption>
</figure>
<figure>
<img class="second cover zero-zero" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/sunset.jpg" />
<figcaption>Position: 0% 0%</figcaption>
</figure>
</body>
</html>
在第二种情况下,将位置设置为左上角会使太阳重新聚焦。
关于该属性的另一件事值得一提的object-position
是,它是可动画的,如果使用得当,可以产生惊人的效果。考虑下面的代码:
img {
/* other CSS here... */
object-fit: cover;
object-position: 0% 0%;
animation: ltr 5s alternate infinite;
}
@keyframes ltr {
0% {
object-position: 0% 0%;
}
25% {
object-position: 20% 0%;
}
100% {
object-position: 100% 100%;
}
}
使用此代码,我使用关键帧动画为图像的位置设置动画,如您所见,最终结果看起来很棒。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>object-fit | Web前端之家www.jiangweishan.com</title>
<style>
body {
text-align: center;
}
figure {
position: relative;
display: inline-block;
margin: 0;
}
figcaption {
position: absolute;
top: 20px;
left: 20px;
background: black;
color: white;
padding: 8px 15px;
}
img {
width: 540px;
height: 480px;
border: 10px solid black;
background: yellow;
object-fit: cover;
animation: ltr 3s alternate infinite;
}
@keyframes ltr {
0% {
object-position: 0% 0%;
}
50% {
object-position: 20% 0%;
}
100% {
object-position: 100% 100%;
}
}
</style>
</head>
<body>
<h1>Animating the <code>object-position</code> Property</h1>
<figure>
<img class="ltr" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/sunset.jpg" />
<figcaption>An Awesome Sunset</figcaption>
</figure>
</body>
</html>
当焦点从一个人转移到另一个人时,这也可能在视频中使用。
浏览器支持和 Polyfills {#browser-support-and-polyfills}
虽然这些属性可以证明非常有用,但您是否可以在现实世界中实际使用它们取决于您支持的浏览器。object-fit
除 IE/Edge 之外的所有主流浏览器object-position
都支持,并且除 IE/Edge 和 Safari 之外的所有主流浏览器都支持。
通常,您可能只需要该object-fit
属性。如果你愿意牺牲一些用户的用户体验,你可以继续使用这个属性。当您需要支持较旧的浏览器时,您可以尝试Federico Brigante 的 polyfill。