Creating Awesome Buttons in CSS

Click the buttons
By
Published ~ 11 minutes read

If you count just the lines of code, CSS is probably the language I type the most in. Yet, it is also the language I share the least about on this website. So this is an attempt to fix that. I created a set of three state buttons that you can customize to your liking.

I rarely use bootstrap, material design or any of popular CSS solutions that are currently available. The reason is simply that I would rather write the CSS myself instead of including an entire library just to make use of one or two features. If you have the same mindset, well without further due here they are.

Find the Buttons on Github.

The buttons themselves are very simple, they use 3 states to create this effect. They have a small one pixel wide bottom border to give the impression of nudging up (state 1). When you hover it grows by another pixel and lighten up (state 2). When you click it the bottom border goes down, it darkens, giving the impression of being pressed down (state 3).

If you also noticed, when you click there is a small effect similar to what you would see on Google's material design. This effect is possible without JavaScript, however I had to use Javascript because it appears right under the mouse button no matter where you click. If you don't have javascript enable the buttons still work fine but this is a nice little animation to have. Let me show you how it is done.

I created the animation using a circle that grows from 30 pixels to 150 pixels. Note that a circle is just a square with border radius set to 50%. And the circle is not a separate element but just the ::after css pseudo selector:

.btn.animate::after {
position: absolute;
content:" ";
top:var(--coord-y);
left:var(--coord-x);
transform: translateX(-50%) translateY(-50%);
background-color:rgba(0,0,0,.1);
display:block;
border-radius: 50%;
animation: btn-click ease-out .5s normal;
}

Two things to note here, one is the animation btn-click which I defined using the @keyframes directive. (I'll post the full code below) And the second is the function var() and it's parameter --coord-x and --coord-y These are CSS3 features. Because I cannot determine the location of the mouse click using CSS, I used Javascript to find the location and then set it as a custom css style property --coord-y (note that you can use any name). The top property will read whatever the value of those custom properties I set on the element.

btn.setAttribute("style","--coord-x: "+x+"px;--coord-y: "+y+"px;");

Once I have set the position of the mouse I can trigger the animation by adding the class animate to the button. I have set the animation to last 500 milliseconds so right away I set a timer to remove the class name after 500ms.

setTimeout(function(){
self.classList.remove("animate");
},400);

And just like that we have ourselves realistic and interactive CSS buttons with minimal amount of code.

The code:

CSS

@keyframes btn-click {
from {
width:30px;
height:30px;
opacity:1;
}
to {
width:150px;
height:150px;
opacity: 0;
}
}
.btn {
position: relative;
top: 0;
border: none;
padding: 12px 16px;
background-color: #d0d0d0;
color: #111;
font-weight: bold;
border-radius: 4px;
box-shadow: 0 2px 2px rgba(0,0,0,.16);
border-bottom: 1px solid #aaa;
outline: none;
transition: background-color .2s, box-shadow .2s;
overflow:hidden;
cursor:pointer;
display:inline-block;
}
.btn.animate::after {
position: absolute;
content:" ";
top:var(--coord-y);
left:var(--coord-x);
transform: translateX(-50%) translateY(-50%);
background-color:rgba(0,0,0,.1);
display:block;
border-radius: 50%;
animation: btn-click ease-out .5s normal;
}
.btn:hover {
top:-1px;
background-color:#dadada;
border-bottom-width: 2px;
box-shadow: 0px 2px 4px rgba(0,0,0,.16);
}
.btn:active {
top:1px;
background-color: #cdcdcd;
box-shadow: 0px 1px 1px rgba(0,0,0,.16);
border-bottom-width: 0;
}
.btn.primary {
background-color:#2980b9;
color:#fff;
border-bottom-color: #1e608c;
}
.btn.primary:hover {
background-color:#3498db;
}
.btn.primary:active {
background-color:#2672a5;
}
.btn.danger {
background-color:#c0392b;
color:#fff;
border-bottom-color: #9e2f23;
}
.btn.danger:hover {
background-color:#de4434;
}
.btn.danger:active {
background-color:#a93226;
}
.btn.warning {
background-color:#f1c40f;
color:#fff;
border-bottom-color: #caa40d;
}
.btn.warning:hover {
background-color:#ffd323;
}
.btn.warning:active {
background-color:#deb40d;
}
.btn[disabled]{
color:#999;
background-color: #d0d0d0;
border-bottom-color: #aaa;
}
.btn[disabled]:hover {
top:0;
background-color: #d0d0d0;
border-bottom-width: 1px;
box-shadow: 0 2px 2px rgba(0,0,0,.16);
}

JavaScript

var Buttons = {
init:function(){
var btns = document.getElementsByTagName("button"),
l = btns.length,i = 0;
function onMouseDown(event){
var scrollTop = document.body.scrollTop,
position = Buttons.getPosition(this),
x = event.pageX - position.left,
y = event.pageY - position.top - scrollTop;
Buttons.onclick(this,x,y);
}
for(;i btns[i].onmousedown = onMouseDown;
}
},
onclick: function(self,x,y){
self.setAttribute("style","--coord-x: "+x+"px;--coord-y: "+y+"px;");
self.classList.add("animate");
setTimeout(function(){
self.classList.remove("animate");
},400);
},
getPosition:function ( el ) {
var x = 0;
var y = 0;
while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
x += el.offsetLeft - el.scrollLeft;
y += el.offsetTop - el.scrollTop;
el = el.offsetParent;
}
return { top: y, left: x };
}
};
Buttons.init();

Did you like this article? You can buy me a coffee.
Share your insightful comments here.

Join my newsletter

Follow me on Twitter, Spotify, or RSS Feed

On a related note, here are some interesting articles.

Getting started with your first Website

Making your own website shouldn't be too difficult. Hosting companies like Godaddy or Hostgator make it super easy for anyone to get started; they allow you to create a whole website without ever writing code. For most people, it is plenty to run a WordPress blog. If this is what you are looking for you should head to Godaddy.com right now. We are done here. But on the other hand, if you want to have control and not be limited by the short comings of a shared hosting without busting your wallet, you have come to the right place.

Web War 3.0 - Screen sizes

When I started working as a web developer, there was no longer a need to use the hacks from the 90s to make your website work. The marquee and blink tags where already dead. I could still see some old blogs referencing document.layers but they were on their way out. But still when I started, I had to worry very much about writing cross browser code.

Simple Responsive CSS trick

Responsive web is here to stay. Some websites are very hard to read when presented at full scale on a tiny screen. I found it cumbersome to rewrite all my CSS styles inside a @media tag to make it responsive at different screen size. However, lately I have been using a few lines of codes that make my page look good no matter where it is displayed.

View all articles

Comments

There are no comments added yet.

Let's hear your thoughts

For my eyes only