CSS Sprites for Irregular Shapes

I like to use the CSS Sprites technique on my sites, as it cuts down HTTP requests. However, it can sometimes be tricky to figure out how to put together an irregular shape in order to be able to use the method. An example is a site I was recently developing that used a 'speech bubble' like this:

Image

I needed to make the speech bubble expandable in height to allow for different unknown amounts of text. So using the image as-is doesn't work. Of course the easy way is to slice the image into three pieces.

Top (speech_bubble_top.png):

Image

Middle (speech_bubble_body.png):

Image

Bottom (speech_bubble_bottom.png):

Image

I can then use the following HTML to make the bubble:

<div class="speech_bubble">
  <div class="bubble_top">&nbsp;</div>
  <div class="bubble_body">This is a variable amount of text. It can be long or short</div>
  <div class="bubble_bottom">&nbsp;</div>
</div>

With this CSS:

.speech_bubble
{
	width:146px;
	color:#FFF;
	font-size:12px;
}
 
.bubble_top
{
	height:3px;
	width:100%;
	background:url(speech_bubble_top.png) no-repeat;
}
 
.bubble_body
{
	padding:2px 5px 0;
	background:url(speech_bubble_body.png) repeat-y;
}
 
.bubble_bottom
{
	height:37px;
	background:url(speech_bubble_bottom.png) no-repeat;
}

And the result will look like this:

 
This is a variable amount of text. It can be long or short
 

This will work, and I will have a speech bubble with a variable height. However, I am using three separate images, resulting in three HTTP requests, which is not good for download speeds, even though the individual images themselves are tiny. So I prefer to use CSS Sprites in this situation. However, the image is irregularly shaped, so I had to think for a minute on how to put it together. I have the following points to consider:
* The top and bottom are not tiled
* The body is tiled, repeating along the y axis.

So I need to come up with some way that will allow me to tile the body along the y axis, while combining it with the top and bottom of the bubble. The solution is to create my image to look like this:

Image

So now I can use the same HTML:

<div class="speech_bubble">
  <div class="bubble_top">&nbsp;</div>
  <div class="bubble_body">This is a variable amount of text. It can be long or short. This time I will make it even longer than before to show how it expands.</div>
  <div class="bubble_bottom">&nbsp;</div>
</div>

But this time I set my CSS a little differently. I use the same background image for all three parts of the bubble, but I use background positioning to only show the right half of the image in the body, and I tile that along the y-axis:

.speech_bubble
{
	width:146px;
	color:#FFF;
	font-size:12px;
}
 
.bubble_top
{
	height:3px;
	width:100%;
	background:url(speech_bubble.png) no-repeat left top; // this displays the top left part of the image through the element
}
 
.bubble_body
{
	padding:2px 5px 0;
	background:url(speech_bubble.png) repeat-y right top; // this tiles the right side of the image along the height of the element
}
 
.bubble_bottom
{
	height:37px;
	background:url(speech_bubble.png) no-repeat left bottom; // this shows the bottom left part of the image through the element
}

And I can still use a variable amount of text inside my speech bubble. But now I have reduced my HTTP requests to one, which will keep the pipes open, allowing the site to be downloaded faster. The result looks like this:

 

 
This is a variable amount of text. It can be long or short. This time I will make it even longer than before to show how it expands.
 

 

Also, lets look at the various filesizes for the images.

speech_bubble.png (original): 1.48KB

speech_bubble_top.png: 220B

speech_bubble_body.png: 160B

speech_bubble_bottom.png: 1.22KB

speech_bubble.png (CSS sprite version): 1.42KB

So while the combined image sizes of the three sliced elements (1.60KB) is larger than the original image size (1.48KB), the CSS sprite version is even smaller than the original, meaning that the download time will be minimized in image size as well. Of course this won't happen with all images, but it did with this one.

Comments:

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
X
Loading