如何缩放CSS Sprite中的图像


157

本文(http://css-tricks.com/css-sprites/)讨论了如何从1个较大的图像中裁剪出较小的图像。您能否告诉我是否有可能/如何裁剪出较小的图像,然后在布局之前缩放裁剪的区域?

这是该文章的示例:

A
{
  background-image: url(http://www.jaredhirsch.com/coolrunnings/public_images/3deb155981/spriteme1.png);
  background-position: -10px -56px;
}

我想知道从spriteme1.png裁剪图像后如何缩放图像

这是示例的网址:http : //css-tricks.com/examples/CSS-Sprites/Example1After/

所以我想知道是否可以缩小项目1,2,3,4旁边的图标?


正如史蒂芬(Stephen)所问,是否有某些事情阻止您以所需的大小渲染图像?
Paul D. Waite,2010年

4
由于我一直在寻找相同问题的答案,所以我最终进入了此页面。在当今世界上具有高清晰度视网膜显示屏的世界中,习惯上要生成比所需大小大一倍的图像,然后在<img>属性或CSS样式中使用高度/宽度值将其减小为显示时高度/宽度的一半。这样可确保在智能手机和平板电脑上清晰显示。但是PNG精灵非常适合快速缓存和呈现。最好不仅使用2x图像的精灵,然后将其缩放到使其看起来也清晰的大小。
Art Geigel

由于原始问题从未得到接受的答案,并且有一个非常整洁且向后兼容的解决方案,因此我制作了一个新的Codepen Stretchy版本,因为原始网站不再在线并且可能还有些人需要向后兼容的解决方案。我用原著/作者的名字作了笔。
所有位等于

Answers:


131

您可以使用background-size,因为大多数浏览器都支持background-size(但并非所有http://caniuse.com/#search=background-size

background-size : 150% 150%;

要么

您可以将缩放组合用于webkit / ie并进行转换:scale用于Firefox(-moz-)和Opera(-o-),用于跨浏览器的台式机和移动设备

[class^="icon-"]{
    display: inline-block;
    background: url('../img/icons/icons.png') no-repeat;
    width: 64px;
    height: 51px;
    overflow: hidden;
    zoom:0.5;
    -moz-transform:scale(0.5);
    -moz-transform-origin: 0 0;
}

.icon-huge{
    zoom:1;
    -moz-transform:scale(1);
    -moz-transform-origin: 0 0;
}

.icon-big{
    zoom:0.60;
    -moz-transform:scale(0.60);
    -moz-transform-origin: 0 0;
}

.icon-small{
    zoom:0.29;
    -moz-transform:scale(0.29);
    -moz-transform-origin: 0 0;
}

3
在Chrome中效果很好,在FF,IE9 / 10中效果很好。大部分产生所需的效果。
RCNeil 2014年

使用(示例)背景大小:15%;适用于精灵,同时保持正确的宽高比。这是与响应站点上的断点一起使用的简单解决方案。
C13L0

1
background-size属性不适用于高度和宽度固定的svg子画面,但是scale可以解决问题。
安德烈(Andre)

要添加对IE8的支持,请使用-ms-zoom属性作为IE8标准模式下缩放的同义词。-ms-zoom:0.7;有关更多详细信息,请参见下面的链接:msdn.microsoft.com/zh-cn/library/ms531189
v

2
2017更新:包括IE9 +在内的所有主流浏览器均支持background-size。 caniuse.com/#search=background-size
Nathan Hinchey

29

使用精灵时,仅限于精灵中图像的尺寸。background-sizeStephen提到的CSS属性尚未得到广泛支持,并且可能导致IE8及以下版本的浏览器出现问题-并且鉴于其市场份额,这不是一个可行的选择。

解决该问题的另一种方法是使用两个元素并通过将其与img标签一起使用来缩放子画面,如下所示:

<div class="sprite-image"
     style="width:20px; height:20px; overflow:hidden; position:relative">
    <!-- set width/height proportionally, to scale the sprite image -->
    <img src="sprite.png" alt="icon"
         width="20" height="80"
         style="position:absolute; top: -20px; left: 0;" />
</div>

这样,外部元素(div.sprite-image)会从img标签中裁剪出20x20px的图像,其作用就像是scaled background-image


2
就像这里的 cletus和Quentin statet一样,这可能不是最好的方法。对我来说,这是一个大问题-我需要src通过CSS 进行分配。
Jook

-1:您不能将演示文稿元素与内容/数据混合。<img>仅应在内容的一部分中使用。出于设计目的,必须有背景图像。
Shahriyar Imanov

最佳答案(a)普遍适用,(b)是人类可以理解的,(c)简短,...(z)将表示与内容分开。
鲍勃·斯坦

18

尝试以下操作:可伸缩的Sprites-跨浏览器,响应式调整大小/拉伸CSS Sprite图像

此方法“响应式”缩放精灵,以便根据浏览器窗口的大小调整宽度/高度。它不被使用, background-size因为在较旧的浏览器中不存在对此的支持

的CSS

.stretchy {display:block; float:left; position:relative; overflow:hidden; max-width:160px;}
.stretchy .spacer {width: 100%; height: auto;}
.stretchy .sprite {position:absolute; top:0; left:0; max-width:none; max-height:100%;}
.stretchy .sprite.s2 {left:-100%;}
.stretchy .sprite.s3 {left:-200%;}

的HTML

<a class="stretchy" href="#">
  <img class="spacer" alt="" src="spacer.png">
  <img class="sprite" alt="icon" src="sprite_800x160.jpg">
</a>
<a class="stretchy s2" href="#">
  <img class="spacer" alt="" src="spacer.png">
  <img class="sprite" alt="icon" src="sprite_800x160.jpg">
</a>
<a class="stretchy s3" href="#">
  <img class="spacer" alt="" src="spacer.png">
  <img class="sprite" alt="icon" src="sprite_800x160.jpg">
</a>

3
该链接在这里并没有真正解释该理论。您正在使用具有溢出功能的div:在使用缩放图片的精灵图片上方隐藏为裁剪区域/窗口。这就是为什么它根本不使用背景图像的原因。只是在另一层之上的一层作为遮罩。
西蒙(Simon)

1
间隔必须是图像还是可以使用简单的div代替?
isapir

4
这是此的CodePen示例。它似乎仅适用于水平或垂直精灵。不是网格。
2013年

我制作了一个新的Codepen Stretchy版本,因为原始网站已不再在线,而且可能还有些人需要向后兼容的解决方案。我做了笔与原作/作者的归属
所有位等于

10

transform: scale(); 将使原始元素保持其大小。

我发现最好的选择是使用vw。它的工作就像一种魅力:

https://jsfiddle.net/tomekmularczyk/6ebv9Lxw/1/

#div1,
#div2,
#div3 {
  background:url('//www.google.pl/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png') no-repeat;
  background-size: 50vw;   
  border: 1px solid black;
  margin-bottom: 40px;
}

#div1 {
  background-position: 0 0;
  width: 12.5vw;
  height: 13vw;
}
#div2 {
  background-position: -13vw -4vw;
  width: 17.5vw;
  height: 9vw;
  transform: scale(1.8);
}
#div3 {
  background-position: -30.5vw 0;
  width: 19.5vw;
  height: 17vw;
}
<div id="div1">
  </div>
  <div id="div2">
  </div>
  <div id="div3">
  </div>


