If you do any front-end development work at all, you’re going to have to work with user interaction. That means working with a user’s inputs, and a lot of these inputs are going to involve the use of buttons.
But <a> tags and <button> tags can be pretty plain and ugly looking. That’s why in this tutorial, I’m going to show you how you can make your buttons look much better than the default styles given by the browser.
I’m going to cover styling <a> tags as well as <button> tags since that’s what you’ll be using when you are working on the front-end.
I want to make a quick note here: you should make sure you are using <a> tags and <button> tags for your interactive elements instead of just styling <div> elements.
Why?
The biggest reason is accessibility. Screen readers and keyboard controls will understand these tags as interactive. <div> tags, not so much. Also, correctly using <a> tags will help your website’s SEO.
Let’s get started.
Setting up the project
This is pretty boilerplate stuff, so feel free to skip this step that involves setting up the project if you know how to set up an HTML and basic CSS file.
As with many front-end projects, you’re going to start out by creating an index.html file. I’m using Visual Studio Code as my editor with Emmet. This allows you to type an ! and it fills in the typical HTML that occurs on pretty much all pages.
Create a style.css file, link it to your index.html file and change the title of the page.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="styles.css" /> <title>Making Beautiful Buttons</title> </head> <body></body> </html>Now, you need to write the HTML for the button. Starting from here, all HTML code is going to go in between your <body> tags. I’m going to omit them to save space since you won’t be changing anything besides what’s in your <body>.
Making your first button
In this tutorial, I am wrapping my buttons in a .button-container <div>. I’m only doing this so it’s easier to see and take screenshots. I’m also putting the class or tag name below the button in a <p> tag, so we can see what we're working with when we open up our index.html with a browser. In your app, you don’t need to have this .button-container <div>; however, your button will probably have some kind of parent wrapped around it. Also, in your application, you are probably going to have some event tied to your button. Maybe you are directing the user to a different part of your webpage, maybe they are directed to a whole new page, or maybe you are stopping the default behavior with javascript by using event.preventDefault(). This tutorial only focuses on styling the buttons, so every time we click a button the page will just reload. The # symbol in <a href="#" class="btn"> is often used as a placeholder for a link or for when we don’t want the link to go anywhere.<div class="button-container"> <a href="#" class="btn">Click me</a> <p>.btn</p> </div>I put a little bit of styling on the .button-container, just to make these a bit more clear.
.button-container { border: 1px solid black; text-align: center; }First, get rid of that ugly purple color and underline that is given to us by default.
.btn { color: inherit; text-decoration: none; }Next, add some padding to the button so it has some space between the sides and the text. Also, let’s add a border, so we can see how big the button is. We will get rid of that later.
.btn { color: inherit; text-decoration: none; border: 1px solid black; padding: 10px 20px; }Well, that doesn’t look right. Why is that? This has to do with the default display property being set to inline for <a> tags. Let’s change that to inline-block.
.btn { color: inherit; text-decoration: none; border: 1px solid black; padding: 10px 20px; display: inline-block; }Change the font to whatever you like. I’m going with a simple sans-serif.
.btn { color: inherit; text-decoration: none; border: 1px solid black; padding: 10px 20px; display: inline-block; font-family: sans-serif; }I don’t like how this button is so close to the top of my container. So, I’m going to add some padding to make things look a little nicer.
.button-container { border: 1px solid black; text-align: center; padding: 20px; }And that’s a basic button. Sure, it looks pretty plain, but it’s much better than the ugly <a> tag that we started with. However, we really need to…
Add transitions to your button
One very important part of doing front-end work (or any UX work for that matter), is giving some kind of feedback to the user. When the user hovers over the button, we are going to raise the button up a little bit. We do this by transform: translate(your-value); Remember that coordinates on the DOM are a little bit different from what you learned in high school math class. 0,0 (x = 0, y = 0) starts at the top-left of the screen. That means in order to move something right, you increase the x value. Moving something down involves increasing the y value. We want to move the button up, so we will do the following..btn:hover { transform: translateY(-3px); }And this is what the button looks like when the user hovers over it. If you look closely, you can see that the button seems to ‘jump’ to the next position. This is because we haven’t told the browser how fast to make this transition. In order to do that, we use the transition property. This tells the browser how long to take from the initial state to the final state. You can play around with the value to see the differences, but I am going to use 0.1s in this example. Also, I am using all in the transition property in order to also set the speed for future transitions that happen with the .btn element.
.btn { color: inherit; text-decoration: none; border: 1px solid black; padding: 10px 20px; display: inline-block; font-family: sans-serif; transition: all 0.1s; }In order to make our button appear to have 3 dimensions, we are going to add a box-shadow to the .btn when it is in the :hover state. This works, because a real, physical 3-dimensional button would have some height and block some light on the opposite side of its light source, causing a small shadow. The box shadow takes a few arguments which include the x-offset, y-offset, blur radius, and color of the shadow. Setting the y-offset makes it look as if the light source is coming from the top, leading to a shadow on the bottom.
.btn:hover { transform: translateY(-3px); box-shadow: 0 10px 4px rgba(0, 0, 0, 0.2); }The :active pseudo-class is activated when the user clicks on the button. Again, a real physical button would be pressed in, leading to a lower height and smaller shadow. So let’s do that. Since we set href="#", the page will just reload. If you blink, you might miss this, but you can also try holding down the button to see the effect a bit longer.
.btn:active { transform: translateY(1px); box-shadow: 0 10px 2px rgba(0, 0, 0, 0.2); }
Extending the base .btn class
This is the basis of our .btn class. We’re going to add some more classes in order to reuse this ‘base component.’ Add some margin to your .button-container to add some spacing..button-container { border: 1px solid black; text-align: center; padding: 20px; margin: 50px; }
Add a border-radius to your button. You can do this in your base .btn class, but I’m going to create a new class.
.btn-round { border-radius: 80px; }
Add a new .btn with the class .btn-round and now we can see our two buttons.
<div class="button-container"> <a href="" class="btn">Click me</a> <p>.btn</p> </div> <div class="button-container"> <a href="" class="btn btn-round">Click me</a> <p>.btn .btn-round</p> </div>
Now, we’re getting to the real exciting stuff. Let’s use CSS variables. Using CSS variables means you can reuse the same values all throughout your code. Later you can come back and change one value which will flow through to the rest of your document.
Set up your variables in :root. I got these colors from Flat UI Colors.
:root { --primary-color: #3498db; --primary-button-text-color: white; }
Create a new class and use those variables.
.btn-primary { background-color: var(--primary-color); color: var(--primary-button-text-color); }
Create a new .btn with .btn-round and .btn-primary.
<div class="button-container"> <a href="" class="btn btn-round btn-primary">Click me</a> <p>.btn .btn-round .btn-primary</p> </div>
And this is what we get.
Since we now have a background and can see the shape of the button, we can get rid of the border. You could always create a .btn-border class which adds a border to any .btn elements you like.
In your CSS file, delete this line. I commented it out so you can see what line to remove.
.btn { color: inherit; text-decoration: none; /*border: 1px solid black; */ padding: 10px 20px; display: inline-block; font-family: sans-serif; transition: all 0.1s; }
The great thing about this CSS button setup is that it’s pretty extendable. Now we can add as many colors or styles that we want and just add them to our elements that have the .btn class.
Here, I’m adding a .btn-secondary class. If you’ve ever used Bootstrap, these classnames and design patterns should look pretty close to what you’re used to.
:root { --primary-color: #3498db; --primary-button-text-color: white; --secondary-color: #2ecc71; --secondary-button-text-color: white; }
.btn-secondary { background-color: var(--secondary-color); color: var(--secondary-button-text-color); }
Add a .btn-secondary to your page.
<div class="button-container"> <a href="" class="btn btn-round btn-secondary">Click me</a> <p>.btn .btn-round .btn-secondary</p> </div>
Styling the <button> element
If you are working with forms, you’ll probably use the <button> tag instead of <a> tags to submit your form. However, browsers give the <button> tag some ugly styles. Do the following to reset those styles.
button { border: none; font-size: inherit; }
<div class="button-container"> <button href="" class="btn btn-round btn-secondary">Click me</button> <p>button</p> </div>
Now, this is what our button should look like.
Closing
If you liked this tutorial and would like to see more please like and share this post. Follow me on Twitter, Dev.io, or Medium, or connect with me on LinkedIn.
Need a front-end developer that knows HTML, CSS, Javascript, and React? Feel free to shoot me a message on any of the above platforms and let’s see how we can work together.
As always, questions and comments are welcome below.
Top comments (0)