Best practices for CSS sprite image [closed] - html

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I was looking around to find some best practice and hints when building css image sprite.
The questions:
Consider a site with lots of images:
Should I group and put images with approximately same size in one png?
What is the acceptable sprite image size? Is it recommended to make different sprite images, instead of one huge file?!
Is there any recommendation for number of images in one sprite image ?!
Is it make any difference on how to put and align images in the sprite image? I just find a hint at http://webdesign.tutsplus.com/articles/css-sprite-sheets-best-practices-tools-and-helpful-applications--webdesign-8340 which mentioned (keep images Organized, it will be more maintainable) but is it the only reason
If it helps:
I use compass sprites utility, and it automatically convert a folder of images to one png file and creates a css file for it. The images aligned under each other automatically

Should I group and put images with approximately same size in one png?
While Michael has a good point on grouping images by usage, you may also want to keep in mind that the optimal sprites have as little whitespace as possible. Saving file requests is awesome, but you do not want to load a bunch of unused pixels instead.
What is the acceptable sprite image size? Is it recommended to make different sprite images, instead of one huge file?!
Imagine a website with a huuuuge collection of icons, buttons and other graphical elements. Now image you put all those elements in one sprite, because, you know, low amount of requests and all. The sprite is 5MB big.
A visitor enters the page, and loading begins. Text appears, but you are still waiting for Megasprite to download. Depending on the filesize and the internet connection, a visitor has to wait a potentially long time before crucial (navigational) elements of the site are usable.
For a simple site a single sprite will do, but when things get more elaborate, it might be beneficial to use a couple of sprites. Furthermore, putting all your images in one sprite is a pain in the gluteus maximus when it comes to maintenance (although automation helps a lot). All in all, huge sprites are bad sprites.
Is it make any difference on how to put and align images in the sprite image?
Not really. There are a few thing you should keep in mind though. First of all, you want the sprite to be as compact as possible; the less unused space the better. However, that may force you to do ridiculous meticulous positioning in CSS. If you're willing to set background-position for each element by hand that's no problem, but nobody will blame you for cheating a little bit and using positions that are easier to work with.
One more thing
Have you considered using SVG sprites? Small in file size, perfectly smooth and crisp at every resolution. CSS Tricks has excellent articles on it here and here

To question 1:
From my experience in working on a large mobile service provider website, it is certainly a good idea to group images together, but probably better grouped logically, by what component or section of the project they belong to, rather than size. So I would group sprites that make a border (sides, rounded corners, etc.) or background images together.
It will make bits of them easier to find and to maintain during development.
On the other hand, if you're making a game and you have all your images created already (e.g. 64 images of animated character) You might as well stick them all in the one file.
Hope this helps.
Michael

