背景大小与背景位置一起使用时,不会对位置进行缩放?

16
我有一个由62张图片组成的精灵,每张图片大小为91 * 91像素,整个精灵大小为91 * 5642像素。它们以一种动态网格的形式显示,在用户/指针移动时会增长和缩小。有时,一个元素(标准的91 * 91像素)会放大到120 * 120像素。显然,我希望背景也能随之增大,以便在整个120 * 120元素中显示整个91 * 91像素的图像。
使用 background-size: 100% auto 使宽度始终完美。问题在于background-position也需要更新其值!所有62个元素都有内联 style = background-position等。我无法从内联更新背景位置。我想首先放置背景,然后再调整大小(缩放),而不是调整大小然后再定位(缩放到错误位置)。
我不确定我是否表达清楚了。为了澄清:
  • 所有元素都有样式width: 91px; height: 91px; background-size: 100% auto;
  • 第二个图像的内联样式将为background-position: 0 -91px
  • 当您将鼠标悬停在该元素上时,它会获得一个样式width: 120px; height: 120px;,然后它会显示第2张图像的大部分和第1张图像的一部分,因为定位发生在调整大小之后=(
  • 如果我更改背景位置(在缩放/悬停后)为0 -120px,则对齐正确。(但是当不缩放/悬停时,显然是错误的。)
使用实际的 zoom:1.3 transform:scale(1.3)是非常非常慢的。 过渡效果很慢。
CSS必须比这更聪明。具有background-size的精灵......那不是不可能吧!
编辑:带有示例fiddle:http://jsfiddle.net/rudiedirkx/g4RQx/
聪明的答案1:background-position: 0 calc(100% / 61 * 2)(61是因为有62张图像,2是第三张图像)。

在许多情况下使用精灵表有其优点,但在这种情况下使用单独的图像会节省很多麻烦。您需要使用精灵表的特定原因吗? - Turnip
看看这个问题的答案https://dev59.com/C3E95IYBdhLWcg3wKqsk 可能是一个可行的解决方案? - Devin Crossman
你使用了哪种过渡效果导致transform: scale()的使用变得“非常非常慢”?当你说慢的时候,是指帧率低吗?尝试使用transform: scale3d()来强制启用硬件加速如何? - BigMacAttack
你会考虑使用一些jQuery的解决方案吗? - Marc Audet
@MarcAudet 是的,如果它不重复CSS逻辑(例如缩放程度),并且可以在原生JS中重写。 - Rudie
显示剩余4条评论
6个回答

14

2
@Rudie 如果你采用这种方法,我建议在图像中添加足够的长度(即使只是空白空间),以允许使用简单的百分比 - 即将其设置为100 * 91像素长,这样你的数字就会变得容易处理且不会四舍五入。 - Matthew
好答案!这应该得到悬赏。 - Dom
非常感谢@Dom。事实如此,马修,最好使用圆整的数字,这样您就不会得到外星像素线了。 - rafaelcastrocouto
1
更好的写法:background-position: 0 -webkit-calc(100% / 62 * 0) http://jsfiddle.net/rudiedirkx/g4RQx/ - Rudie
1
都是你的,@rafaelcastrocouto。谢谢! - Rudie
显示剩余6条评论

5
在您的悬停状态下,根据比例缩放编辑背景位置。
a:hover {
    width: 120px;
    height: 120px;
    background-position: 0 -240px; /* -182px * 1.3186... */
}

FIDDLE


只是为了记录:在你的问题中,你提到缩放很慢。我尝试使用缩放,但我没有看到慢的过渡效果:

a:hover {
    transform: scale(1.3);
    transform-origin: 0 0;
    transition: all .5s;
}

FIDDLE


1
问题在于位置部分是内联的,并且每个图像都设置了位置,这就解释了为什么您需要针对每个<a>元素设置一个背景位置。 - Matthew
或者 - 我应该说至少那是我理解的方式。 - Matthew
是的,马修,你理解了。我需要在CSS中有62个不同的:hover状态。这是不可接受的。 - Rudie
@Danield 我会再试一下 scale()。一年前它非常慢。 - Rudie
这应该是一个正确的方法!这很棒! - Sarin Suriyakoon

3
如果您需要更平滑的过渡,那么这就是您需要的。

DEMO

DEMO2 带居中缩放。

HTML:

 Hover image large transition<br>
    Hover that:<br>
    
    <p><a href="#"></a></p>
    <p><a href="#"></a></p>
    <p><a href="#"></a></p>
    <p><a href="#"></a></p>
    <p><a href="#"></a></p>

CSS:

 p {
    margin: 0;
    display: inline-block;
    
}
a {
    display: block;
    border: solid 10px green;
    /* always: */
    width: 91px;
    height: 91px;
    background: black url(//hotblocks.nl/tests/gamessprite.gif) no-repeat 0 0;
    background-size: 100% auto;

    /* inline: */
    background-position: 0 -182px;
     -webkit-transition: all .5s;
    -moz-transition: all .5s;
    -o-transition: all .5s;
    transition: all .5s;
}
a:hover {
    -webkit-transform: scale(1.3);
    -ms-transform: scale(1.3);
    transform: scale(1.3);
    -webkit-transform-origin: 0 0;
    -ms-transform-origin: 0 0;
    transform-origin: 0 0;
    -webkit-transition: all .5s;
    -moz-transition: all .5s;
    -o-transition: all .5s;
    transition: all .5s;
}

Fiddle: fiddle


1
我建议您添加translate3d()。这样您就可以使用GPU加速。 - mtt
1
我在寻找一个不需要使用 scale() 的答案。这样就不需要使用 background-position 解决方案了。 - Rudie

-1

我认为答案应该很简单,

我已经更新了fiddle

请检查一下,

如果您像这样指定样式,它应该可以轻松解决问题...

a {
 display: block; /* always: */
 width: 91px;
 height: 91px;
 background: black url(//hotblocks.nl/tests/gamessprite.gif) no-repeat 0 0;
 background-size: 100% auto;
 /* inline: */
 background-position: 0% 3.30%; /* this will do the trick */ 
}
a:hover {
 width: 150px;
 height: 150px;
}

如有任何疑问,请回复...


-1

许多答案建议在background-pos中使用百分比而不是静态像素,但我有不同的方法。这有点奇怪... 但它有效! <-- fiddle

所以我在您的链接中添加了一个带有附加背景的span。而且,我没有使用内联background-position,而是在span上使用了百分比高度,就像这样:

<a href="#">
    <span style="height: 100%"></span>
</a>

使用这个CSS,你就可以满足所有需求,图片会自动适应。

a {
    display: block;
    overflow: hidden;
    width: 91px;
    height: 91px;
    position: relative;
}
a span{
    background: url(//hotblocks.nl/tests/gamessprite.gif) no-repeat 0 0;
    background-size: 100% auto;
    background-position: 0 0;
    position: absolute;
    display: block;
    bottom: 0;
    width: 100%;
}
a:hover {
    width: 120px;
    height: 120px;
}

如果您不使用其他解决方案,那么这是更多的HTML和CSS,但解决问题的方法越多越好 :)


太聪明了!如果我只有大约10个tiles,这种方法完全可以接受,但是我有62个tiles且数量不断增长,那么会出现巨大的<span>元素,即使它们只是部分可见也很耗费资源。虽然非常聪明,但成本昂贵,我还是会考虑其他方法。 - Rudie

-1

嗯...,你有几个问题。;-)
内联样式在所有方面都是“不好”的。其中一个原因是您无法使用任何外部CSS覆盖它们(由于其更高的特异性)。因此,这已经是为什么没有纯CSS解决方案的原因之一。

另一个原因是,您需要根据实际位置或精灵编号重新计算背景位置。目前还无法使用CSS进行此操作(例如:background position: 0 calc(nth-child * 91px);)

因此,唯一的纯CCS方法将使用缩放变换,这也相当好地支持

顺便说一下:“精灵的外观取决于我,所以如果将其设置为120 * 120网格而不是91 * 91,那会更简单...”
至少那样会更好。缩小总比放大质量好!

相反,使用JavaScript解决方案,特别是使用jQuery非常简单,因为您可以使用.index()函数,从而轻松计算新的背景位置。

结论:
目前还没有真正/实用的解决方案来处理CSS精灵!


您/客户可以使用!important覆盖内联样式。我无法使用jQuery的.index(),因为元素顺序不是精灵顺序。所有源图像都是91*91 =(,所以保存为120没有什么用处。transform: scale确实是最简单的方法,但性能非常差。(尽管上次尝试效果不错。)我主要是在寻找新的创意点子。有吗? - Rudie
好的,!important是一种可能性(个人从来不使用它),但正如之前所说,它不起作用,因为据我所知,没有CSS解决方案。至于JS的问题...,如果元素顺序不是精灵顺序,您还可以使用背景图像的当前坐标来计算新坐标。"我主要在寻找新的创意。有任何想法吗?"实际上没有!因为在我看来,使用一个图形(而不是60个或更多)是有意义的。不幸的是,没有其他方法可以通过CSS实现您的目标,只能使用比例变换。 - Netsurfer
源图像为91*91,可以制作1个精灵。我的意思是,同意使用transform: scale。这也可能是它被发明的原因=)不过,也许zoom: 1.3也可以用……带有负边距……哦,我会试试的。 - Rudie

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