您好,这没有回答问题。您应该在同一张图片中显示三个具有不同比例的div。简而言之,它应该显示不同大小的“字体”。你能修好它吗?
罗伯特

嗨,@罗伯特。现在怎么样?
Tomasz Mularczyk

PS,您是否注意到使用大众测量单位的行为?
罗伯特

我不确定,这是什么意思?
Tomasz Mularczyk

VW VH与视口大小成比例缩放。到目前为止,我从未使用过它们。只是您对使用它们的经验的好奇。在您可能已经注意到的某些情况下,它们是如此“神奇”还是存在需要考虑的问题(意外行为)?谢谢
罗伯特

7

这就是我要做的。请记住,它不适用于IE8及以下版本。

#element {
  width:100%;
  height:50px;
  background:url(/path/to/image.png);
  background-position:140.112201963534% 973.333333333333%;
}

背景图像的宽度将随着父级的#element缩小而缩小。如果转换height为百分比,也可以对其高度进行相同的操作。唯一棘手的问题是找出的百分比background-position

第一个百分比是处于正常宽度时精灵的目标区域的宽度除以精灵的总宽度,然后乘以100。

第二个百分比是缩放后的小精灵目标区域的高度除以小精灵的总高度,然后乘以100。

这两个方程式的措词有些草率,所以请告诉我是否需要我更好地解释。


