How we made buttons before CSS3
It’s 2007, and your designer just handed you a design with a “beautiful button”, back then, most likely a PSD from Photoshop or a Fireworks file. Looking at the file, you notice that the button has:
- A two-tone gradient with a hard edge in the middle
- Rounded corners
- A subtle box shadow at the bottom
Today, you’d write a few lines of CSS and call it a day. But back then? CSS couldn’t do gradients (~2010). Couldn’t do rounded corners (~2010). Couldn’t do box shadows (~2009).
I started web development around 2007-2008 and learned these techniques in the trenches. This was the way. Let me show you how we did it.
The button
This is what the designer handed you:
1st approach: Image as background
The simplest way to create such a button is to export the image from Photoshop and use it as a background of an HTML button.
Here’s the image we’ll use as background:
And here’s the result:
| |
This approach works, but has some drawbacks:
- The button size is fixed to the image dimensions
- You need a new image for every button variation
- Each image is a separate HTTP request - a big problem in 2007 when connections were slow and browsers limited concurrent downloads to 2 per domain
2nd approach: Slicing the image
The fixed-size problem led to a clever technique: slice the button into three pieces:
- Left side - full height image with rounded left corners
- Right side - full height image with rounded right corners (mirrored from left in Photoshop)
- Middle stripe - 1px wide, repeats horizontally to fill any width
We’d use absolutely positioned spans for the edges:
| |
Now the button can grow to fit any text! But we still have problems:
- Extra span elements for the edges
- Multiple HTTP requests for images
- Need new images for different colors
3rd approach: CSS Sprites
The slicing technique works, but each image is a separate HTTP request. In 2007, browsers limited concurrent connections to just 2 per domain . Three images? Three round trips to the server. There were tricks to work around this limit - maybe a topic for another article.
The solution? Combine all images into a single sprite and use background-position to show just the piece you need:
Same image, different background-position values:
| |
One image, one HTTP request. The browser downloads the sprite once, caches it, and every button on the site loads instantly.
Back in the day, some sites had massive sprites with all their buttons, icons, and UI elements in a single file.
Button states
What about hover and active states? Back to Photoshop. For each state, you’d create new images, slice them, add them to the sprite, and write more CSS rules. A simple hover effect could mean hours of work.
Over time, tools appeared to automate sprite creation - some even output JSON with all the positions.
And today?
All that complexity? Gone. Modern CSS can do it in a few lines:
| |
No images. No extra markup. Just CSS.
It’s incredible how far we’ve come, nowadays css can do animations, grids, custom properties, container queries and much more.
I really like the web as a platform, it keeps improving, you don’t need anyone’s permission to create something, no app store approval, no gatekeepers. Open your editor, open a browser, and start building.
Let me know what you think.