9-slice scaling in HTML
9-slice scaling is a technique from Adobe’s Flash product line and has been adapted into Fireworks. It is used to scale certain parts of a symbol different from others when resizing the symbol (i.e. not scaling the corners at all) to make corners and borders look the same at every size of the symbol. With a little CSS and HTML this can be done in browsers, too.
The Adobe Fireworks help has a good article explaining 9-slice scaling. Now imagine you’re designing a liquid width layout for a website - wouldn’t it just be great if it would scale as it was 9-sliced? Here’s how:
Slicing
First you need one image for each of the outer areas in the 9-slice grid. That’s top left, top center, top right, left center, right center, bottom left, bottom center and bottom right. We don’t need an image for the center, since it’s filled with one solid color in this example and we can use CSS for that. Note that all top and all bottom slices must share the same height. The top center and bottom center slices should be 1 pixel wide, since we’re not going to scale them, but repeat them (which is the difference of this technique compared to the original 9-slice scaling). Left and right center slices only need to be 1 pixel high for the reasons just mentioned.
After all, the slicing looks like this (forgive me the typo):
![]()
HTML code
Here’s the HTML you’ll need. Read the comments in the code for explanation.
<div class="content"><!-- this is the overall container --><div class="content-top"><!-- this contains the top left, top right and top center slices --><div class="content-top-left"></div><div class="content-top-right"></div><!-- notice the top center or top repeat slice needs to be at the end --><div class="content-top-repeat"></div></div><div class="content-repeat"><!-- this is just a container for the vertically scaling part - you could leave it out, but it seems cleaner to me --><div class="content-repeat-left"><div class="content-repeat-right"><!-- in this case the left center and right center must be nested and must contain the actual content div, so they automatically scale with it --><div class="content-repeat-center"><!-- /** this is where you'd place the content **/ --><div class="content-repeat-clearfix"><!-- this will prevent problems with floated stuff within the content --></div>
</div></div></div></div><div class="content-bottom"><!-- this contains the bottom left, bottom right and bottom center slices --><div class="content-bottom-left"></div><div class="content-bottom-right"></div><!-- as above the bottom center div must be after the bottom left and right divs --><div class="content-bottom-repeat"></div></div></div>
CSS
And here’s where the magic comes in - this will actually combine the images and the HTML code and make it scale perfectly. Again, read the comments for explanation:
.content .content-top {
/* No rules needed here, but for the sake of completeness */}.content .content-top .content-top-left {
/* float this one left and .content-top-right right so they flow over .content-top-repeat, which is the top center slice */float: left;
/* width and height are defined by the image */width: 83px;
height: 49px;
background: url('images/content_top_left.png') no-repeat;
}.content .content-top .content-top-right {
float: right;
/* height needs to be the same across all top slices! */height: 49px;
width: 99px;
background: url('images/content_top_right.png') no-repeat;
}.content .content-top .content-top-repeat {
height: 49px;
/* the margins are the width of the top left and top right slices - this is not always neccessary, but in my case I was using alpha-transparent PNG8, which broke the layout in IE6 then */margin-left: 83px;
margin-right: 99px;
/* note that we repeat-x the image here */background: url('images/content_top_repeat.png') repeat-x;
}.content .content-repeat {
/* No rules needed here, but for the sake of completeness */}.content .content-repeat .content-repeat-left {
/* repeat-y the image - this div will automatically resize with the content */background: url('images/content_repeat_left.png') left repeat-y;
}.content .content-repeat .content-repeat-left .content-repeat-right {
/* same as center left slice */background: url('images/content_repeat_right.png') right repeat-y;
}.content .content-repeat .content-repeat-left .content-repeat-right .content-repeat-center {
/* Put your text formatting here *//* again, margins are the widths of the left and right center slice */margin-left: 3px;
margin-right: 14px;
/* and this is the solid background color */background: #fffbf2;
}.content .content-repeat .content-repeat-clearfix {
/* you better have this if you have floated stuff in your content */clear: right;
}.content .content-bottom {
/* No rules needed here, but for the sake of completeness */}.content .content-bottom .content-bottom-left {
/* same technique as above when stying the top part */float: left;
/* again, image size defines the size of this div */width: 12px;
height: 46px;
background: url('images/content_bottom_left.png') no-repeat;
}.content .content-bottom .content-bottom-right {
/* see above */float: right;
width: 61px;
/* note the height _must_ be euqal across all bottom slices */height: 46px;
background: url('images/content_bottom_right.png') no-repeat;
}.content .content-bottom .content-bottom-repeat {
/* margins again defined by the width of the bottom left and right slices */margin-left: 12px;
margin-right: 46px;
/* and height is the same across all bottom slices */height: 46px;
/* don't forget the repeat-x thingy */background: url('images/content_bottom_repeat.png') repeat-x;
}
Summary
Now that was a massive amount of code, wasn’t it? A little demo would be nice, right? Check this one: http://www.mgv-oberhaid.de/ - try changing your browser’s font size and watch the content div to see the effect.
Update: Obviously all the IDs in HTML should have been classes - the CSS excerpt did style classes, which is a better idea if you want to use multiple 9-slice boxes on a page. The demo URL was outdated, too.