6

这似乎对我有用。

如果子画面在网格中,则将“ background-size子画面”数量设置为100%,将“ 子画面”数量设置为100%。然后使用background-position -<x*100>% -<y*100>%x和y是从零开始的精灵

换句话说,如果您想要左边的第二个精灵和第二行的2上方和1下方,

background-position: -200% -100%;

例如,这是一个精灵表4x2精灵

在此处输入图片说明

这是一个例子

div {
  margin: 3px;
  display: inline-block;
}
.sprite {
  background-image: url('https://i.stack.imgur.com/AEYNC.png');
  background-size: 400% 200%;  /* 4x2 sprites so 400% 200% */
}
.s0x0 { background-position:    -0%   -0%; }
.s1x0 { background-position:  -100%   -0%; }
.s2x0 { background-position:  -200%   -0%; }
.s3x0 { background-position:  -300%   -0%; }
.s0x1 { background-position:    -0%  -100%; }
.s1x1 { background-position:  -100%  -100%; }
.s2x1 { background-position:  -200%  -100%; }
.s3x1 { background-position:  -300%  -100%; }
<div class="sprite s3x1" style="width: 45px; height:20px"></div>
<div class="sprite s3x1" style="width: 128px; height:30px"></div>
<div class="sprite s3x1" style="width: 64px; height:56px"></div>
<div class="sprite s2x1" style="width: 57px; height:60px"></div>
<div class="sprite s3x0" style="width: 45px; height:45px"></div>
<div class="sprite s0x1" style="width: 12px; height:100px"></div>

<br/>
<div class="sprite s0x0" style="width: 45px; height:20px"></div>
<div class="sprite s1x0" style="width: 128px; height:45px"></div>
<div class="sprite s2x0" style="width: 64px; height:56px"></div>
<div class="sprite s3x0" style="width: 57px; height:60px"></div>
<br/>
<div class="sprite s0x1" style="width: 45px; height:45px"></div>
<div class="sprite s1x1" style="width: 12px; height:50px"></div>
<div class="sprite s2x1" style="width: 12px; height:50px"></div>
<div class="sprite s3x1" style="width: 12px; height:50px"></div>

如果精灵大小不同,则需要将background-size每个精灵的设置为百分比,以使精灵的宽度变为100%

换句话说,如果图像的宽度为640px,而该图片中的子画面的宽度为45px,则将45px变为640px

xScale = imageWidth / spriteWidth
xScale = 640 / 45
xScale = 14.2222222222
xPercent = xScale * 100
xPercent = 1422.22222222%

然后,您需要设置偏移量。偏移的复杂性是0%左对齐,而100%右对齐。

在此处输入图片说明

作为一名图形程序员,我期望100%的偏移量可以使背景在整个元素上移动100%,换句话说就是完全偏离右侧,但这并不是100%与一起使用时的意思backgrouhnd-positionbackground-position: 100%;表示右对齐。因此,在扩展后将其考虑在内的论坛是

xOffsetScale = 1 + 1 / (xScale - 1)              
xOffset = offsetX * offsetScale / imageWidth

假设偏移量为31px