What are CSS Sprites?
CSS Sprites is a method of combining multiple images used throughout your website into one big image. You can then use the proper background-position CSS attribute to load the particular image you want from your CSS Sprite using the X and Y coordinates.
CSS Sprites and Website Performance
A lot of people are under the assumption that it would be faster to reduce image file sizes and load every image individually. This is not true, in fact, it’s quite the opposite. The reason for this is because every time you make an HTTP request (whether it’s in your HTML code or your CSS code) you essentially create one more connection that has to occur in order to fully load a given page. So, for instance, if you have a page with 16 background images (as referenced in your website’s CSS file) that means that in order for that page to load it has to make 16 individual HTTP requests for each of those images. That’s not to mention any additional HTTP requests that will have to be made for stylesheets, JavaScripts, etc..
By combining all 16 of those background images into one big CSS Sprite the website only has to make one HTTP connection instead of 16 individual connections. This also means that anytime an image needs to be loaded on the fly (i.e. a rollover image) that image will already be loaded without any delay thanks to the fact that it’s already been loaded as part of your single CSS Sprite file.
So, not only are you drastically increasing performance by reducing the amount of connections but you can also take advantage of your CSS Sprites by using CSS image preloading.
How to Make a CSS Sprite
When it comes to creating CSS Sprites you’ve got two options. If you’re proficient enough with a photo editing program such as Adobe Fireworks or Adobe Photoshop then you’ll have no problem creating a CSS Sprite. For people who aren’t as savvy with those sorts of programs we recommend using SpriteMe. SpriteMe is a bookmarklet. After you’ve added it to your bookmarks bar, you simply go to any website and click the SpriteMe bookmarklet. SpriteMe will then open up an overlay over the right side of your screen with everything you need. You’ll also find that there is a demo on the SpriteMe site which will greatly assist anyone who isn’t as knowledgable.
Here’s an example of what a CSS Sprite would look like (this was created in Adobe Fireworks):
CSS Sprite Example
The above is an example of what a CSS Sprite might look like. Keep in mind there are a lot of different ways to do this. Some people like to leave 1 pixel of space in between each image just to provide some space. Other people like to leave a substantial amount of space between images. You’ll also find some people who like to stack things next to each other in rows to maximize the use of space. The bottom line is that there really isn’t a wrong way of doing this. So, with that being said consider the above example just that, an example.
Implementing the CSS Code
Now that you’ve finished making your CSS Sprite it’s time to get down to the nitty gritty and put CSS code in place so that we can actually make use of our CSS Sprite. For our example we’ll use the CSS Sprite above and show you how we made it work with the ‘Submit Comment’ button on our Comment Form at the bottom of this post.
#commentform input[type=submit] {
width: 122px;
height: 26px;
border: 0px;
background-color: #FFFFFF;
background-color: #FFFFFF;
background: url(/images/btn-sprite.png) no-repeat 0px 201px;
}
#commentform input[type=submit]:hover {
cursor: pointer;
background-position: 0px 175px;
}
Basically the trick here in using the CSS Sprites in your code is that you’re referencing the X and Y axis from the CSS Sprite. In this case the CSS code uses the background attribute, references the image URL, and finally addresses the X and Y axis which happen to be 0px for both.
The hover version of the button doesn’t have to reference the background image URL since it’s already been referenced above. Instead you simply need to change the Y axis to 175px to reflect the fact that the hover state of the button is above the non-hover state of the button.
I realize this might initially come off as confusing but I promise you once you play around with it you’ll see it’s actually very simple. If all of the CSS Sprite images are aligned to the left then your Y axis always remains at 0 pixels. This is one reason we prefer to stack our images all aligned to the left since it takes a lot of the guess work out of it. Given that your Y axis would always be the same in this case the only thing that would change is your X-axis. So, if the non hover button is at 0 pixels on the Y-axis and 201 pixels on the X-axis then the hover button above it would be at 0 pixels on the Y-axis and 175 pixels on the X-axis.

Related

Are svg images harder to render for a browser than bitmaps?

So I am making this horizontal scroll site which has a ton of images. I planned on using svgs for the entire site, but with only 20-30 svg images of medium to high complexity used in the page, and chrome already seems to be showing som jank and high paint times for scroll (and firefox is even worse, though safari seems to do a lot better).
Scroll timeline
View the site (scroll works on mac only, windows users can use arrow keys)
My question is, if I were to use pngs instead of svgs, would it reduce the paint times and hence the jank? Why is the browser struggling with only around 20 odd svg images?
As was my doubt, the problem turned out to be something completely different. Browsers are more than capable of handling multiple vector images. But what they aren't good at (and understandably so) is at redrawing those images very often.
Problem
My long horizontal scroll site was quite wide (30,000px). I had a background-color property applied to one of lower z-index'ed div's to represent the sky throughout the scroll site. I didn't want the sky to stretch the entire 30,000px since it essentially didn't change much, and hence gave it viewport width and height, with:
position:fixed;
Not a very smart move. Turns out that this property was causing my document layer to be repainted on every frame. Initially I though it was normal for browsers to do so on scroll, since Robby Leonardi's site, which I used as reference also repainted every frame.
Solution
Thanks to this article by one of the chrome dev tools developers, I set aside conventional wisdom, and make the sky layer
position:absolute;
and stretched it the entire site width, and boom! The paint rectangles were gone. And the scroll performance was smoother than butter.
Other solutions I tried
Hiding elements not near the viewport to make painting lighter, as suggested by #philipp, but didn't yeild any appreciable difference. Also, it felt super-hacky, and it wasn't targeting the root cause of the problem.
I tried modularizing my site into scenes and using translateZ(0) hack on each scene so that only the smaller scenes get repainted instead of the document. This actually helped quite a bit, and scroll was decent. Then,
I gave all the svg images their own layer by using translateZ(0). I started getting FPS of around 60 now, but again, this wasn't the right way of doing things.
I once had a similar thing. The SVG was 10 or more times as wide as the one shown above, it contained ~20k elements and was about 3MB in size. The only Thing what brought back performance (since it was a jump and run game) was an algorithm which was able to find all elements whose bounding box overlapped the viewport. With this I could use display: none; to hide everything what is invisible.
That reduced the amout of visible elements to ~150 per frame and the game ran again fluently.
I used a balanced binary tree (avl tree) and a one dimensional range query, since the height of the viewport was always the same as the image.
Good luck!
[EDIT]
Forgot to leave something like an anwer. From my Experience are large/huge SVG Graphics a bottleneck in rendering, especially if there is a lot of scripting happening. If you do not need any Interactivity with the elements from the Graphic, so nothing than a large Background Image, I would recommend to use a Tile map, based on PNG images, that is the standard way in Jump'n'Run games with huges »worlds«, so you can gain perfomance in two Points:
Rendering is faster,
You can »lazy ajax load« tiles, depending on visibility, to prevent users to download the »whole world« at startup.
Additinally you could use something like PIXI.js to render with WebGL, what will push the performance drastically and with it comes support for Tilemaps and Spritesheets.
If you insist on the advantages of Vector Grafics (Scaling, Interactivity) than you need to find a way to hide as much elements as possible to keep the frame rate high.

