如何设置图片的宽度和高度而不拉伸它?

128

如果我有:

#logo {
    width: 400px;
    height: 200px;
}
然后
<img id="logo" src="logo.jpg"/>

图片将会拉伸以填满该空间。我希望图片保持原始大小,但是在DOM中占据那么多的空间。我需要添加一个封装的 <div> 或者 <span> 吗?我不喜欢为样式而添加标记。


2
如果您仍在 Stack Overflow 上,是否考虑更新答案? - mikemaccana
13个回答

133

是的,你需要一个封装的div:

<div id="logo"><img src="logo.jpg"></div>

使用类似以下的方式:

#logo { height: 100px; width: 200px; overflow: hidden; }

其他解决方案(填充、边距)更繁琐(需要根据图像的尺寸计算正确的值),但也不能有效地使容器比图像更小。

此外,上述方法可以更轻松地适应不同的布局。例如,如果要将图像放在右下方:

#logo { position: relative; height: 100px; width: 200px; }
#logo img { position: absolute; right: 0; bottom: 0; }

7
你可以用 <figure> 标签来替换 <div> 标签:这样做有语义化的作用,并且如果需要的话,你可以为它添加标题 (<figcaption>)。https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figure - Mateus Leon
此外,如果是用于品牌推广,在网站展示中,请使用<h1>(如果是首页)或<p>(如果是其他页面),并将标题和alt属性应用于<img>,以便添加SEO友好的标记。它们也是块级元素,就像div一样,可以作为您的裁剪功能的包装器。 - Mateus Leon

120

2017年的回答

CSS object fit 在所有当前浏览器中都可以使用。它允许 img 元素变大而不拉伸图像。

您可以在 CSS 中添加 object-fit: cover;


2
你应该明确说明它适用于哪些浏览器。 - Nathan Tuggy
2
请查看以下链接以了解浏览器兼容性:https://caniuse.com/#search=object-fit - Alessia

30

将图像作为div的背景载入。

改为:

<img id='logo' src='picture.jpg'>


<div id='logo' style='background:url(picture.jpg)'></div>

所有浏览器都会裁剪图像中不适合的部分。这比包装一个溢出隐藏的元素有几个优点:
  1. 没有额外的标记。div只是替换了img。
  2. 轻松地将图片居中或设置为另一个偏移量。例如:url(pic) center top;
  3. 当足够小时重复图像。(好吧,我不知道为什么要那样做)
  4. 在同一语句中设置背景色,轻松地将相同的图像应用于多个元素,以及适用于背景图像的所有内容。

更新: 这个答案是在object-fit之前,现在你应该使用object-fit/object-position。

它仍然对旧版浏览器有用,用于额外属性(如background-repeat),以及边缘情况(例如,解决Chrome对flexbox和object-position的bug以及FF(前任?)与grid + autoheight + object-fit的问题。网格/ flexbox中的包装器div经常会产生...不直观的结果。


4
给出负一评分的用户请解释一下,以造福其他用户。就我个人而言,我已经使用这种方法获得了很好的效果,甚至在IE6和iOS上的Safari浏览器上也能运行良好。 - SamGoody
1
只是想补充一下 - 这通常是一个很好的方法。人们甚至为图像精灵表指定背景位置坐标以进行优化。然而,一个区别是它没有 <img> 元素具有的错误事件处理程序。 - badunk
我还向包含这些内容的 div 添加了一个类:background-repeat:no-repeat !important; float:left; width:100px; height:100px; - Nils
3
一些浏览器默认不打印背景图片,因此如果希望用户打印该页面,则这可能不是一个好的方法。 - Bennett McElwee
5
这不符合语义学上的正确性。如果这是有用的,为什么HTML5会增加更多与图像相关的标签,如figcaption、picture以优化语义呢?请按照原本img标签的设计使用它,停止将所有东西都替换为<div>标签。 - Mateus Leon
显示剩余2条评论

26

CSS3 object-fit

我不确定它已经被Webkit、IE和Firefox实现到了什么程度,但Opera的效果很棒。

object-fit可与SVG内容一起使用,但同样的效果也可以通过在SVG本身中设置preserveAspectRatio=""属性来实现。

img {
  height: 100px;
  width: 100px;
  -o-object-fit: contain;
}

Chris Mills在这里进行了演示:http://dev.opera.com/articles/view/css3-object-fit-object-position/


2
这真的很酷。太遗憾了,支持有限.. 看起来Chrome 32是第一个不需要供应商前缀就支持它的。 - Josh Crozier
太棒了,完美运作。只需添加一个属性就解决了所有问题。我只需要在Chrome上使用它,它就能正常工作。是的,没有厂商前缀。谢谢。 - whyAto8

15
#logo {
    width: 400px;
    height: 200px;

    /*Scale down will take the necessary specified space that is 400px x 200px without stretching the image*/
    object-fit:scale-down;
}

9
创建一个 div 并给它一个类。然后在其中放置一个 img。
<div class="mydiv">

<img src="location/of/your/image" ></img>

</div>

设置您的 div 尺寸并使其相对定位。

    .mydiv {
        position: relative;
        height:300px;
        width: 100%;
        overflow: hidden;
    }

然后为你的图片添加样式

img {
    width: 100%;
    height: auto;
    overflow: hidden;
}

希望这有所帮助。

7
<img style="object-fit: contain" src="...">

对我来说完美地工作了。


1
这就是我最终使用的。 "object-fit: cover" 以某种方式破坏了图像,但是 "contain" 正好满足了我的需求。它使所有图像都能够显示而不会被拉伸、扭曲等,无论它们是纵向还是横向。 - CaptainGenesisX

3
您可以按如下方式使用:

代码示例:

.width100 {
  max-width: 100px;
  height: 100px;
  width: auto;
  border: solid red;
}
<img src="https://www.gravatar.com/avatar/dc48e9b92e4210d7a3131b3ef46eb8b1?s=512&d=identicon&r=PG" class="width100" />


1
我需要添加一个封装的
吗?
我认为你需要。唯一想到的是填充,但这需要事先知道图像的尺寸。

0
如果使用flexbox对您来说是一个有效的选择(不需要支持旧浏览器),请查看我的另一个答案这里(可能与此重复):
基本上,您需要在div中包装img标签,您的CSS将如下所示:
.img__container {
    display: flex;
    padding: 15px 12px;
    box-sizing: border-box;
    width: 400px; height: 200px;

    img {
        margin: auto;
        max-width: 100%;
        max-height: 100%;
    }
}

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