xOffsetScale = 1 + 1 / (14.222222222 - 1)
xOffsetScale = 1.0756302521021115
xOffset = offsetX * xOffsetScale / imageWidth
xOffset = 31 * 1.0756302521021115 / 640
xOffset = 0.05210084033619603
xOffsetPercent = 5.210084033619603

这是一个带有2个子画面的640x480图像。

  1. 在31x 27y尺寸45w 32h
  2. 在500x 370y尺寸105w 65h

在此处输入图片说明

遵循上面精灵1的数学运算

xScale = imageWidth / spriteWidth
xScale = 640 / 45
xScale = 14.2222222222
xPercent = xScale * 100
xPercent = 1422.22222222%

xOffsetScale = 1 + 1 / (14.222222222 - 1)
xOffsetScale = 1.0756302521021115
xOffset = offsetX * xOffsetScale / imageWidth
xOffset = 31 * 1.0756302521021115 / 640
xOffset = 0.05210084033619603
xOffsetPercent = 5.210084033619603

yScale = imageHeight / spriteHEight
yScale = 480 / 32
yScale = 15
yPercent = yScale * 100
yPercent = 1500%

yOffsetScale = 1 + 1 / (15 - 1)
yOffsetScale = 1.0714285714285714
yOffset = offsetY * yOffsetScale / imageHeight
yOffset = 27 * 1.0714285714285714 / 480
yOffset = 0.06026785714285714
yOffsetPercent = 6.026785714285714

div {
  margin: 3px;
  display: inline-block;
}
.sprite {
  background-image: url('https://i.stack.imgur.com/mv9lJ.png');
}
.s1 {
  background-size:      1422.2222% 1500%;
  background-position:  5.210084033619603% 6.026785714285714%;
}
.s2 {
  background-size:      609.5238095238095% 738.4615384615385%;
  background-position:  93.45794392523367% 89.1566265060241%;
}
<div class="sprite s1" style="width: 45px; height:20px"></div>
<div class="sprite s1" style="width: 128px; height:30px"></div>
<div class="sprite s1" style="width: 64px; height:56px"></div>
<div class="sprite s1" style="width: 57px; height:60px"></div>
<div class="sprite s1" style="width: 45px; height:45px"></div>
<div class="sprite s1" style="width: 12px; height:50px"></div>
<div class="sprite s1" style="width: 50px; height:40px"></div>
<hr/>
<div class="sprite s2" style="width: 45px; height:20px"></div>
<div class="sprite s2" style="width: 128px; height:30px"></div>
<div class="sprite s2" style="width: 64px; height:56px"></div>
<div class="sprite s2" style="width: 57px; height:60px"></div>
<div class="sprite s2" style="width: 45px; height:45px"></div>
<div class="sprite s2" style="width: 12px; height:50px"></div>
<div class="sprite s2" style="width: 50px; height:40px"></div>


您如何计算offsetX和offsetY的值?
TryHarder

5

旧帖子,但这是我使用的内容background-size:cover;(@Ceylan Pamir的提示)...

示例用法
水平的圆形挡板(悬停在正面图像上,以不同的图像向后翻转)。

示例SPRITE
480px x 240px

最终尺寸示例
单个图片@ 120px x 120px

