如何在 CSS 精灵中缩放图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2430206/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I scale an image in a CSS sprite
提问by michael
In this article, http://css-tricks.com/css-sprites/, it talks about how can I crop off a smaller image from 1 bigger image. Can you please tell me if it is possible/how I can crop off a smaller image and then scale the cropped off region before I lay it out?
在这篇文章http://css-tricks.com/css-sprites/ 中,它讨论了如何从 1 个较大的图像中裁剪出较小的图像。你能告诉我是否有可能/我如何裁剪较小的图像,然后在布局之前缩放裁剪区域?
Here is an example from that article:
这是那篇文章中的一个例子:
A
{
background-image: url(http://www.jaredhirsch.com/coolrunnings/public_images/3deb155981/spriteme1.png);
background-position: -10px -56px;
}
I would like to know how can I scale that image after I crop it from from spriteme1.png
我想知道从 spriteme1.png 裁剪后如何缩放该图像
Here is the URL of the example: http://css-tricks.com/examples/CSS-Sprites/Example1After/
这是示例的 URL:http: //css-tricks.com/examples/CSS-Sprites/Example1After/
So I would like to know if I can make the icons next to Item1,2,3,4 smaller?
所以我想知道我是否可以将Item1、2、3、4旁边的图标变小?
回答by aWebDeveloper
You could use background-size, as its supported by most browsers (but not all http://caniuse.com/#search=background-size)
您可以使用background-size,因为大多数浏览器都支持它(但并非所有http://caniuse.com/#search=background-size)
background-size : 150% 150%;
Or
或者
You can use a combo of zoomfor webkit/ie and transform:scalefor Firefox(-moz-) and Opera(-o-) for cross-browser desktop & mobile
您可以将webkit/ie的缩放和transform: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;
}
回答by Alex Gyoshev
When you use sprites, you are limited to the dimensions of the image in the sprite. The background-size
CSS property, mentioned by Stephen, isn't widely supported yet and might cause problems with browsers like IE8 and below - and given their market share, this isn't a viable option.
当您使用精灵时,您受限于精灵中图像的尺寸。background-size
Stephen 提到的CSS 属性尚未得到广泛支持,可能会导致 IE8 及以下浏览器出现问题 - 鉴于它们的市场份额,这不是一个可行的选择。
Another way to solve the problem is to use two elements and scale the sprite by using it with an img
tag, like this:
解决这个问题的另一种方法是使用两个元素并通过将精灵与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>
This way, the outer element (div.sprite-image
) is cropping a 20x20px image from the img
tag, which acts like a scaled background-image
.
这样,外部元素 ( div.sprite-image
) 从img
标签中裁剪出 20x20px 的图像,其作用类似于缩放的background-image
.
回答by tobyj
Try this: Stretchy Sprites- Cross-browser, responsive resizing/stretching of CSS sprite images
试试这个:Stretchy Sprites- CSS 精灵图像的跨浏览器、响应式调整大小/拉伸
This method scales sprites 'responsively' so that the width/height adjust according to your browser window size. It doesn't usebackground-size
as supportfor this in older browsers is non-existent.
此方法“响应式”缩放精灵,以便根据您的浏览器窗口大小调整宽度/高度。它不使用,background-size
因为在旧浏览器中不存在对此的支持。
CSS
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
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>
回答by Tomasz Mularczyk
transform: scale();
will make original element preserve its size.
transform: scale();
将使原始元素保持其大小。
I found the best option is to use vw
.
It's working like a charm:
我发现最好的选择是使用vw
. 它就像一个魅力:
https://jsfiddle.net/tomekmularczyk/6ebv9Lxw/1/
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>
回答by Tomasz Mularczyk
Here's what I did to do this. Keep in mind it won't work on IE8 and below.
这是我为做到这一点所做的。请记住,它不适用于 IE8 及更低版本。
#element {
width:100%;
height:50px;
background:url(/path/to/image.png);
background-position:140.112201963534% 973.333333333333%;
}
The background image's width will scale down as the parent of #element
scales down. You can do the same with its height, too, if you convert height
to a percentage. The only tricky bit are figuring out the percentages for background-position
.
背景图像的宽度将随着父#element
级缩小而缩小。如果转换height
为百分比,您也可以对其高度执行相同的操作。唯一棘手的一点是计算background-position
.
The first percentage is the width of the targeted area of the sprite when at normal width divided by the sprite's total width, and multiplied by 100.
第一个百分比是正常宽度时精灵的目标区域的宽度除以精灵的总宽度,再乘以 100。
The second percentage is the height of the targeted area of the sprite before being scaled divided by the sprite's total height, and multiplied by 100.
第二个百分比是缩放前精灵目标区域的高度除以精灵的总高度,再乘以 100。
The wording on those two equations is a little sloppy, so let me know if you need me to explain it better.
这两个方程的措辞有点草率,所以如果你需要我更好地解释它,请告诉我。
回答by gman
This seems to work for me.
这似乎对我有用。
If the sprites are in grid, set the background-size
to 100% number of sprites across and 100% number of sprites down. Then use background-position -<x*100>% -<y*100>%
where x and y are the zero based sprite
如果精灵在网格中,设置background-size
为 100% 的精灵数量和 100% 的精灵数量。然后使用background-position -<x*100>% -<y*100>%
其中 x 和 y 是基于零的精灵
In other words if you want the 3rd sprite from the left and 2nd row that's 2 over and 1 down so
换句话说,如果你想要左边的第三个精灵和第二行的 2 上和 1 下所以
background-position: -200% -100%;
For example here's a sprite sheet 4x2 sprites
例如,这是一个 4x2 精灵的精灵表
And here's an example
这是一个例子
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>
If the sprites are different sizes you'd need to set the background-size
for each sprite to the a percent such that that sprite's width becomes 100%
如果精灵的大小不同,您需要将background-size
每个精灵的设置为百分比,以便精灵的宽度变为 100%
In other words if image is 640px wide and the sprite inside that image is 45px wide then to get that 45px to be 640px
换句话说,如果图像是 640px 宽,并且该图像内的精灵是 45px 宽,那么让 45px 为 640px
xScale = imageWidth / spriteWidth
xScale = 640 / 45
xScale = 14.2222222222
xPercent = xScale * 100
xPercent = 1422.22222222%
Then you need to set the offset. The complication of the offset is that 0% is aligned left and 100% is aligned right.
然后你需要设置偏移量。偏移的复杂性是 0% 左对齐,100% 右对齐。
As a graphics programmer, I'd expect an offset of 100% to move the background 100% across the element, in other words entirely off the right side but that's not what 100% means when used with backgrouhnd-position
. background-position: 100%;
means right aligned. So, the forumla for taking that into account after scaling is
作为一名图形程序员,我希望 100% 的偏移量可以将背景 100% 移动到元素上,换句话说,完全远离右侧,但这不是 100% 与backgrouhnd-position
. background-position: 100%;
表示右对齐。因此,在缩放后考虑到这一点的论坛是
xOffsetScale = 1 + 1 / (xScale - 1)
xOffset = offsetX * offsetScale / imageWidth
Assume the offset is 31px
假设偏移量为 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
Here's a 640x480 image with 2 sprites.
这是带有 2 个精灵的 640x480 图像。
- at 31x 27y size 45w 32h
- at 500x 370y size 105w 65h
- 31x 27y 尺寸 45w 32h
- 500x 370y 尺寸 105w 65h
Following the math above for sprite 1
按照上面的数学计算精灵 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>
回答by chris
Old post, but here's what I did using background-size:cover;
(hat tip to @Ceylan Pamir)...
旧帖子,但这是我使用的内容background-size:cover;
(给@Ceylan Pamir 的提示)...
EXAMPLE USAGE
Horizontal circle flipper (hover on front side image, flips to back with different image).
示例用法
水平圆形翻转器(悬停在正面图像上,用不同的图像向后翻转)。
EXAMPLE SPRITE
480px x 240px
示例
精灵 480 像素 x 240 像素
EXAMPLE FINAL SIZE
Single image @ 120px x 120px
示例最终尺寸
单个图像@ 120px x 120px
GENERIC CODE.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;}
通用代码.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;}
.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;}
ABBREVIATED CASE FIDDLE
http://jsfiddle.net/zuhloobie/133esq63/2/
回答by stephenmurdoch
try using background size: http://webdesign.about.com/od/styleproperties/p/blspbgsize.htm
尝试使用背景尺寸:http: //webdesign.about.com/od/styleproperties/p/blspbgsize.htm
is there something stopping you from rendering the images at the size you want them in the first place?
有什么阻止你首先以你想要的大小渲染图像吗?
回答by Neil
It took me a while to create a solution to this problem I was happy with:
我花了一段时间来为这个我感到满意的问题创建一个解决方案:
Problem:
问题:
An SVG sprite of icons - say 80px x 3200px
We want to scale each use of them in content selectors (:before/:after) in various places over various sizes without re-defining the co-ords of each sprite based on the size used.
一个 SVG 图标精灵 - 比如 80px x 3200px
我们希望在不同大小的不同位置的内容选择器 (:before/:after) 中缩放它们的每次使用,而不根据使用的大小重新定义每个精灵的坐标。
So this solution allows you to use the same sprite co-ords in a <button>
as a <menuitem>
whilst still scaling it.
因此,该解决方案可让您使用相同的精灵共同ORDS的<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%;
}
By using percentages (to 2 decimal places) in background-position rather than background-size as suggested by others here, you can scale the same icon declaration to any size, without needing to redeclare it.
通过在 background-position 中使用百分比(到小数点后 2 位)而不是这里其他人建议的 background-size,您可以将相同的图标声明缩放到任何大小,而无需重新声明它。
The position-y percentage is the original sprite height/icon height as a % - in our case here 80px*100/3200px == each sprite is represented by a y-position of 2.5%.
position-y 百分比是原始精灵高度/图标高度,以 % 表示 - 在我们的例子中,80px*100/3200px == 每个精灵由 2.5% 的 y 位置表示。
If you have hover/mouseover states you can double the width of the sprite and specify in the position-x coordinate.
如果您有悬停/鼠标悬停状态,您可以将精灵的宽度加倍并在位置 x 坐标中指定。
The disadvantage of this approach is that adding more icons at a later date will change the sprite height and so y-position %, but if you don't do that then your sprite co-ordinates will need change for each scaled resolution you require.
这种方法的缺点是以后添加更多图标会改变精灵高度和 y 位置 %,但如果您不这样做,那么您的精灵坐标将需要针对您需要的每个缩放分辨率进行更改。
回答by adyry
Use transform: scale(...);
and add matching margin: -...px
to compensate free space from scaling. (you can use * {outline: 1px solid}
to see element boundaries).
使用transform: scale(...);
和添加匹配margin: -...px
来补偿缩放的可用空间。(您可以* {outline: 1px solid}
用来查看元素边界)。