如何使用CSS将图像大小调整为其自身的百分比?

149

我试图通过一个百分比来缩小一张图片的大小。例如,我只想将图片缩小一半,使其大小为原来的50%。但是应用 width: 50%; 将会将该图片大小调整为容器元素(可能是父元素,例如 <body>)的50%。

问题在于,我是否可以使用自身百分比来调整图片大小,而不使用JavaScript或服务器端?(我没有直接获取图像大小的信息)

我非常确定您无法这样做,但我只是想看看是否有聪明的仅使用CSS的解决方案。谢谢!


如果您使用 width: <number>%,它将占用包含元素的百分比。我认为没有其他方法可以做到这一点! - Aniket
10个回答

135

我为您提供两种方法。

方法1。

该方法仅调整图像的可视大小,而不是它在DOM中的实际尺寸,并且缩放后的可视状态位于原始大小的中心位置。

img {
  transform: scale(0.5);
}
<img src="https://via.placeholder.com/300x200" />

浏览器支持注释:浏览器统计数据显示在css中。

方法2。

#wrap {
  overflow: hidden;
  position: relative;
  float: left;
}

#wrap img.fake {
  float: left;
  visibility: hidden;
  width: auto;
}

#img_wrap {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

#img_wrap img.normal {
  width: 50%;
}
<div id="wrap">
  <img class="fake" src="https://via.placeholder.com/300x200" />
  
  <div id="img_wrap">
    <img class="normal" src="https://via.placeholder.com/300x200/cccccc" />
  </div>
</div>

注意: img.normalimg.fake 是同一个图片。
浏览器支持说明: 该方法在所有浏览器中都可以使用,因为所有浏览器都支持方法中使用的 css 属性。

这种方法的工作方式如下:

  1. #wrap#wrap img.fake 具有流动性。
  2. #wrap 具有 overflow: hidden 属性,以使其尺寸与内部图像 (img.fake) 相同。
  3. img.fake#wrap 中唯一没有绝对定位的元素,以避免破坏第二步。
  4. #img_wrap#wrap 中具有绝对定位,并且在大小上扩展到整个元素 (#wrap)。
  5. 第四步的结果是,#img_wrap 具有与图像相同的尺寸。
  6. 通过在 img.normal 上设置 width: 50%,其大小为 #img_wrap50%,因此是原始图像大小的 50%

2
这并不会将图像的大小调整为其原始大小的50%,而是现在是img_wrap的父级的50%。 - Wesley
我认为可以使用display:none代替visibility,就像我的代码一样。在你的例子中,虚假隐藏图像的空间仍然被“保留”,如果您在其周围放置内容,则会破坏布局。 - Wesley
4
“transform:scale()”的解决方案存在一个大问题。也就是说,它与CSS盒子模型的互动非常不协调,甚至可以说根本没有互动。因此,你会得到看起来完全错误的布局。参见:http://jsfiddle.net/kahen/sGEkt/8/。 - kahen
我喜欢变换选项,因为我可以轻松地添加动画效果(它是一个在悬停时变大的图像)。 - Moshe Shaham
刷新Fiddles时,使用新的工作图像而不是损坏的图像怎么样?那将会非常棒。 - mathheadinclouds
显示剩余3条评论

62
这肯定是使用容器元素方法中最简单的解决方案之一。
使用容器元素方法时,这个问题是这个问题的一个变化。诀窍是让容器元素收缩包裹子图像,这样它的大小就等于未调整大小的图像大小。因此,当将图像的width属性设置为百分比值时,图像相对于其原始比例进行缩放。
一些其他的可启用收缩包装属性和属性值是:float: left/rightposition: fixedmin/max-width,如链接的问题中所述。每种方法都有自己的副作用,但display: inline-block是一个更安全的选择。Matt在他的答案中提到了float: left/right,但他错误地将其归因于overflow: hidden

span {
  display: inline-block;
}

img {
  width: 50%;
}
<span>
        <img src="https://via.placeholder.com/300x200"/>
    </span>


编辑:正如trojan所提到的那样, 您还可以利用新引入的CSS3内在和外在尺寸模块:

figure {
  width: intrinsic;
}

img {
  width: 50%;
}
<figure>
  <img src="https://via.placeholder.com/300x200" />
</figure>

然而,在撰写本文时,并非所有流行的浏览器版本都支持它

有人知道如何修复不折叠的span边框吗? fiddle - CoR
这正是我需要的...简单快捷,谢谢。 我使用它如下:HTML: <img src="https://www.google.com/images/srpr/logo11w.png"/> CSS: img { display: inline-block; width: 15%; } - Chnikki
1
对于未来的读者:目前正确设置figure的值是width: fit-content;。现代浏览器的支持也更好了。 - Dániel Kis-Nagy
你是指 max-content 吗? - aindurti