通用代码
.front {width:120px; height:120px; background:url(http://www.example.com/images/image_240x240.png); background-size:cover; background-repeat:no-repeat; background-position:0px 0px;}

.back {width:120px; height:120px; background:url(http://www.example.com/images/image_240x240.png); background-size:cover; background-repeat:no-repeat; background-position:-120px 0px;}

摘要案例案例
http://jsfiddle.net/zuhloobie/133esq63/2/


4

尝试使用背景尺寸:http//webdesign.about.com/od/styleproperties/p/blspbgsize.htm

有什么阻止您首先渲染想要的图像大小的图像吗?


我可以结合使用JavaScript和CSS来解决此问题吗?我尝试了背景尺寸;属性。我无法正常工作。由于某些原因,它无法缩放图像。
迈克尔

1
background-size是CSS 3,尚未得到广泛支持。
janmoesen

4
现在大多数浏览器版本都支持它。检查此caniuse.com/#search=background-size
kiranvj

4

我花了一些时间来创建对此感到满意的解决方案:

问题:

  • SVG图标精灵-例如80px x 3200px

  • 我们想要在各种位置的内容选择器(:before /:after)中以各种大小缩放它们的每次使用,而无需根据所使用的大小重新定义每个子画面的坐标。

因此,该解决方案允许您在仍缩放比例<button><menuitem>同时使用相同的精灵坐标。

[data-command]::before {
    content: '';
    position: absolute;
    background-image: url("images/sprite.svgz");
    background-repeat: no-repeat;
    background-size: cover;
}

button[data-command]::before {
  width: 32px;
  height: 32px;
}

menuitem[data-command]::before {
  width: 24px;
  height: 24px;
}

[data-command="cancel"]::before {
  background-position: 0% 35%;
}

[data-command="logoff"]::before {
  background-position: 0% 37.5%;
}

通过在背景位置使用百分比(到小数点后两位),而不是此处其他人建议的背景大小,您可以将同一图标声明缩放为任意大小,而无需重新声明。

y位置百分比是原始精灵高度/图标高度,以%表示-在我们的示例中,此处为80px * 100 / 3200px ==每个精灵由2.5%的y位置表示。

如果具有悬停/鼠标悬停状态,则可以将精灵的宽度加倍,并在position-x坐标中指定。

这种方法的缺点是,以后添加更多图标会更改子画面的高度,从而改变y位置的百分比,但是,如果不这样做,则子图形坐标将需要针对所需的每个缩放分辨率进行更改。


2

好吧,我认为找到了一种用于缩放图像的更简单的解决方案:示例-假设您要使用一个具有3个大小相等的精灵的图像,请使用CSS缩放图像

background-size : 300% 100%;

然后指定需要应用于html元素的自定义高度和宽度,例如:

 width :45%;
 height:100px;

示例代码如下所示:

.customclass {
    background: url("/sample/whatever.png") 0 0 no-repeat ;
    background-size : 300% 100%;
    width :45%;
    height:100px;
}

即时通讯对CSS来说还很陌生,样式并不是我的最佳领域,但这可能是错误的做法。.但是它在Firefox / Chrome / Explorer 10中对我有用,希望在旧版本中也能使用。


2

使用transform: scale(...);并添加匹配项margin: -...px以补偿缩放后的可用空间。(您可以* {outline: 1px solid}用来查看元素边界)。


2

2018在这里。使用背景大小和百分比。

片:

假设有一个精灵行。图纸的宽度应该是一个可以被100 +一个Sprite的宽度整除数字。如果您有30个大小为108x108像素的精灵,请在末尾添加额外的空白以使最终宽度为5508px(50 * 108 + 108)。

CSS:

.icon{
    height: 30px;  /* Set this to anything. It will scale. */
    width: 30px; /* Match height. This assumes square sprites. */
    background:url(<mysheeturl>);
    background-size: 5100% 100%; /*  5100% because 51 sprites. */
}

/* Each image increases by 2% because we used 50+1 sprites. 
   If we had used 20+1 sprites then % increase would be 5%. */

.first_image{
    background-position: 0% 0;
}

.ninth_image{
    background-position: 16% 0; /* (9-1) x 2 = 16 */
}

HTML:

<div class ="icon first_image"></div>
<div class ="icon ninth_image"></div>


0

设置精灵图像的包装元素的宽度和高度。使用此CSS。

{
    background-size: cover;
}

1
我不明白为什么这被否决了。为我工作。将发布我的方法作为答案。
克里斯,2015年

我在这里同意克里斯。这也解决了我的问题。不知道为什么它被否决了!
ShellZero

3
它不适用于sprite(请参阅问题标题),这就是为什么此解决方案不可行的原因。
迪姆科·德苏

-8

容易...在子画面的工作表上使用具有不同比例的同一图像的两个副本。在应用程序的逻辑上设置坐标和大小。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.