【问题标题】:How can I scale an image in a CSS sprite如何在 CSS 精灵中缩放图像
【发布时间】:2011-01-26 16:14:18
【问题描述】:

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

这是该文章中的一个示例:

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

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

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

所以我想知道是否可以将Item1,2,3,4旁边的图标变小?

【问题讨论】:

  • 正如斯蒂芬问的那样,是否有什么东西阻止了你以你想要的尺寸渲染图像?
  • 我最终来到了这个页面,因为我正在寻找同样事情的答案。在当今使用高清 Retina 显示器的世界中,通常会构建比所需尺寸大两倍的图像,然后在显示时使用 属性或 CSS 样式中的高度/宽度值将其减小到一半的高度/宽度。这确保了智能手机和平板电脑上的清晰显示。但是 PNG 精灵非常适合快速缓存和渲染。最好不仅使用 2x 图像的精灵,然后将其缩放到使其看起来也清晰的大小。
  • 由于原始问题从未得到接受的答案,并且有一个非常简洁且向后兼容的解决方案,我制作了一个新的Codepen Stretchy 版本,因为原始网站不再在线并且maaaaybe仍然有些人需要向后兼容的解决方案。我用原始作品/作者的归属制作了这支钢笔。

标签: css css-sprites


【解决方案1】:

2021 年更新:大多数主流浏览器都支持背景大小,但如果您的移动浏览器不支持,请使用缩放。

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

background-size : 150% 150%;

或者

您可以将 zoom 用于 webkit/blink/ie 和 transform:scale 用于 Mozilla(-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;
    /* Mozilla support */
    -moz-transform:scale(0.5);
    -moz-transform-origin: 0 0;
}

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

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

【讨论】:

  • 在 Chrome 中运行良好,在 FF、IE9/10 中运行良好。在大多数情况下产生预期的效果。
  • 使用(示例)背景大小:15%;非常适合精灵,同时保持正确的纵横比。这是在响应式网站上使用断点的简单解决方案。
  • background-size 属性不适用于我的具有固定高度和宽度的 svg sprite,但是 scale 可以解决问题。
  • 要添加对 IE8 的支持,请使用 -ms-zoom 属性作为 IE8 标准模式下缩放的同义词。 -ms-缩放:0.7;更多详情请查看以下链接:msdn.microsoft.com/en-us/library/ms531189(v=vs.85).aspx
  • 2017 更新:所有主流浏览器都支持 background-size,包括 IE9+。 caniuse.com/#search=background-size
【解决方案2】:

当您使用精灵时,您受限于精灵中图像的尺寸。 Stephen 提到的 background-size 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 标记中裁剪出 20x20 像素的图像,其作用类似于缩放后的 background-image

【讨论】:

  • 像 cletus 和 Quentin statet here 一样,这可能不是最好的方法。对我来说,这是一个破坏者 - 我需要通过 css 分配 src
  • -1:您不能将演示元素与内容/数据混合。 &lt;img&gt; 只能在它是内容的一部分时使用。出于设计目的,背景图片是必须的。
  • 最佳答案 (a) 普遍适用,(b) 易于理解,(c) 简短,... (z) 将呈现与内容分开。
【解决方案3】:

试试这个:Stretchy Sprites - Cross-browser, responsive resizing/stretching of CSS sprite images

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

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>

【讨论】:

  • 该链接并没有真正解释这里的理论。您正在使用带有溢出的 div:隐藏为使用缩放版本的精灵图像之上的裁剪区域/窗口。这就是为什么它根本不使用背景图像。只是一层在另一层之上作为蒙版。
  • spacer 必须是图片还是可以用简单的 div 代替?
  • Here is a CodePen 这个例子。它似乎只适用于水平或垂直精灵。不是网格。
  • 我制作了一个新的Codepen Stretchy 版本,因为原来的网站不再在线,而且可能还有一些人需要向后兼容的解决方案。我用原始作品/作者的归属制作了这支钢笔
