Question

I've a sprite of 62 images of 91 * 91px, which makes the whole thing 91 * 5642 px. They're displayed in sort of a dynamic grid that grows and shrinks depending on user/pointer movement. Sometimes an element (std 91 * 91 px) zooms in to make it 120 * 120 px. Obviously I want the background to grow with so that the entire 91 * 91 px image is shown in the entire 120 * 120 element.

Enter background-size: 100% auto to make the width always perfect. Problem now is that background-position expects its values to be updated as well! All 62 elements have inline style=background-position etc. I can't update the background position from inline. I want the background to first position and then resize (zoom), not resize and then position (zoom to wrong position).

I'm not sure I'm making any sense. To clarify somewhat:

  • All elements have a style of width: 91px; height: 91px; background-size: 100% auto;.
  • The second image would have an inline style of background-position: 0 -91px.
  • When you hover that element it gets a style width: 120px; height: 120px; and then it shows most part of the 2nd image and some part of the 1st, because positioning happens after resizing =(
  • If I change the background-position (after zoom/hover) to 0 -120px, it aligns correctly. (But then obviously it's wrong when not zooming/hovering.)

A very easy solution would be to use actual zoom: 1.3 or transform: scale(1.3), but that's VERY VERY slow with transitions.

I must be missing something. CSS has to be smarter than this. A sprite with background-size... That's not impossible is it!?

How the sprite looks is up to me, so I could make it have a 120 * 120 grid instead of 91 * 91, if that would be simpler...

EDIT: With example fiddle: http://jsfiddle.net/rudiedirkx/g4RQx/

Smart answer 1: background-position: 0 calc(100% / 61 * 2) (61 because 62 images, 2 because 3rd image)

Était-ce utile?

La solution

it's actually pretty simple, just use percentage position.

background-position: 0 3.28%;

http://jsfiddle.net/g4RQx/18/

Autres conseils

In your hover state, edit your background position according to the scale ratio

a:hover {
    width: 120px;
    height: 120px;
    background-position: 0 -240px; /* -182px * 1.3186... */
}

FIDDLE


Just for the record: in your question you mentioned that scale is slow. I tried using scale and I didn't see slow transtions:

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

FIDDLE

If your requirement is smoother transition than this is what you need.

DEMO

DEMO2 with centered zoom.

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

Well ..., you have several problems. ;-)
Inline styles are "bad" in all ways. One is that you cannot override them with any external CSS (cause of their higher specificity). So this already one reason why there is no pure CSS solution for your problem.

Another reason is, that you would need to re-calculate the background-position depending on the actual position, respectively on the sprite number. Something you cannot do with CSS, yet (e.g. something like: background position: 0 calc(nth-child * 91px);)

So the only pure CCS way will be using the sale transform which also fairly good supported!

BTW: "How the sprite looks is up to me, so I could make it have a 120 * 120 grid instead of 91 * 91, if that would be simpler..."
That would be better at least. Downscaling is always better quality than upscaling!

A Javascript solution, especially with jQuery is quite simple on the opposite, as you can use the .index() function and so easily calculate the new background-position.

Conclusion:
At the moment there is no real/ practical solution for handling CSS sprites in such a way!

Many of the answers suggests percentage instead of static pixels in the background-pos, i however have a different approach. It's a bit wierd... but it works! <-- fiddle

So i've added a span inside your link with the background attached to it. And instead of your inline background-position, ive instead used height in percent on the span, like this:

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

And with this css it will be all you need and the image will fix the rest.

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

This is more html and css that you need if you dont use the other solutions, but the more ways to solve something the better :)

I think the answer should be simple,

I have updated the fiddle,

Please check it,

If you specify style like this, it should solve the problem easily...

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

Please reply if any concern...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top