17

缩放图片:

img {
  transform: scale(0.5);
}
<img src="https://via.placeholder.com/300x200" />


15

这是一个非常古老的帖子,但我在寻找一种简单的解决方案来在标准分辨率显示屏幕上显示高清(retina)屏幕截图时找到了它。

所以现代浏览器有一个仅使用HTML的解决方案:

<img srcset="image.jpg 100w" sizes="50px" src="image.jpg"/>

这是告诉浏览器该图像的尺寸是其预期显示尺寸的两倍。这些值是成比例的,不需要反映图像的实际尺寸。也可以使用2w 1px来达到相同的效果。src属性仅由旧版浏览器使用。

它的好处是在Retina或标准显示器上显示相同的大小,而在后者上缩小。


14

另一个解决方案是使用:

<img srcset="example.png 2x">

由于 src 属性是必需的,因此它无法进行验证,但它可以工作(除了任何IE版本,因为不支持 srcset)。


1
我在这个问题上感到矛盾,因为这个不进行验证,而@Max_B的方法虽然使用了一个小技巧,但是可以进行验证。嘿呀! - Chris Pink
1
实际上,@ChrisPink,自从发布这个答案后,我意识到你可以直接将相同的图像添加为src,这样就可以验证了。在支持srcset的浏览器中(所有现代浏览器),图像将始终被正确地调整大小。 - undefined

2
实际上,这是可能的。我在设计我的第一个大规模响应式设计网站时无意中发现了如何实现它。
使用overflow:hidden可以为包装器提供高度和宽度,而不需要使用clearfix hack来处理浮动内容。然后,您可以使用边距来定位内容。您甚至可以将包装器div设置为内联块。

.wrapper {
  position: relative;
  overflow: hidden;
}

.box {
  float: left; /* Note: 'float:right' would work too */
}

.box>img {
  width: 50%;
}
<div class="wrapper">
  <div class="box">
    <img src="https://via.placeholder.com/300x200" alt="">
  </div>
</div>


0
function shrinkImage(idOrClass, className, percentShrinkage){
'use strict';
    $(idOrClass+className).each(function(){
        var shrunkenWidth=this.naturalWidth;
        var shrunkenHeight=this.naturalHeight;
        $(this).height(shrunkenWidth*percentShrinkage);
        $(this).height(shrunkenHeight*percentShrinkage);
    });
};

$(document).ready(function(){
    'use strict';
     shrinkImage(".","anyClass",.5);  //CHANGE THE VALUES HERE ONLY. 
});

这个解决方案使用js和jquery,仅基于图像属性而不是父级进行调整大小。它可以根据类和id参数调整单个图像或一组图像的大小。

欲了解更多信息,请访问此处:https://gist.github.com/jennyvallon/eca68dc78c3f257c5df5


-2

我认为你是对的,就我所知,仅使用纯CSS是不可能的(我的意思是不跨浏览器)。

好吧,我不太喜欢我的答案,所以我想了一下。我可能找到了一个有趣的想法,可以帮助解决问题...也许它确实是可能的(虽然不是最漂亮的东西):

在Chrome、FF和IE 8&9中测试并且可行。但在IE7中无法工作。

#img_wrap {
  display: inline-block;
  position: relative;
}

#rescaled_img_wrap {
  width: 50%;
}

#original_img {
  display: none;
}

#rescaled_img {
  width: 100%;
  height: 100%;
}
<div id="img_wrap">
  <img id="original_img" src="https://via.placeholder.com/300x200" />
  <div id="rescaled_img_wrap">
    <img id="rescaled_img" src="https://via.placeholder.com/300x200/dddddd" />
  </div>
</div>


1
你的示例调整图像大小不成比例。 - Vladimir Starkov
1
你的方法使得通过调整窗口大小来缩小图像成为可能。 - Vladimir Starkov
这是因为您正在使用 inline-block,所以 #img_wrap 的宽度不仅取决于内部 HTML 宽度,还取决于上下文容器的宽度。 - Vladimir Starkov
据我所知,那个 display:none 图像没有起到任何作用,可以将其删除。或者是我漏掉了什么? - tremby

-3

这是一个不难的方法:

div {
  position: absolute;
}

img,
div {
  width: ##%;
  height: ##%;
}
<div>
  <img src="https://via.placeholder.com/300x200" />
</div>


2
这使它成为其容器的百分比,而不是自身大小的百分比。 - afilina

-3

虽然它并没有直接回答问题,但一种缩放图像的方法是相对于视口的大小(特别是宽度),这主要是响应式设计的用例。不需要包装元素。

img {
  width: 50vw;
}
<img src="https://via.placeholder.com/300x200" />


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