Styling the Button Element with CSS

No matter what CMS you might be using, WordPress, Drupal, Joomla, Magento, etc., it’s of benefit to learn some CSS to make sure you can carry your branding through your site. Buttons on websites are a bit more complex to style, but they really give the site a finished and polished look when you customize them to fit your look and feel.

The <button> tag describes a clickable surface, which triggers an action, a JS method or event when clicking on it. Buttons provide interactivity in your site, that is why they should always be associated with a script (that is not always the case, as we will see later).

You are allowed to embed text and images into a <button> element, in contrast to the <input type=”button”> element. Buttons can be embedded in all HTML content categories, including <form> elements.

Keep reading to learn more!

The Markup

You declare a button with this markup:

<button type=”button” class=”button”>Plain button</button>

Notice, that specifying the type attribute is mandatory.

190906 buttons

HTML Attributes

The <button> tag supports the following HTML attributes:

  • HTML4 Specification:

    • name
      • The name of the button
    • type
      • The type of the button
    • value
      • The initial value of the button
    • disabled
      • Shows a disabled button
  • HTML5 Specification:

    • autofocus
      • The button gets focus when the page is loaded
    • form
      • Specifies one or more forms, the button belongs to
    • formaction
      • Where to send the form data, once the form is submitted
        • available for <button type=”submit”>
    • formenctype
      • How should data be encoded, once the form has been submitted
        • available for <button type=”submit”>
    • formmethod
      • How should data be sent (method POST or GET)
        • available for <button type=”submit”>
    • formnovalidate
      • The form data will not be validated on submission
        • available for <button type=”submit”>
    • formtarget
      • Where to display the response, once the form has been submitted (_blank, _self, etc)
        • available for <button type=”submit”>

All the HTML Global attributes and Event attributes are supported.

Semantic HTML

Buttons are control fields, with which it is possible to trigger an action within your site. A button containing a link, like a CTA-button is semantically no button at all. Despite this fact, CTA links are mostly represented as buttons by almost every developer.

Basic Design Principles of a Button

To style a button, you have to take several aspects into consideration. Here are a few tips that will help you to adapt the button to your site.

Match the Button to Your Brand

It is always important to match the button styles to the brand guidelines, the graphical style, the predefined color palette of the site or the logo.

Furthermore, it is relevant to match also the contextual style of the button – you should ask yourself questions like:

  • Where is this button going to be placed? (header region, body region, etc)
  • What kind of acton is the button going to trigger?
  • Does this button has to have the same width and height as the other buttons?
  • What kind of display is going to be used, when viewing the content?

Use Enough Contrast

Make good use of all the size, color, whitespace and typography options, that way, you create a visual weight that helps the button to stand out from the rest of the elements inside the interface.

Use Rounded Buttons and Shapes

Rounded buttons and buttons with particular geometric shapes provide a nice design touch to every user interface. This kind of shapes attract the visitor’s attention and help to create the desired interactivity.

Match the Colors of Background, Borders, and Shadows

A rule of thumb is:

  • If the button is darker than its background
    • use no border
    • use a border that matches the button
    • use a soft shadow or no shadow at all
  • If the button is lighter than its background
    • use a border that matches the background
    • use shadows

Use Icons

Icons give the user an additional perception about the button. Unicode characters inside the button markup like arrows, provide more affordance (the design perception about how the element – in this case, the button – should be used).

Provide Primary, Secondary and Tertiary Styles

The primary buttons should always have the strongest color. The saturation of the color of the secondary and tertiary buttons should be reduced progressively, to reflect the difference. This applies to the font of the button, and its size as well.

Design Feedback States

The different button states are:

  • default
  • hover
  • click
  • busy
  • disabled

Styling of Buttons

It is important to give each button its own look and feel. The font size of buttons has to be adapted to mobile device screens since the thumb of a person is bigger and requires more space than a mouse pointer, the height of the line should be also increased. It makes sense to increase the width of the button to reach at least half of the viewport width.

The background color of the primary button should usually match the primary color of your site or application. The use of utf-8 symbols is advised since they provide the user with additional clues on how to use the button. Furthermore, you can use images inside your buttons.

 Basic CSS Properties

There are 8 basic properties, to style a button:

  • background-color
  • border
  • color
  • padding
  • text-align
  • text-decoration
  • font-size
  • display (by default inline-block)

Let’s test them all with an example!


<!-- Default button - Browser styles -->
<div class="button-container">
	<button type="button" class="button">Plain button</button>

<!-- Buttons - Basic Styling -->
<div class="button-container">
	<button class="button-basic">Basic</button>
	<button class="button-basic button-basic-1">Basic 1</button>
	<button class="button-basic button-basic-2">Basic 2</button>
	<button class="button-basic button-basic-3">Basic 3</button>


