I’ve recently had to make a lot of forms with similar style (a lot of graphics), but the width of the fields and buttons was varying from 20px to 500px, and there were at least six different groups sizes so using a fixed width background was not an option.

Usually the way to make scalable field is to use three parts: left, middle and right. The left and right parts are having a non-repeating background, and have fixed width, while the middle part is having a repeating background:

So the html will look like this:

<style>
    .form field {width:330px; height: 30px}
    .form_field .left{width:16px; background: url(path_to_left.png) top left no-repeat;height: 48px; float:left;}
    .form_field .middle{width:268px; background: url(path_to_middle.png) top left repeat-x ; border: none; height: 48px;float:left;}
    .form_field .right{width:16px; background: url(path_to_right.png) top left no-repeat;height: 48px;float:left;}
</style>

<div class="form_field">
    <div class="form_field left"></div>
    <input type="text" class="form_field middle"/>
    <div class="form_field right"></div>
</div>

But the code still looks long, and I am not a big fan of using three images. There is a easy way to avoid this and to make the code shorter – by using two instead of three images – one big (for left AND middle) and one right. This is how we can save one element. And by combining all the images into one, and using only this as a background (think css sprites) we can avoid the three images, ergo better loading times.

So the new html will look like this:

<style>
    .form field {width:330px; height: 30px}
    .form_field .middle{width:268px; background: url(path_to_image.png) top left no-repeat ; border: none; height: 48px;float:left;}
    .form_field .right{width:16px; background: url(path_to_image.png) top right no-repeat;height: 48px;float:left;}
</style>

<div class="form_field">
    <input type="text" class="form_field middle"/>
    <div class="form_field right"></div>
</div>

We just saved two lines of code. Keep in mind that this time we are using the same image – “path_to_image.png” (which is the whole image shown above) for the two div containers – that reduces the loading time by combining all the images into one – think about CSS Sprites. The only difference this time is that we are showing the background aligned to the right for the right container.

The same technique can be applied to buttons also:

<style>
    .form field {width:330px; height: 68px}
    .form_field .middle{width:268px; background: url("http://avoev.com/wp-content/uploads/2010/11/button1.png") top left no-repeat ; border: none; height: 68px;float:left; cursor: pointer}
    .form_field .middle:hover {background: url("http://avoev.com/wp-content/uploads/2010/11/button1.png") bottom left no-repeat ;}
    .form_field .right{width:16px; background: url("http://avoev.com/wp-content/uploads/2010/11/button1.png") top right no-repeat;height: 68px;float:left; cursor: pointer}
</style>

<div class="form_field">
    <input type="submit" class="form_field middle" value="Big"/>
    <div class="form_field right"></div>
</div>

<div class="form_field">
    <input type="submit" class="form_field middle" value="Tiny" style="width: 60px;"/>
    <div class="form_field right"></div>
</div>

<div class="form_field">
    <input type="submit" class="form_field middle" value="Small" style="width: 150px;"/>
    <div class="form_field right"></div>
</div>
<div style="display:block; clear: both;"></div>

And this is the result:

As you can see here, we’ve generated three different sized buttons just by re-using our code, and changing the width on the input field.
The only problem here will be the hover state, since we are hovering only on the middle (form_field middle), child and by using form_field middle:hover we will change only the background of the specified container.

The solution for this is to target the parent div for the hover by adding two new lines and removing the “.form_field .middle:hover” one:

...  
	.form_field:hover .middle {background: url("http://avoev.com/wp-content/uploads/2010/11/button1.png") bottom left no-repeat ;}
	.form_field:hover .right{width:16px; background: url("http://avoev.com/wp-content/uploads/2010/11/button1.png") bottom right no-repeat;}
...

And we’re done. Now we are controlling the two div elements by hovering the parent. Just hover to see the result:

And this is the full code:

<style>
    .form field {width:330px; height: 68px}
    .form_field .middle{width:268px; background: url("http://avoev.com/wp-content/uploads/2010/11/button1.png") top left no-repeat ; border: none; height: 68px;float:left; cursor: pointer}
	.form_field:hover .middle {background: url("http://avoev.com/wp-content/uploads/2010/11/button1.png") bottom left no-repeat ;}
    .form_field .right{width:16px; background: url("http://avoev.com/wp-content/uploads/2010/11/button1.png") top right no-repeat;height: 68px;float:left; cursor: pointer}
	.form_field:hover .right{width:16px; background: url("http://avoev.com/wp-content/uploads/2010/11/button1.png") bottom right no-repeat;}
</style>

<div class="form_field">
    <input type="submit" class="form_field middle" value="Big"/>
    <div class="form_field right"></div>
</div>

<div class="form_field">
    <input type="submit" class="form_field middle" value="Tiny" style="width: 60px;"/>
    <div class="form_field right"></div>
</div>

<div class="form_field">
    <input type="submit" class="form_field middle" value="Small" style="width: 150px;"/>
    <div class="form_field right"></div>
</div>