Creating Sleek On/Off Button with CSS3
Using a button is, so far, the preferred way to interact with an electronic stuff; such as the radio, TV, music player, and even a smartphone that has a voice command feature still needs at least one or two physical buttons.
Furthermore, in this digital age, the button has evolved in its digital form as well, which makes it more interactive, dynamic and real easy to make, compared to the physical button.
So, this time, we are going to create a slick and interactive button which is based on this excellent design over at Dribbble using only CSS.
Well, let’s just get started.
HTML
We will start off the button by placing the following markup on our HTML document. It’s really simple, the button would be based on an anchor tag, we also have a span
next to it to create the indicator light, and then they are wrapped together within an HTML5 section
tag.
<section> <a href="#button" id="button"></a> <span></span> </section>
Here is how our button initially looks like.
Basic Styling
In this section, we will start working on the Styles.
We firstly apply this dark background from Subtle Pattern on the body’s document, and center the section
. Then, we will also remove the dotted outline
upon the :focus
and :active
link.
body { background: url('images/micro_carbon.png'); } section { margin: 150px auto 0; width: 75px; height: 95px; position: relative; text-align: center; } :active, :focus { outline: 0; }
Using Custom Font
For the button’s icon, we will be using a custom font from Font Awesome rather than an image. That way the icon will be easily style-able and scale-able through the stylesheet.
Download the font, store the font files (eot, woff, ttf and svg) in the fonts folder, and then place the following code on your stylesheet to define a new font family.
@font-face { font-family: "FontAwesome"; src: url("fonts/fontawesome-webfont.eot"); src: url("fonts/fontawesome-webfont.eot?#iefix") format('eot'), url("fonts/fontawesome-webfont.woff") format('woff'), url("fonts/fontawesome-webfont.ttf") format('truetype'), url("fonts/fontawesome-webfont.svg#FontAwesome") format('svg'); font-weight: normal; font-style: normal; }
The power icon that we need for this button is represented in Unicode number F011; if you look closely at the HTML markup above, we have put this numeric character
within the anchor tag, but since we haven’t defined the custom font-family
in the button style, the icon is yet to be rendered correctly.
Further reading: Unicode and HTML: Document Characters
Styling the Button
First of all, we need to define the custom font-family
for the button.
Our button will be a circle, we can achieve the circle effect using the border-radius
property and set the value at, at least, half of the button’s width
.
Since, we are using a font for the icon, we can easily set the color
and add text-shadow
for the icon in the stylesheet as well.
Next, we will also create a beveled effect for the button. This effect is quite tricky. First, we need to apply background-color: rgb(83,87,93);
for the button’s color base, then we add up to four layers of box-shadows
.
a { font-family: "FontAwesome"; color: rgb(37,37,37); text-shadow: 0px 1px 1px rgba(250,250,250,0.1); font-size: 32pt; display: block; position: relative; text-decoration: none; background-color: rgb(83,87,93); box-shadow: 0px 3px 0px 0px rgb(34,34,34), /* 1st Shadow */ 0px 7px 10px 0px rgb(17,17,17), /* 1nd Shadow */ inset 0px 1px 1px 0px rgba(250, 250, 250, .2), /* 3rd Shadow */ inset 0px -12px 35px 0px rgba(0, 0, 0, .5); /* 4th Shadow */ width: 70px; height: 70px; border: 0; border-radius: 35px; text-align: center; line-height: 79px; }
There is also a larger circle in the outside of the button and we will be using the :before
pseudo-element for it rather than adding extra markup.
a:before { content: ""; width: 80px; height: 80px; display: block; z-index: -2; position: absolute; background-color: rgb(26,27,29); left: -5px; top: -2px; border-radius: 40px; box-shadow: 0px 1px 0px 0px rgba(250,250,250,0.1), inset 0px 1px 2px rgba(0, 0, 0, 0.5); }
Further reading: CSS :before and :after pseudo-elements (Hongkiat.com)
Indicator Light
Under the button, there is a tiny light to designate the Power On and Off status. Below, we apply red for the light’s color because the power is initially OFF, we also add box-shadow
to imitate the gleam effect of the light.
a + span { display: block; width: 8px; height: 8px; background-color: rgb(226,0,0); box-shadow: inset 0px 1px 0px 0px rgba(250,250,250,0.5), 0px 0px 3px 2px rgba(226,0,0,0.5); border-radius: 4px; clear: both; position: absolute; bottom: 0; left: 42%; }
The Effect
At this point our button starts looking good and we only need to add some effects on it, for instance, when the button is ‘being’ clicked on, we want the button to look like it’s being pressed and held down.
To achieve the effect, the first box-shadow
in the button will be zeroed and the position will be lowered a bit. We also need to adjust the other three shadows’ intensities a little to match the button position.
a:active { box-shadow: 0px 0px 0px 0px rgb(34,34,34), /* 1st Shadow */ 0px 3px 7px 0px rgb(17,17,17), /* 2nd Shadow */ inset 0px 1px 1px 0px rgba(250, 250, 250, .2), /* 3rd Shadow */ inset 0px -10px 35px 5px rgba(0, 0, 0, .5); /* 4th Shadow */ background-color: rgb(83,87,93); top: 3px; }
Furthermore, once the button has been clicked, it should remain pressed down and the icon should ‘shine’ to indicate that the power is ON.
To achieve such an effect we will target the button using the :target
pseudo-class, then change the icon’s color to white and add a text-shadow
with white color as well.
a:target { box-shadow: 0px 0px 0px 0px rgb(34,34,34), 0px 3px 7px 0px rgb(17,17,17), inset 0px 1px 1px 0px rgba(250, 250, 250, .2), inset 0px -10px 35px 5px rgba(0, 0, 0, .5); background-color: rgb(83,87,93); top: 3px; color: #fff; text-shadow: 0px 0px 3px rgb(250,250,250); }
Further reading: Using :target pseudo-class
We also need to adjust the box-shadow
in the circle outside the button, as follows.
a:active:before, a:target:before { top: -5px; background-color: rgb(26,27,29); box-shadow: 0px 1px 0px 0px rgba(250,250,250,0.1), inset 0px 1px 2px rgba(0, 0, 0, 0.5); }
The light indicator will turn from the default red to green color to emphasize that the power is ON already.
a:target + span { box-shadow: inset 0px 1px 0px 0px rgba(250,250,250,0.5), 0px 0px 3px 2px rgba(135,187,83,0.5); background-color: rgb(135,187,83); }
Transition Effect
Lastly, to make the button’s effect run smoothly, we will also apply the following transition effect.
This snippet below will specifically add the transition to the color
property and the text-shadow
for 350ms
in the anchor element.
a { transition: color 350ms, text-shadow 350ms; -o-transition: color 350ms, text-shadow 350ms; -moz-transition: color 350ms, text-shadow 350ms; -webkit-transition: color 350ms, text-shadow 350ms; }
This second snippet below will add the transition for the background-color
and box-shadow
property in the light indicator.
a:target + span { transition: background-color 350ms, box-shadow 700ms; -o-transition: background-color 350ms, box-shadow 700ms; -moz-transition: background-color 350ms, box-shadow 700ms; -webkit-transition: background-color 350ms, box-shadow 700ms; }
Final Result
We have come through all the styles we need, now you can see the final result live as well as download the source file from the links below.
Bonus: How to turn it off
Here comes the bonus. If you have tried the button from the above demo, you’ve noticed that the button can only be clicked once, an that’s to turn it on, so how do we turn it off?.
Unfortunately, we have to do it with the jQuery, but it is really simple as well. Below is the all the jQuery code we need.
$(document).ready(function(){ $('#button').click(function(){ $(this).toggleClass('on'); }); });
The snippet above will add the class ON in the anchor, and we used the toggleClass
function from jQuery to add it. So, when the #button
is clicked on, the jQuery will check whether the class ON has been added or not: when it is not, the jQuery will add the class, and if it has been added, the jQuery will remove the class.
Note: Don’t forget to include the jQuery library.
Now we have to change the Style a little bit. Simply replace all the :target
pseudo-element with the .on
class selector, as follows:
a.on { box-shadow: 0px 0px 0px 0px rgb(34,34,34), 0px 3px 7px 0px rgb(17,17,17), inset 0px 1px 1px 0px rgba(250, 250, 250, .2), inset 0px -10px 35px 5px rgba(0, 0, 0, .5); background-color: rgb(83,87,93); top: 3px; color: #fff; text-shadow: 0px 0px 3px rgb(250,250,250); } a:active:before, a.on:before { top: -5px; background-color: rgb(26,27,29); box-shadow: 0px 1px 0px 0px rgba(250,250,250,0.1), inset 0px 1px 2px rgba(0, 0, 0, 0.5); } a.on + span { box-shadow: inset 0px 1px 0px 0px rgba(250,250,250,0.5), 0px 0px 3px 2px rgba(135,187,83,0.5); background-color: rgb(135,187,83); }
Finally, let’s try it in the browser.