HTML & CSS - - By Craig Buckler

How to Build a Better Button in CSS3

I tend to opt for <button> tags rather than <input type="submit" /> but, whichever you prefer, the standard style follows your OS conventions. It can be a little uninspiring…

standard HTML button

Let’s build a better button using CSS3 styles, animations and transformations:

better HTML button with CSS3

View the button demonstration…

The HTML

No surprises here — we only require a single button tag:

<button>Click me!</button>

We’re going to apply our styles to every button but, if you’d prefer not to do that, add a class and target it in the CSS accordingly.

The CSS

Our button should work well in the latest browsers but also degrade gracefully in older applications. That said, I’m only going to add CSS prefixes when they’re absolutely necessary. Firefox, Opera and IE10 support transitions, transformations and animations without prefixes — but we still require -webkit- for Chrome and Safari.

Let’s start with some basic styles to format the button:

button
{
	display: block;
	font-size: 1.1em;
	font-weight: bold;
	text-transform: uppercase;
	padding: 10px 15px;
	margin: 20px auto;
	color: #ccc;
	background-color: #555;
	background: -webkit-linear-gradient(#888, #555);
	background: linear-gradient(#888, #555);
	border: 0 none;
	border-radius: 3px;
	text-shadow: 0 -1px 0 #000;
	box-shadow: 0 1px 0 #666, 0 5px 0 #444, 0 6px 6px rgba(0,0,0,0.6);
	cursor: pointer;

Nothing too complicated. I’ve used a fairly generic gray color throughout, but you can apply whatever colors you need. Note also that a background-color has been defined for browsers which do not support linear-gradients. I’ve also set the cursor to pointer — I’ve never understood why browsers don’t do that by default?

The box-shadow is the most interesting property: box-shadow: 0 1px 0 #666, 0 5px 0 #444, 0 6px 6px rgba(0,0,0,0.6). This defines the edge of the button, a 5px “depth” and a light shadow around it.

We complete the block by stating we want transition effects applied to every style when a hover or focus event occurs. Prefixless and -webkit alternatives are required:

-webkit-transition: all 150ms ease;
	transition: all 150ms ease;
}

In the next block, we’ll define the hover and focus styles. This defines a pulsate animation which makes the text glow:

button:hover, button:focus
{
	-webkit-animation: pulsate 1.2s linear infinite;
	animation: pulsate 1.2s linear infinite;
}

@-webkit-keyframes pulsate
{
	0%   { color: #ddd; text-shadow: 0 -1px 0 #000; }
	50%  { color: #fff; text-shadow: 0 -1px 0 #444, 0 0 5px #ffd, 0 0 8px #fff; }
	100% { color: #ddd; text-shadow: 0 -1px 0 #000; }
}
		
@keyframes pulsate
{
	0%   { color: #ddd; text-shadow: 0 -1px 0 #000; }
	50%  { color: #fff; text-shadow: 0 -1px 0 #444, 0 0 5px #ffd, 0 0 8px #fff; }
	100% { color: #ddd; text-shadow: 0 -1px 0 #000; }
}

Firefox, Chrome and Safari do not require the 0% and 100% definitions but IE10 fails to animate text-shadows if we don’t use them. Sounds like a browser bug to me — make a mental note of that one.

Finally, we set the button active state:

button:active
{
	color: #fff;
	text-shadow: 0 -1px 0 #444, 0 0 5px #ffd, 0 0 8px #fff;
	box-shadow: 0 1px 0 #666, 0 2px 0 #444, 0 2px 2px rgba(0,0,0,0.9);
	-webkit-transform: translateY(3px);
	transform: translateY(3px);
	-webkit-animation: none;
	animation: none;
}

This performs a number of actions:

  • the animation is switched off and the text is set to it’s ‘fully glowed’ state
  • the button is moved down 3 pixels using translateY
  • the box-shadow which defines the button depth is changed to 0 2px 0 #444. It’s therefore been reduced from 5px to 2px, but the 3px translation makes it appear that the button has sunk into the page.
  • the outer shadow is also reduced to give the impression the button is lower.

Our button is now complete:

better HTML button with CSS3

View the button demonstration…

The code works as expected in all modern browsers. The only issue I discovered was in Opera — it plays the pulsate animation just once? But they’re switching to WebKit soon, so let’s not worry too much…

Please use the code however you like!

Sponsors