Basic styling of button elements

updated Florens Verschelde

You will want to use the button element for e.g. buttons triggering JavaScript actions, and not <a href="#">…</a> which has a different semantic meaning, or span or div which have no meaning and don’t come with keyboard navigation and accessibility features built in.

But button elements have historically been tricky to style, and though the situation is quite better now there are still a few quirks that need fixing. Here’s some code that resets the browsers’ default styles for this element.

button {
  margin: 0;
  padding: 0;
  border: none;
  font: inherit;
  color: inherit;
  background: none;

/* Firefox fix - bug 140562 */
button::-moz-focus-inner {
  padding: 0;
  border: none;
/* We're using :-moz-focusring rather than :focus so that we
   don't change the default focus in other browsers. If you
   set your own focus styles for buttons, you might drop the
   :-moz-focusring part. */
button:-moz-focusring {
  outline: 1px dotted;

This is the result we get:

If you want to allow for buttons with the default browser style, you might want to use a class for resetting buttons rather than applying the styles to the button selector.

Some details

Incompressible padding in Firefox

In Firefox, button elements seem to have some incompressible padding (similar to padding: 1px 3px). It’s actually the result of a Firefox-specific pseudo-element inside the button, used to display a focus outline inside the button (around its content).

You can remove it by targetting the button::-moz-focus-inner pseudo-element, but it will remove Firefox’s focus styles so we have to declare our own.

Button content shuffling when clicked in Firefox

You shouldn’t see this issue if you use the above code, but Firefox adds some padding to buttons with the :active:hover combined states. This might make the text or content of you button shuffle a little bit when clicked. To avoid this, just make sure you set a padding on your button.

Related test page

See this page for more tests. Note that it doesn’t use the ::-moz-focus-inner fix, so this Firefox issue will be visible in the different tests.