/* Basic Styles */
button {
  margin-bottom: 3em;

.button-basic {
	background-color: #4b5052;
	border: 2px solid black;
	color: whitesmoke;
	padding: 1em 1.5em;
	text-align: center;
	text-decoration: none;
	font-size: 1em;
	display: inline-block;
	width: 22%; /* to test the test-align property */

190906 buttons 002Change style properties on each button selectively:


.button-basic-1 {
	background-color: aqua;
	color: blueviolet;
	text-align: right;

.button-basic-2 {
	border: 5px solid pink;
	padding: 1.5em 2.25em;

.button-basic-3 {
	font-size: 1.25em;
	text-decoration: overline underline yellow wavy;
	text-align: left;

190906 buttons 003

Additional CSS Properties

You can tweak the look and feel of your buttons even further, by applying these additional properties:

  • border-radius – create rounded corners
  • box-shadow – add drop shadows to the button
  • opacity – so the user perceives the button as disabled
  • the :hover pseudo-element
  • the cursor property


<!-- Buttons - Additional Styling -->
<div class="button-container">
  <button type="button" class="button-fancy"><strong>Fancy</strong> button</button>
  <button type="button" class="button-fancy button-fancy-1">Fancy 1</button>
  <button type="button" disabled class="button-fancy button-fancy-2">Fancy 2</button>
  <button type="button" class="button-fancy button-fancy-3"><span>Fancy 3</span></button>


/* Additional Styles  */
.button-container {
	background-image: linear-gradient(to right, #0c0c86, #02046b);  /* direction, start color, end color */
	padding: 1.5em;

.button-fancy {
	background-color: #23b83c;
	border: 2px solid #020353;
	color: whitesmoke;
	padding: 1em 1.5em;
	text-align: center;
	text-decoration: none;
	font-size: 1em;
	display: inline-block;
	width: 22%;
	border-radius: 5px;
	box-shadow: 3px 3px 8px 0 #000; /* h-offset v-offset blur spread color */

190906 buttons 004Notice the use of a dark color for the shadows of the button and for its borders as well. As stated, the viewer perceives this kind of combination as harmonic compared to the same button on a light background.

190906 buttons 005

To add some “interaction”, we use the :hover selector combined with the cursor property. I am going to change randomly other properties, so those buttons look less boring.


.button-fancy:first-of-type {
	border: 4px solid #000;
	border-top-left-radius: 2em;
	border-bottom-left-radius: 2em;
	background-color: #FFF;
	color: black;

.button-fancy-1 {
	border: 2px solid #FFF;
	border-top-right-radius: 2em;
	border-bottom-right-radius: 2em;
	background-color: #000;
	color: #FFF;

.button-fancy-2:hover {
	opacity: 0.10; /* perception of emptiness */
	background-color: #cbff52;
	color: #626254;
	cursor: grab;

.button-fancy-2:active {
	opacity: 0.25;
	background-color: #ff5852;
	color: #f8f8e7;
	cursor: grabbing;

.button-fancy-3 {
	background-color: #cef61c;
	color: #000;
	font-style: italic;
	border-radius: 2.5em;

.button-fancy-3:focus {
	background-image: radial-gradient(circle at center, red 0, green 30%, blue 45%, yellow);
	outline: 1px solid rgba(255,255,255,0);

.button-fancy-3:hover span,
.button-fancy-3:focus span {
	display: none;

.button-fancy-3:focus:before {
	content: "\1F60B"; /* Inserting an Unicode Character in the CSS */
	font-style: normal;


The first and second buttons make use of the border-radius property on two of the four edges of their containers, and some contrast, to visually convey a button group. The third button has been disabled in the HTML (attribute disabled), so this button will not receive the focus. You can test this by clicking the last button – Fancy 3 –, and then trying to click Fancy 2. Fancy 3 will not change its state until you click on another button on the site. The cursor property is a nice detail with less effort to provide the “renowned” affordance. The first button has also some kind of styling, provided by the semantic tag <strong> in the HTML code. Notice also the use of the :focus and :hover pseudo-classes, to reinforce the affordance.

The pseudo-element ::before serves the same purpose by inserting a Unicode character when hovering over the button.

Styling Radio Buttons

Radio buttons confront the user with two or more selection options, allowing only one choice at the time. All buttons belong to a radio group, that is, a set of options related to each other. The browser renders radio buttons as small circles, which are highlighted when selected. To associate radio buttons to the same set of options, you have to declare the same name attribute for each one of the buttons.


<!-- Radio BUttons -->
<div class="button-container">
<input type="radio" name="availability" id="day" value="day">
<label for="day"><img src="svg_radio_2.svg" alt="day"></label>
<input type="radio" name="availability" id="night" value="night">
<label for="night"><img src="svg_radio_1.svg" alt="night"></label>


/* Radio Buttons */

input[type=radio]:checked {
  opacity: 0;

label {
  filter: grayscale(100%);

input[type=radio]:hover + label,
input[type=radio]:checked + label {
  filter: grayscale(0);

190906 buttons 006

The radio buttons are still on the page, but their opacity has been set to 0, so you will not be able to see them (accessibility). The images have been set with a 100% grayscale filter, so the user perceives these options as “not selected”. The images (button labels) will get their full color when hovering over them or when choosing an option. The “+” selector in the CSS code is telling the browser to select the label element directly placed after the input element.

CSS Button Generators

There are web applications that let you configure the style of your buttons through a graphic interface. Once you have taken a quick overview of such interfaces, you will notice that these applications use the same styling properties, we learned in this tutorial, to generate the buttons. In my opinion, knowing how to manually code the buttons is much easier and quicker.

190906 buttons 007

The <button> tag is supported on all browsers, and so are all other CSS properties, pseudo-classes and pseudo-selectors used in this tutorial.

Additional Links

I hope you liked this exercise. The code is available here. Thanks for reading!

And to learn even more CSS, check out our CSS video training courses!


  • Jorge Montoya

    Jorge lived in Ecuador and Germany. Now he is back to his homeland Colombia. He spends his time translating from English and German to Spanish. He enjoys playing with Drupal and other Open Source Content Management Systems and technologies.

0 0 votes
Blog Rating
Notify of
Newest Most Voted
Inline Feedbacks
View all comments

Nice tutorial, thanks for sharing.

Marko Denic

Great tutorial, Jorge. Thanks!

Would love your thoughts, please comment.x