【解决方案4】:

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。简而言之,它应该显示不同大小的“字体”。你能解决它吗?
  • 嗨@罗伯特。现在怎么样?
  • P.S.您是否注意到使用大众测量单位的行为?
  • 我不确定,你的意思是什么行为?
  • 大众 VH 与视口大小成比例缩放。直到现在我才使用它们。这只是对您使用它们的体验的好奇。在您可能已经注意到的某些情况下,它们是否如此“神奇”或者是否存在需要考虑的问题(意外行为)?谢谢
【解决方案5】:

这似乎对我有用。

如果精灵在网格中,请将background-size 设置为 100% 的精灵数量和 100% 的精灵数量。然后使用background-position -&lt;x*100&gt;% -&lt;y*100&gt;%,其中 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-position 一起使用时的含义。 background-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

这是一张 640x480 的图片,带有 2 个精灵。

  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 的值的?
  • 简体:xOffsetPercent = 100 * offsetX / (imageWidth - spriteWidth)。 @TryHarder offsetX 是精灵表中精灵的偏移 x,以像素为单位。
【解决方案6】:

我就是这样做的。请记住,它不适用于 IE8 及更低版本。

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

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

第一个百分比是精灵在正常宽度下目标区域的宽度除以精灵的总宽度,再乘以 100。

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

这两个等式的措辞有点草率,所以如果需要我更好地解释,请告诉我。

【讨论】:

    【解决方案7】:

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

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

    示例精灵
    480 像素 x 240 像素

    最终尺寸示例
    单张图片@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;}

    缩写的 CASE FIDDLE
    http://jsfiddle.net/zuhloobie/133esq63/2/

    【讨论】:

      【解决方案8】:

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

      是否有什么东西阻止您以您想要的尺寸渲染图像?

      【讨论】:

      • 我可以结合使用 JavaScript 和 CSS 来解决这个问题吗?我尝试了背景大小;财产。我无法让它工作。由于某种原因,它不会缩放图像。
      • background-size 是 CSS 3,尚未得到广泛支持。
      • 现在大多数浏览器版本都支持它。检查这个caniuse.com/#search=background-size
      【解决方案9】:

      我花了一些时间来解决这个我很满意的问题:

      问题:

      • 图标的 SVG 精灵 - 比如说 80px x 3200px

      • 我们希望在内容选择器 (:before/:after) 中以各种尺寸缩放它们的每次使用,而不需要根据使用的尺寸重新定义每个精灵的坐标。

      因此,此解决方案允许您在 &lt;button&gt; 中使用与 &lt;menuitem&gt; 相同的精灵坐标,同时仍可对其进行缩放。

      [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%;
      }
      

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

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

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

      这种方法的缺点是以后添加更多图标会改变精灵高度和 y 位置 %,但如果你不这样做,那么你的精灵坐标将需要针对每个缩放分辨率进行更改你需要。

      【讨论】:

        【解决方案10】:

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

        【讨论】:

          【解决方案11】:

          好吧,我认为找到了一个更简单的缩放图像的解决方案:示例 - 假设您想要使用具有 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 中对我有用,希望它也适用于旧版本..

          【讨论】:

            【解决方案12】:

            这里是 2018 年。 使用带有百分比的背景大小。

            表格:

            这假设有单行精灵。工作表的宽度应该是一个能被 100 整除的数字 + 一个精灵的宽度。如果您有 30 个 108x108 像素的精灵,则在末尾添加额外的空白以使最终宽度为 5508 像素(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>
            

            【讨论】:

              【解决方案13】:

              transform: scale(0.8); 与您需要的值一起使用,而不是 0.8

              【讨论】:

                【解决方案14】:

                将宽度和高度设置为精灵图像的包装元素。使用这个 CSS。

                {
                    background-size: cover;
                }
                

                【讨论】:

                • 我不明白为什么这被否决了。为我工作。将发布我的方法作为答案。
                • 我同意克里斯的观点。这也解决了我的问题。不知道为什么它被否决了!
                • 它不适用于 sprite(查看问题标题),这就是该解决方案被否决的原因。
                【解决方案15】:

                简单...在精灵的工作表上使用不同比例的相同图像的两个副本。在应用的逻辑上设置坐标和大小。

                【讨论】:

                  猜你喜欢
                  • 2023-03-03
                  • 2020-12-02
                  • 2012-09-26
                  • 2019-04-15
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-03-25
                  相关资源
                  最近更新 更多