Is it possible to accomplish the equivalent of a Flash-driven webcomic (zoom, drag, fade in, synced audio etc) using HTML5 techniques?

Bit of background
I've been producing a Flash-driven webcomic for three years now, incorporating some basic animation, a synced soundtrack and zoom-drag page viewing. The recent Flash-bashing, my desire to reach iHandhelds and my preference for open versus proprietary means that I want to make the move to HTML5 techniques this year. In the long-term, I think the writing's on the wall for Adobe's product, and I'm not entirely convinced that's a bad thing.
I'm relatively comfortably with both CSS and HTML, having worked a little in web design before. However, JavaScript is a foreign country to me, and I simply wanted to get some advice as to
whether what I want to achieve can be accomplished consistently across all browsers and
what the best techniques/approaches to the problem would be.
Any advice, even general principles, are very welcome. I've already sought out several HTML5 tutorials and introductions, which lead me to believe that the canvas element will be foundational to my plan; however while all the individual problems I face have been answered by many blogposts and guides, combining the various solutions into a single entity is something I'm not currently able to figure out, as I'm not certain of the limitations of the new HTML5 tags, or of best practice.
If I'm successful in achieving what I'm after, I'm going to post the full code online with an explanation of all the elements. Webcomics might not be a huge domain, but having a resource that did this would have made my life a lot easier - hopefully it'll help someone else in a similar position.
What I'm after
Here's a diagram giving the basics of the design requirements. I'll explain the elements, and the desired extras, below.
(Perhaps the simplest way to demonstrate what I'm after would be for interested folks head over to my website and see how my comic currently works. This isn't a plug - it would simply give the quickest insight.)
At core, I'm after a viewer that will:
display text (SVG image) in a canvas element above an raster image the page's panel art
both images should be zoom-and-draggable in sync but should ideally fade in separately, with the raster image coming first, followed by the SVG image
I'm guessing that the best way to accomplish this would be to layer two canvas elements one above the other using z-index, with the SVG file in the uppermost element. These could then be nested, as in the diagram, within a div element that would carry the zoom-drag function. Is this a reasonable approach, or are there more efficient options?
The next and previous buttons are self-explanatory. Would it best to have each page (bearing in mind some will involve animation and music) on a separate page, or to have all pages within a chapter on a single page, with the buttons making them visible progressively? I imagine this would have a great impact on loading speeds.
Finally, I'd like to have the viewer capable of displaying fullscreen if the reader desires. I imagine this could be accomplished by using Javascript to make the canvas elements and their surrounding div switch between different CSS giving a px-defined size and 100% height and width. Is this a good approach? Is it possible to apply the size change to the div element only and have the canvas elements automatically follow suit, possibly by defining their size via % in CSS?
Desired extras
At various points in the comic I make use of basic animation techniques - simple movements of layered raster images across the viewing pane. This would be simple to accomplish, I imagine, using Javascript; am I correct in thinking that applying overflow:hidden to the wrapping div will prevent images larger than the viewing area from spilling outside the viewer area?
I also want to synchronise audio with some of these animations. I understand that synchronising canvas events with the audio would be the best way to do this on, permitting both to begin activity only upon page loading or next button click.
That's about everything. As said, any advice at whatever level would be greatly appreciated, even if it's 'yes' or 'no' to the various questions I've asked. At root, it would also be good to know if HTML5 is the best option for what I'm after or whether (with gritted teeth) I should stick to Flash for now and go after handhelds using Adobe AIR.

