Learn how to make your own cross-browser consistent buttons and forms from scratch with CSS or Sass.
It’s hard to style basic web components if you’ve never done it before. You want your buttons and forms to look good and also be cross-browser consistent. The easiest solution is to use a framework like Bootstrap or Foundation, but that won’t help you understand the fundamentals. It’s actually not as hard as it seems, and in this article I’ll show you how.
To make life easy for myself, I’ve compiled all these into my own framework, Primitive (which also incorporates Sass and Gulp) and I encourage you to make your own as well, even if only for learning purposes.
Style buttons, in the form of div, link (a), input, and button elements.
Style forms, including HTML5 input, textarea, and select elements.
I referenced my fundamentals article from before because it includes a few things I like all my web projects to have: a CSS reset, and border-box reset. Basically, these two things will allow you to have a little more consistency and control over your layout.
And that’s it as far as setup goes. I also personally like to put -webkit-font-smoothing: antialiased; on the html selector to make text appear more crisp and pleasant.
First, we’ll style the buttons. Here’s our goal:
What exactly is a button? It can be one of the following:
<button> – a button element
<input type="button"> – an input element, with the type set to either button, submit, or reset.
<a class="button"> – a hyperlink, styled to look like a button.
These styles are somewhat opinionated, but easy to change. I’m setting the display to inline-block for links and regular divs. I chose a background color and border. I removed the underlines on links, made the text sans serif (Arial or Helvetica), bold, and added some padding.
If you’re using Normalize, it should be relatively consistent across browsers with just this. Here’s how Chrome renders it (I’ve left off the round borders to make it easier to compare):
Safari might do things like add extra margin on inputs, and Firefox might have the text sit on different baselines or have different line heights, causing little issues like these:
I’m setting the baseline of the text to be vertically centered, supressing line breaks within text, ensuring the cursor is always a pointer, and setting margins and a line-height. This should make most browsers happy. If you’re not using Normalize, you’ll also need to add this in to make Firefox happy.
So you can kind of pick and choose what you want to style. I don’t use them all, so I don’t include them all.
Here’s what the unstyled form looks like, before and after Normalize.
It’s pretty far from what we’re aiming for, but it won’t take much work to get this looking how we want. First I’m going to put the whole form inside of a .container class so it doesn’t take up the whole screen, and I’m going to add the border-box and button styles from earlier in the tutorial.
First, I’m making all the elements block level, so they take up the full width of the container. I’m going to give them all some padding, and remove the default background color. Just like with the buttons, the text will be vertically aligned. I’m setting the width and max-width to 100%, to make sure it fills the whole container but doesn’t exceed it. Finally, I add my opinionated styles, which consist a thin gray border and rounded corners. Most of the personality of the form will come from the border shape and color.
Now we have a bit more structure to the form, but the select doesn’t play nice at all. In it’s current state, it’s controlled by the browser, and I’m not even able to change the shape of the borders. Here’s what I’ll do to make it match the other fields.
I’ve removed the default mozilla and webkit appearance of the select, and added an encoded png image for the arrow. You can also use an actual image of an arrow, either png or svg, that you’ve created, but this way I don’t have to load anything extra. This works in modern Chrome, Firefox, Safari, Edge, and Opera. Here’s how it looks:
Internet Explorer 9, 10, and 11 will render it like this: (you can go to Microsoft’s developer page to generate IE screenshots if you’re on a Mac.)
I don’t think it’s too bad for a fallback. Now all that’s left is styling the labels:
Hopefully now you feel confident styling forms and buttons without relying on a CSS framework. As I mentioned at the beginning of the article, I’ve applied all of this into making my own small framework, which really helped me when I was learning, and I now use for all my own projects. If there is a positive response to this guide, I could also make a follow up for additional components, like navigation, accordions, cards, etc.