CSS tips and tricks #2-Custom form design

In today’s episode of of CSS tips and tricks we will focus on designing awesome web form. You may already worked and customized forms, however most of people do only basic styling of text inputs or text. I want to show some advanced tricks. If you think that you are not able to style radio buttons or checkboxes, I will shock you and turn your current knowledge upside down. You can find example code on Codepen on link at the bottom of this article. Let’s dive in!

We will start with simple inputs for firstname, surname and mail. For message we will use textarea and also include some radio buttons, dropdown and checkbox. All parts will be divided into individual containers by divs and at the bottom will be submit button. HTML setting is following:


<form action="#" id="js-form">
<div class="name">
<input type="text" name="name" placeholder="Adam" />
<input type="text" name="surname" placeholder="Smith" />
<input type="mail" name="email" placeholder="adam.smith@mail.com"/>
<div class="radio">
<label for="radio-choice-1">Choice 1</label>
<input type="radio" name="radio-choice" id="radio-choice-1" value="choice-1" />
<label for="radio-choice-2">Choice 2</label>
<input type="radio" name="radio-choice" id="radio-choice-2" value="choice-2" />
<div class="dropdown">
<label for="select-choice">Select Dropdown Choice:</label>
<select name="select-choice" id="select-choice">
<option value="Choice 1">Choice 1</option>
<option value="Choice 2">Choice 2</option>
<option value="Choice 3">Choice 3</option>
<div class="message">
<label for="textarea">Textarea:</label>
<textarea cols="40" rows="8" name="textarea" id="textarea"></textarea>
<div class="check">
<label for="checkbox">Checkbox:</label>
<input type="checkbox" name="checkbox" id="checkbox" />
<div class="submit">
<input type="submit" value="Submit" disabled/>

For CSS… First we will set typography for whole page. For font I chose Open sans which is beautiful sans serif typeface. Font is delivered by Google web fonts. As a fallback I will go with simple sans-serif. Default font size for document will be 16 pixels. We will continue by settting box-sizing of all elements to border-box (padding then will not impact width and height off element -> it will apply inside the box) and resetting margins and padding to 0. For resetting all the styles (so they look similar across the browsers) I suggest you to include reset stylesheet from either HTML5 Doctor or Meyer web.


html {font: 16px 'Open sans', sans-serif;}
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
margin: 0;
padding: 0;

Now we will setup our form. We will set the padding to 1em (thanks to 16px in html 1em will be equal to 16px) and it will apply on inner elements -> the will be pushed 1em from the borders. Width of the form will be 320px (keep it mobile-first so form fits portrait mode on small displays). We will not set height to make it automatic according to content. Color of text will be #aaa (light shade of grey) and border of the form will be .1em solid #ddd (shade of grey lighter than text -> thanks to contrast text will be more visible) with radius of 4px. This radius and border will be applied on all elements to keep it consistent. Also set the width of div containers to 100% (100% of form width -> 320px except the padding).


form {
padding: 1em;
width: 320px;
color: #aaa;
border: .1em solid #ddd;
border-radius: 4px;
div {width: 100%;}

Next step is to style our inputs. Let’s give ’em little bit more modern look by making the border thinner (.1em) and light grey (#ddd) and also make the inputs bigger by setting the width to 47% (of div container) and height to 3em. Because inputs are inline elements, they will nicely sit on one line. Text indentation will be .5em to move the text typed inside little bit further from left border. One more thing… Set the outline (border when input has focus – is selected) to turquoise green (#1abc9c) (same as button -> consistency).


.name input,
.submit input,
textarea {
width: 47%;
height: 3em;
text-indent: .5em;
border: .1em solid #ddd;
border-radius: 4px;
outline-color: #1abc9c;

To space the inputs we will add a top margin of 1em (except the firstname and surname). After that we will set the width for dropdown, textarea and button to 100%.


.name input[type="mail"],
.submit {
margin-top: 1em;
.dropdown select,
.message textarea,
.submit input {
width: 100%;

To change the color of dropdown you have to set it again individually to #aaa. Height of textarea will be 8em. Let’s also style the button… We will set the background to #1abc9c (turquoise), color of text to #fff (white) and border to 0 except the bottom border which will be .1em solid ##169d82 (darker turquoise). Text will be bold and size of 1em.


.dropdown select {color: #aaa;}
.message textarea {height: 8em;}
.submit input {
background: #1abc9c;
color: #fff;
border: 0;
border-bottom: 4px solid #169d82;
font-size: 1em;
font-weight: bold;

Now comes the best part – customizing the radio buttons and checkbox. To do this we will use :before pseudo-class and for checked state font awesome to generate check symbol. :before pseudo-class is used to generate some new content before (on the left side) of the element. No images or other amateur tricks are needed! For creating new radio and checkbox we will first set their position to relative so the :before class can use absolute positioning relative to the element.


.radio input,
.check input {position: relative;}

Now we will play with :before of radios and checkbox … We want to create small box to cover the default one. So, set the content to empty (“”), position to absolute with top and left to 0. Width and height will be 1em and background #e9e9e9 (darker shade of grey) with border-radius of 4px.


.radio input:before,
.check input:before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 1em;
height: 1em;
background: #e9e9e9;
border-radius: 4px;

Voiala, the default box and radios are gone! Great job. Let’s now create our own checked states. Set the content to “f00c” (code of check symbol in font awesome font-family), font-family will be ‘fontAwesome’ and color turquoise -> #1abc9c (consistency!).


.radio input:checked:before,
.check input:checked:before {
content: "f00c";
font-family: 'fontAwesome';
color: #1abc9c;

Congrats, you just created your own customized form! I hope that I did not forget anything … Example code are available on Codepen (link is below). Thank you very much for your time and see you next time! AD

Codepen example:


If you liked this article, please subscribe so you don't miss any future post.

If you'd like to support me and this blog, you can become a patron, or you can buy me a coffee 🙂

By Alex Devero

I'm Founder/CEO of DEVERO Corporation. Entrepreneur, designer, developer. My mission and MTP is to accelerate the development of humankind through technology.


  1. I do not even know how I ended up right here, however I believed this publish was good.
    I don’t realize who you might be but definitely you’re going to a well-known blogger for those who are not already.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.