Why use a sprite sheet rather than individual images?

One thing I have noticed on some sites is that they use one BIIIIIIIG image containing lots of little images, then use CSS background-position to define the coordinates of each image, rather than use individual images.
Here's where I'm at:
Cons for using big sprite sheet
Need to load a large image to just display even one small image
Need to write (or generate) a long stylesheet with a class for each image
Cluttering CSS with lots of class definitions may impact performance
If one image changes (or another is added), cache problems may be encountered both on the image and the CSS associated with it
Requires a <div> with proper styling (display: inline-block; width: 32px; height: 32px; background-image: url('spritesheet.png');) which adds yet another class to the mix.
Many more that I can't remember now I'm typing them.
Pros for using big sprite sheet
... Erm... none yet.
In fact the only thing that comes close to a pro here is that when I cut up the sheet into individual images the resulting folder took up 3Mb on disk (due to each file being <100 bytes and my allocation size being 4k). The actual files themselves come out less than half the size of the sheet and CSS, so even with the overhead of an HTTP request there is a significant space saving.
Basically, my question is: Does anyone have ANY pros for using a big sheet over individual images?
The aim is to reduce HTTP requests. In addition, sometimes the compressed sprite will weigh less than the original images.
Recently I had a website with a lot of transparent gradients (white to trans, grey to trans) and some black and white on transparent images. By putting them all in a sprite and reducing the colors in the png to 8 I could get the sprite to be smaller in filesize than the original images (just... it was about a 0.5% saving). By reducing the number of HTTP requests from 10 to 1 though meant the site loaded faster (if measuring time from first connection to all data transferred).
In that case, a measurable increase was found.
I agree though that it's possible to mess things up and to end up with a larger sprite than needed, especially if you aren't using PNG compression.
Note two years after posting this – if you are using SSL, you should look into SPDY (my note in a further two years will mention HTTP 2.0 instead of SPDY!). SPDY negates the benefits of spriting.
Not much of what you said as Cons really are cons at all.
When you load one large image, it contains only one of the different attributes that an image needs (color table, mime type etc ex: imagine if you're using a progressive jpg format, one spritesheet will allow the image to be scanned once, whereas many will decrease load time significantly) instead of having the same information in 100 different files, it will lessen the filesize in the big picture.
Also there will only be ONE http request (or two, depending on how many spritesheets you have.) but if handled properly, only one per pageload.
If you're using bg images in CSS, then you already have made the css selectors so there is no extra work, just copy/paste the url.
I've never encountered any cache problems with spritesheets that can't be solved by pressing ctrl+F5.
It doesn't require a div with proper styling in any case at all.
This is not an <img> tag replacement method, it's used primarily for bg images. Like for buttons and icon sets.
The pros far outweigh the cons in this method, the proof is that it has been taken up into use by so very many developers. If it were a terrible method, nobody would have picked it up and somebody would have already raised these issues when it was first put into use.
If anyone has more to add, don't be shy :)
Google describes it here. Basically it should reduce page loading time. Every new connection initialization adds some delay. In some cases it can also reduce data transfer size and therefore also reduce page loading time. It is suitable for images that change rarely or all together (themes). Then browser can use cached image and needs to check only one file for changes not every image one by one.
Sprite sheets are a mess. Period. No need to sugar coat it. They present a massive step backwards in design technology, which probably explains why the only people who like using sprite sheets are old school game developers. Sprite sheets only have one redeeming quality, they are a little faster to load. Other than that, they are garbage. Not to mention a nightmare to set up.
In what world is it "acceptable" to have to include 500 lines of code just to run a simple walk cycle. Hopefully some clever guys will come up with a solution as simple as dragging a self contained, alpha-supporting video format such as flv, but that would also run on tablets...
If you feel like writing a massive list about how great sprites are, I can only wonder how boring your design job must be. The bottom line is that if a "tool" is making it harder for you to do things which should be easy, then it's not a good tool. Throw it away.
Yes - number of requests.
Most browsers will only download around 2 resources per domain in parallel, so if you serve up a lot of small images, the user has to wait for for around half that many HTTP request-response cycles. If you use a sprite, that's only one request and one response (albeit a bigger response).
If you have many images, the browser will need to download each and every one of them. Since the browser can only download a limited number of files simultaneously, this will take time. A single image will only tie one download slot allowing the page to render faster.
Additionally, if used in many other pages, the large sprite sheet will already be cached.
this is specially good for a lot of small images, because the browser only has to do an http request for all the images, and not hundreds of them. So you're web loads much faster on the client browser.
the thing is loading speed. Only one http request is quite faster than dozens of them.
Also, it helps keep your CSS cleaner. For instance, I use sprites for buttons (which also means no extra delay for loading the hover state img)
<button type="submit" class="vorige"><span>Vorige</span></button>
button {display: block; width: 162px; height: 47px; background-position: 0 0;}
button:hover {background-position: 0 94px; cursor: pointer;}
button:active {background-position: 0 47px;}
button span {display: none}
.vorige {background-image: url(../img/button/btn_vorige.png);}
.volgende {background-image: url(../img/button/btn_volgende.png);}
.verstuur {background-image: url(../img/button/btn_verstuur.png);}
because of the sprite I can leave out the code for a seperate hover image:
.vorige:hover {background-image: url(../img/button/btn_vorige_active.png);}
.volgende:hover {background-image: url(../img/button/btn_volgende_active.png);}
.verstuur:hover {background-image: url(../img/button/btn_verstuur_active.png);}

Ripped edge pattern on div?

The designer I'm working with has given me a monster of an implementation issue...
Page background is grey, and atop of it is a crumpled paper texture (non-repeating with painted design elements) for the first 600 pixels (by 1400 pixels across; currently centered as a non-repeating background). At the bottom is another div with more text on it -- with a dropshadow, complex line pattern for the background and ripped edges, hovered slightly above the top div.
Saving the top part as a JPG and the bottom part as a transparent PNG leads to filesizes of +1mb.
Saving the top part as a JPG and the bottom part as a JPG doesn't work very well due to the drop shadow. It would technically work to save the bottom part as a slice with elements of the top part underneath the dropshadow, but it would have to line up pixel-perfect always or else look crappy. And at that point, I might as well save the whole site as one big image...
If the bottom part had a solid colour for the background, I could set each edge to have a different transparent PNG. However, the line pattern on the bottom part means that this wouldn't work.
My question is ultimately:
How the heck do people do ripped edges these days without making their site one big image?
Thanks!
Screengrab:
CSS3 does provide a border-image property, which should be able to help you with the ripped border effect (although even then, it would help if it was a repeating image).
See here for the W3 specification.
However it may not be much use to you, because browser support for this feature isn't great -- IE doesn't support it at all (not even IE9), and while most other browsers do support it, they all currently have gaps in their support and require a vendor prefix in the CSS property.
See CanIUse.com for a full browser support table for it.
To be honest, I think you should just go back to your designer and ask him to make it easier to work with -- he's probably just created something he thinks looks good, but is unaware of the limitations of the design he's put together; if you explain the issue to him, he may well be able to produce something a bit more usable for you.
There's really not a whole lot you can do here.
Page edges are ideally seamlessly repeated via repeat-y, and in your case it looks like the texture is one big image. You're either going to have to settle for sub-par performance or present the designer with your issues.
Check the archive of this blog for a good example.
You either have to fix the background images and use the entire image (or the top image AND the bottom image) and make the background non-scrolling. OR you have to get him to design a pattern that can repeat and then use a smaller PNG.
Clearly, your designer has a print background....
Ok, there's ways that will most likely theoretically work. But theoretical isn't always practical. I suspect your desire is to have cross-browser capability, as all of us should. So, start by throwing most new CSS3 tricks out, thanks to legacy IE. Forget box-shadow, forget crazy png tranparencies without hacks, etc.
What you're left with is doing a gigantic .jpg background. That will load....eventually.....
In this case, you can see the storm on the horizon, so run for cover. Go back to the designer, explain why this is about as smart an idea as texture layered over gradients, and help them understand why our buddies at Microsoft have made this virtually impossible. Just like a fully-flashed out site, it can be done somehow....but it's probably not the best use of time and resources. The web isn't print, it's dynamic...and when you put something "on a page" it's not going to stay put as it would in Illustrator, nor can you guarantee that your user is going it experience it in 100# glossy with a metallic overlay. Yes, I was a designer before I was a developer.....
Sound like a cop-out? Maybe it is. But I've been in your shoes, building sites for credit cards. My team was forced to waste thousands of dollars of the bank's money trying to make sites work with designs that probably shouldn't have been done on the web, thanks to print designers doing double-duty, getting designs approved prior to talking to the tech team....after, of course, we presented management with the options. Ultimately, it got the boss fired for going over budget.
although this is untypical, I would recommend cutting a big square shaped hole in the center of the image so that you're only left with the edges themselves and a transparent center and saving to PNG. Then saving the center part itself as a jpeg and putting the jpeg directly on top of the PNG in the correct position.
This way, the majority of the very large PNG will contain very little data and be a very small file size. The rest of the data would then, obviously, be jpeg and therefore smaller.

Should I use a sprite-like technique for thumbnails on my website?

On a website I'm creating, I have about 100 various thumbnails (64x64) that get displayed at different times. On some pages, only 5-15 thumbnails may be displayed. On others, all 100 are loaded.
I'm considering using a technique like CSS sprites to display the images. That is, rather than have image tags for each thumb, do something like:
<span class=thumb1"></span>
And then use CSS to take a slice of one single image with all the thumbs stitched together. That is, one image with all 100 thumbs (in this scenario, a 640x640 image).
My questions:
Is this a good idea?
If yes,
should I do it on all pages the
images occur, or only on the pages
with all the images?
Is there
another technique other than sprites
that may be better than simply
including the images with img tags?
If you think that an ordinary user would visit at least two different pages with these thumbnails than my opinion is that using sprites would really be a good idea!
I would in fact make a single big image with all the thumbnails and then use it in all the pages!
Why?
Fewer http requests (from 100 to 1)! And this is one of the most important thing about web site optimizations (read here from Yahoo Performance Team speed optimization rules )
This way users will download the whole image only the first time and then they will get a super quick loading of that images in all the following pages
The most famous websites on the internet already do that! See sprites used in Yahoo, Amazon or Youtube pages.
You can add other UI or layout images to your sprite
Optimize the resulting PNG:
After you have generated your sprite, if a PNG, you can optimize the PNG even more using this tool: http://www.sitepoint.com/blogs/2009/09/18/squishing-the-last-drops-from-your-pngs/
When not to use sprites:
When part of the images in the sprite change frequently
In this specific case: when the majority of users would need less than the (about) 10% of the images
I'm not quite sure what you mean with "sprites", but this is what I think you mean: instead of 100 images seperately, you create 1 image, with a 10x10 raster. Each coordinate (x,y) contains one of the images you like to show.
Now, if you display an image, you use CSS to set background-location: i.e. x * -64px and y * -64px, perhaps using JavaScript to calculate the x and y for each image-span, or Server-Side scripting to print out a dynamic CSS.
Yes, this is a good idea: it reduces load time, since one only has to download one big image, instead of hundreds of smaller ones.
It depends. If you have caching-abilities for a page, then you can "stitch" all thumbnails into one image file. If you have a very dynamic webpage, then it's quite harsh to build this stitched image every time the thumbnales are updated.
Not sure, if this is what you ment with "sprites", then no, if you ment something else with "sprites", then yes: this answer is an example of one.
It is a good idea if
Speed matters
You don't care about accessibility (screen readers reading the ALT text of an image, etc, all that is gone when you use sprites)
You don't care that your thumbnails are not going to be printed by default in any browser
You can do it without it becoming a maintenance nightmare (which image was on position 461 again?)
As to your second question, it is probably advisable to put all sprites into one or very few container images to minimize loading times.