ChaBuku Bakke
ChaBuku Bakke

Reputation: 693

What is the proper use of high-res sprites on iOS with CSS?

I am having some serious trouble trying to get my sprites to show up right on a iPhone4+ using a high res (2x) version of my navigation sprite. Here's the code I'm using right now.

.pixelj a, .games a, .team a, .forums a {
    width: 156px;
    height: 35px;
    background-image: url('/assets/blogtext2x.png');
    background-repeat: no-repeat;
/*  background-size: 156px 17px;*/  
    text-indent: -9999px;
    overflow: hidden;
    display: block;
    float: left;
    }

As you can see this is for a navigation where I have all the navigation word elements in a single sprited image. I tried using "background-size" but that just squished the whole sprite into the width/height provided. If I get rid of it it shows the 2x images but doesn't make them 50% so they view correctly.

What am I doing wrong here? Here's the @media query I am using to target high-res devices:

@media (min--moz-device-pixel-ratio: 1.5),
  (-o-min-device-pixel-ratio: 3/2),
  (-webkit-min-device-pixel-ratio: 1.5),
  (min-device-pixel-ratio: 1.5),
  (min-resolution: 1.5dppx),
  (max-device-width: 640px) {

Upvotes: 1

Views: 849

Answers (1)

johnkavanagh
johnkavanagh

Reputation: 4674

You're absolutely on the right track here.

Essentially the process here with providing 'retina' graphics in a sprite via CSS is:

  • Set up your normal sprite, with the relevant positioning/etc within your CSS to feed to non-retina devices,
  • Set the background-size of this image,
  • Use a media query to feed the @2x variant of the image to those devices that support it.

There are a few key things to bear in mind:

  • setting background-size requires several declarations with different vendor prefixes to get the best browser coverage - see my code below to see what I mean
  • background-size is the size of the non-retina variant of the background image, not the size of the element it sits within. So, if the normal-size sprite image is 200px by 400px (and the high-resolution version is 400px by 800px), then it's 200px 400px that you declare.
  • background-size values are declared as <width> <height>.
  • You have to declare background-size in the first declaration, not in the retina media-query overwrite.
  • Although using @2x is becoming common-practice, it's not essential in web development: you could use a totally different image name.

It's very difficult to help you with your specific question without all the code, or a live URL to look at, but here's a high-level example.

In this example, I have a background-image which is 100px wide and 50px high which is positioned in the middle of the element

/* the element */
.element{
    background: url(../img/site/background-image.png) 50% 50% no-repeat;

    /* vendor-specfic declarations for background-size */
    -webkit-background-size: 100px 50px;
    -moz-background-size:  100px 50px;
    -o-background-size:  100px 50px;
    background-size:  100px 50px;
}

/* for retina users */
@media screen and (-webkit-min-device-pixel-ratio: 2), 
screen and (max--moz-device-pixel-ratio: 2),
screen and (min-device-pixel-ratio: 2){ 
    .element{
        /* we only over-write background-image here */
       background-image: url(../img/site/[email protected]);
    }
}

This will mean that those devices which fall into the second media query will load the @2x version of the background image, and will scale it to the background-size dimensions as declared.

Because the image is scaled back to the dimensions you set, if you're using sprites you only have to declare all the element's background-positions once as you usually would, and not twice to account for the larger retina graphic dimensions.

EDIT: Having now seen your site, I can see exactly the problem you're having with your navigation:

Screenshot

The reason it looks like this is your CSS here (line 972 of style2.css):

.pixeljam a, .games a, .team a, .forums a {
    background: no-repeat url('/assets/blogtext2x.png');
}

If you change that to background-image and remove the no-repeat, then it will work (otherwise background resets your previous background positions).

.pixeljam a, .games a, .team a, .forums a {
    background-image: url('/assets/blogtext2x.png');
} 

Upvotes: 2

Related Questions