Full CSS3 HTML5 Contact Form with No Images

In this tutorial, I will show you the code step by step to create a full HTML5 CSS3 contact form like the one above, without using any images. First, a little disclaimer. HTML5 and CSS3 are still working drafts; the goal of this tutorial is to show what we can do with those technologies. This form has some compatibility issues with old browsers, so if you want to use it in production, do so at your own risks.

The form we will build is a simple contact form with basic information: name, email, URL, subject and message.

Full CSS3 HTML5 Contact Form with No Images

[tut demo=”href=”http://www.onextrapixel.com/examples/html5-css3-contact-form/” download=”http://www.onextrapixel.com/examples/html5-css3-contact-form/html5-css3-contact-form.zip”]

For the sanity of the code, I omitted the vendor prefixes in this article, but you will find them in the complete file (or by viewing the source code of the example)

Final Product

HTML5 New Form Elements

HTML5 specs introduce many new form elements to enhance form functionalities. For this tut, here are the ones we will use in our form:

  • Input type = email can be used when user needs to enter an email address. Browsers that support it will be able to detect if what the user entered was an email address or not.
  • Input type = url can be used to check if the user entered a correct and valid URL.
  • Autocomplete = on attribute can be placed either on the form, or on single inputs. When autocomplete = “on”, if the a user has already completed a form, the autocomplete attribute enables him to find what he already entered.
  • Require = required attribute sets the state of a form element as required. For browsers which support it, the user won’t be able to send the form until all the required fields have been completed. By default the user can’t see required fields until he submits the form, so the web designer still has to add a visual indication.
  • Placeholder this attribute represents a short hint so that the user knows what he can enter as data, for example the format for email. The placeholder disappears when the user clicks on the field, and reappears when the cursor is moved and the field is still empty.

Now that you are more familiar with the new elements, let’s see the HTML code for our nice little form :

<div id="content">
<h1> Contact me </h1>

<form action=" " method="post"  autocomplete="on">
<p> <label for="username" class="iconic user" > Name <span class="required">*</span></label> <input type="text" name="username" id="username"  required="required" placeholder="Hi friend, how may I call you ?"  /> </p>

<p> <label for="usermail" class="iconic mail-alt"> E-mail address <span class="required">*</span></label> <input type="email" name="usermail" id="usermail" placeholder="I promise I hate spam as much as you do" required="required"  /> </p>

<p> <label for="usersite" class="iconic link"> Website </label> <input type="url" name="usersite" id="usersite"  placeholder="e.g.: http://www.miste.com" /> </p>

<p> <label for="subject" class="iconic quote-alt"> Subject </label> <input type="text" name="subject" id="subject"  placeholder="What would you like to talk about?" /> </p>

<p> <label for="message" class="iconic comment"> Message  <span class="required">*</span></label> <textarea placeholder="Don't be shy, live me a friendly message and I'll answer as soon as possible "  required="required" ></textarea> </p>

<p class="indication"> All fields with a <span class="required">*</span> are required</p>

<input type="submit" value=" ★  Send the mail !" />      

Naked Form

Not many ids or classes, the goal here is to use as less HTML as possible and to use CSS3 to style the form. And don’t forget to use the HTML5 doctype !

Creating the Striped Background

Let’s start with general layout and let’s give this form a background.To create the striped border, we will only style one element : #content. The idea here is pretty simple : we will create a full striped background on this element using CSS3 gradients like this :

margin:50px auto;   
border:1px solid #383838;   
background: #D1D1D1;
/* My stripped background */
background: repeating-linear-gradient(-45deg, #EFC1CB , #EFC1CB 30px, #F2F2F2 30px, #F2F2F2 40px, #C2E8F5 40px, #C2E8F5 70px,#F2F2F2 70px, #F2F2F2 80px);
box-shadow:0px 1px 6px #3F3F3F;

Let’s take a closer look at our gradient : background: repeating-linear-gradient(-45deg, #EFC1CB , #EFC1CB 30px, #F2F2F2 30px, #F2F2F2 40px, #C2E8F5 40px, #C2E8F5 70px,#F2F2F2 70px, #F2F2F2 80px);.

Putting this in words, here is what we are doing : create a linear gradient with a 45° angle, the first stripe is a pink one, that goes from 0 to 30px, then add a grey one from 30 to 40px, and a blue one from 40 to 70px, and finish with another grey one from 70 to 80px. Repeat the whole gradient. Doing this, we create a 45° striped “gradient” with a 30px pink line, a 10px grey one, a 40px blue one, and a 10px grey one.

Stripped Background

Now that we have our gradient background, we will cheat, remember we want a border. All we have to do, is position a new container on the top of it, with another color. We don’t want to add unnecessary spans or divs, so we will use a pseudo class :after to do the trick :

/** my "fake" background that will hover the stripes **/
position: absolute;
content : " ";
bottom: 0;
left: 0;
right: 0;
top: 0;
z-index: -1; 
border:1px #E5E5E5 solid;       

The “size” of our border is here controlled by the margin of the after element. Remember to use enough padding on #content so that your content will actually be “inside” the after fake background.

Styling H1 and Text Font

For the h1, I chose the Questrial font, for the body the Droid Sans and the ampersand will use the Alice font. Those are Google font directory fonts, so all I have to do is use the Google font api code in my header like this, one http request to style them all :

<link href='http://fonts.googleapis.com/css?family=Questrial|Droid+Sans|Alice' rel='stylesheet' type='text/css'>


I applied the droid sans to the body, and the questrial to the h1. For the h1 decoration, we will again use the :before :after tricks :

h1 {
font-family: 'Questrial', Verdana, sans-serif;
margin:0 0 20px 0;

/** have a nice ampersand **/
h1:after {
content: '&';
font-family: 'Alice', Verdana, serif;
text-shadow: 0px 1px 0px #fff;

/** create the gradient bottom **/
h1:before {
content: ' ';
background: linear-gradient(left,  rgba(255,255,255,0) 0%,rgba(182,180,180,0.7) 42%,rgba(180,178,178,0) 43%,rgba(168,166,166,0) 50%,rgba(180,178,178,0) 57%,rgba(182,180,180,0.7) 58%,rgba(238,237,237,0.3) 90%,rgba(255,255,255,0) 100%); /* W3C */

Adding the Little Icons, with No Images

Here comes the good trick, I’m sure you are wondering “she said there will be no images, how did she add those little icons?”. The trick is quite simple, we will be using an icon font. For those who are not familiar with the concept, it consists of mapping each letter of the alphabet with an icon, and creating a font using those icons. An interesting article by Chris Coyer from csstricks should help you get a better understanding of how this works.


Credit where due, for this demo we will be using the awesome icon font by P.J. Onori called iconic.

Here is the code, again, we will use the :before trick you’re getting used to it.

/** adding our icon font !! */
@font-face {
font-family: 'IconicStroke';
src: url('font/iconic_stroke-webfont.eot');
src: url('font/iconic_stroke-webfont.eot?#iefix') format('embedded-opentype'),
url('font/iconic_stroke-webfont.woff') format('woff'),
url('font/iconic_stroke-webfont.ttf') format('truetype'),
url('font/iconic_stroke-webfont.svg#IconicStrokeRegular') format('svg');
font-weight: normal;
font-style: normal;

font-family: "IconicStroke";
.iconic.link:before { content: '/'; }
.iconic.quote-alt:before { content: "'"; }
.iconic.comment:before { content: "q"; }
.iconic.user:before { content: "u"; }
.iconic.mail-alt:before { content: "M"; }

We first apply the iconic font to all our “icons” and then, use letters associated with the icon. The idea of using a before, is that this is pure non semantic styling, so the letters won’t add any non semantics in the html code.

Here we can use the icon font since we still have the label in plain text, so it’s basically just eyecandy and won’t trigger usability issues : form will still be readable even if the font won’t load.

Styling our Fields, the Power to Say :not()

As I said in the introduction, we want to use as little HTML as possible, so no ids. To format our inputs, we could trigger them one by one, using input[type= text, email …]. But CSS3 gives us a quicker, cleaner solution, the :not().We want all our inputs to look the same except the submit button, so we can use this : input:not([type="submit"]).


Here is the code, comments should help you understand each part

/** we remove the red glow around required fields since we are already using the red star */
input:required, textarea:required {
/** inputs and textarea**/
padding:4px 8px;
border:1px dashed #DBDBDB;
font-family:'Droid Sans',Tahoma,Arial,Verdana sans-serif;
transition:background 0.2s linear,
box-shadow 0.6s linear;
border:dashed 1px #969696;
box-shadow:2px 2px 7px #E8E8E8 inset;
height: 20px;
/* placeholder */
::-webkit-input-placeholder  {

What we can emphasize here :

  • We removed the browser focus style with outline:none; to add our own focus/active style.
  • We used CSS3 transition to add a nice effect when the field is active. Note that you can use different transitions on different elements with different timings as long as you separate them with commas.
  • We have to use the vendor prefix to style the placeholder. Note that webkit-input-placeholder also works on textareas (bug or not ? good question) but for Mozilla you will have to use a specific one for textareas.
  • Since we are using a red star (see next point) to style the required fields, we will remove the ugly default red glow from browsers.

Time to Style the Send Button!

For the send button, we use an input type=submit, and here, we unfortunately can’t use the :before :after trick, it does not work on such inputs. So I used a special character directly in the HTML. I’m not so proud of this non semantic solution, so you may want to remove it.

Final Form

To style the button, we here again use some gradient goodness, and a little box shadow trick I’ll explain after the code.

/** Styling the send button **/
font-family: 'Alice',serif;
padding:10px 4px;
border:1px solid #E0E0E0;
text-shadow: 0px 1px  1px #E8E8E8;
background: rgb(247,247,247);
background: linear-gradient(top,  rgba(247,247,247,1) 1%,rgba(242,242,242,1) 100%);
box-shadow:0px 1px 1px #FFF inset,           
0 0 0px 5px #EAEAEA;
transition:all 0.2s linear;

border-color: #CECECE;
background: linear-gradient(top,  rgba(244,244,244,1) 0%,rgba(242,242,242,1) 100%);
box-shadow:0px 1px 1px #FFF inset,
0 0 0px 5px #E0E0E0;       

background: linear-gradient(top,  rgba(234,234,234,1) 0%,rgba(242,242,242,1) 100%);
box-shadow:0px -1px 1px #FFF inset,
0 0 0px 5px #E0E0E0;

The button is composed of a very light gradient, a 1px white inset box shadow at the top, a first 1px grey border, and a second 5px grey border. I see what you will say “but you can’t apply two CSS borders”, and you’re right. That’s where our box-shadow trick comes in. You can set as many box shadows you like using comma.

The trick here is in the sentence “The property is a comma-separated list of shadows, each specified by 2-4 length values” of the specs: you can set a length to the box shadow, and that’s what we do with the 0 0 0px 5px #E0E0E0. We create a box shadow with x and y 0 shadow, a grey color, and a 5px length, thus creating a “fake” second border.

Styling the Labels with Nice Transitions

To finish, we will add some nice colors and transitions to our labels when the user hovers over them.

-webkit-transition: color 1s ease;
-moz-transition: color 1s ease;
transition: color 1s ease;
transition: color 1s ease;
transition: color 1s ease;


Here I just wanted to emphasize the fact that you can add many pseudo classes like label:hover:before. For the moment unfortunately the transition on pseudo class will only work on Firefox, so the icon’s color will change with no transition on chrome. And that’s by the way another goodness of the icon font : you can easily change its color without the need of a sprite for example. Your turn to have fun.

You can now have a little bit of fun with the form, test hover effects, and test the power of the HTML5 new elements. Try to click on send without filling the required fields, or enter an invalid email address to see what happens. I would recommend using Firefox or Chrome latest versions.

[tut demo=”href=”http://www.onextrapixel.com/examples/html5-css3-contact-form/” download=”http://www.onextrapixel.com/examples/html5-css3-contact-form/html5-css3-contact-form.zip”]


I hope this tutorial gave you a better understanding of the future and all possibilities that HTML5 and CSS3 can offer us. I will once again emphasize the fact that this is a demo, for the purpose of playing around with code, and that you should not use it on a live website unless you know what you are doing and use solid fallbacks.

To enhance compatibility, you could for instance detect browser features using modernizr and you can find some useful HTML5 polyfills.

Your turn now: how do you use CSS3 in your projects ? What about HTML5? Add a comment to this article to give us your opinion.

Stéphanie Walter is a Graphic and Web Designer. She's a Pixel and CSS lover who also enjoys working on UI and UX design for Mobile and Web Apps. She considers CSS as a design tool to create great interactive websites and share on different blogs what she learns daily.


    • David Clothier,
    • January 23, 2012
    / Reply

    Awesome! Thanks for sharing…

  1. / Reply

    great tutorial, need to look at this further, I’ve been using Aweber and more recently MailChimp and just completed a tutorial on how to add a MailChimp free form and then change the submit button color after embedding it in a site. So I’m wondering if you created a form like this how would you use it? Do the details just come through via email, (I need to read it fully).

    I love all the code though and the explanations, something to bookmark and come back to


    1. / Reply

      Hi Lee,

      I’m note quite sure about your question, are you asking “how will i retried the details the user submited” ? Basicaly, this in done on your server, and depends on the script language it uses. Usually it would be php, you retrive values submited, and then you can send it to yourself, put them in a data base, etc. I would advice you to try to find a tutorial on “webform submission” for example, it should help your a lot :)

      1. / Reply

        back again today, on your form message placeholder “Don’t be shy, live me a friendly message and I’ll answer as soon as possible ” should be leave. It more or less works perfectly. Couple of things I need to iron out.

        Your code adds the border to the submit button I already have, also MailChimp
        The final version does not look like your either size and shape is correct, but the stripey border does not appear, the shadow does.

        lot of code to go through but I like it, I’m assuming I will be able to add my id from one of my own forms, change up the code and go from there. Like it though.

        1. / Reply

          Well as I said, this is an experiment, so it might not work on everybrowser. And I have to admit that I’m not familiar with the mailchimp forms, I don’t know if you can tweek the html structure.
          Il you need an image or an extra div, it’s fine to use it as long as it serves a purpose :)

  2. / Reply

    i love to learn more about HTML5 and CSS3 techniques and your useful article helping me alot. thanks

  3. / Reply

    Nice! I like the labels with nice transitions. Thnx!

  4. / Reply

    Thanks for posting this, I just completed the tutorial ( I used MS visual studio 2010) and I’m in love with it! Icons as a font, very very awesome.

    1. / Reply

      For the icon font you might want to be carefull with it, some tests were made and it seems like some screen-readers tend to “read” the letter, even if used in a :before/ :after. So this might cause accessibility problems

    • Kirn,
    • January 29, 2012
    / Reply

    How do you know which letters map to which icons in the icon set? I downloaded it but I’m having trouble figuring out how to get other icons.

    1. / Reply

      You need something like Fontcase.

    2. / Reply

      You just have to take a look in the css provided in the file :)

    • Corfu,
    • February 1, 2012
    / Reply

    thanks for instructions Stephanie

    • Prodyot,
    • March 8, 2012
    / Reply

    A very cool form.
    By the way I am not good in math and I almost failed in the “spam protection” where they asked me (1+3=?).
    I had to google to get the answer :)

  5. / Reply

    And I thought I was doing it wrong!

  6. / Reply

    Just Mind Blowing ……..

    • Gustavo Reis,
    • March 18, 2012
    / Reply

    Hello Stéphanie!

    Good evening!

    I learned your tutorial. That full CSS3 and HTML5 contact form worked very well on my blog post (Blogger), but we always have one little problem. The problem is that when I put the , I tested to submit a message, but when I sent the message, the Mail’s application was open and the e-mail wasn’t sent directly to my e-mail. I have already googled and I didn’t get the result. I’m not satisfied with the JotForm, which sends the messages directly to the e-mail, so I tried to add the sources of each tag to JotForm tags.

    Some tips about how making this contact form sending the message directly to the e-mail?

    Thank you for your attention, understanding and help!


  7. / Reply


    I love this but I have one problem…I can’t seem to locate where you insert the email address in which the contact form is sending to. I feel like I’ve been through this form like 10 times and can’t figure out where it goes?

  8. / Reply

    This is the fantastic HTML and CSS tutorial I’ve ever seen really amazing woooowwww

    • Fitz,
    • April 1, 2012
    / Reply

    Dear Stéphanie,
    this is a magnificent form you’ve created and I really would love to implement it on my WordPress Site. I’m hosting it myself but am not very used to using Html and Css. Could you tell me where in wordpress i have to copy which part of code to have it work?

    Thank you very much :)!

      • Fitz,
      • April 1, 2012
      / Reply

      OK, I’ve already managed the design stuff. But how do i tell the form to send an email to my adress, wenn the send button is clicked :)?

    1. / Reply

      First I would not advice to use this on a live website, as I said, it’s demo only, they are plenty of CSS elements that are not supported. If you really want to use it on a live site on WordPress, it will depend on your template. You might have a special template for the form, or a plugin. Hard to tell :)

  9. / Reply


    I’m impressed by the code and the graphic results. Great example.



  10. / Reply

    Alright im a total n00b at this. so please be patience.

    I can understand how ti implement the css code and get a contact form. How ever how do i implement dat when the end user hits the send button I will get the email.

    Im making an Iphone app for my website http://www.hgn4u.nl. it’s insurance company. I would like my client to be able to report and damages home or car accidents from this app.

    With a contact form like this it should be possible right :-$?

    Kind regard and thanks in advance

  11. / Reply

    Awesome form, thanks a lot

  12. / Reply

    Hello Stéphanie, great form but when i’m using it for a site font based icons are not appearing.

  13. / Reply

    Nice Tutorials……..

    • Spyros,
    • May 30, 2012
    / Reply

    Hi! Great tutorial!!!

    I have a question regarding the use of characters in css file. I have downloaded the font and there are only Hexidecimal values in the files. How did you convert the hex values in normal characters as in your tutorial?
    I have google it and nothing came up! (and I am good at googling!!!)

    Which files should I look into or how do I find which characters of the font match which “keyboard” characters?

    I hope my question makes sense…


  14. / Reply

    Hi Stéphanie !

    Thank you a lot for this really great template ! I needed to write a basic contact form for a website I’m working on and I must admit your tutorial helped me a lot !

    I added to your code a few PHP source code in order to manage the actual behavior of the form : sending the e-mail, with a few security constraints. If it can help anyone, I wrote a not about my contribution right here : http://blog.antoineneveux.fr/a-complete-php-contact-form/ and I shared all the source code.

    Thanks again for your tutorial Stéphanie ! That’s a really nice work :)

    • Kev,
    • June 4, 2012
    / Reply

    Not bad but it’s not responsive design. If anyone is interested, you can get a form like this made responsive. In other words, it looks good on all screen sizes from an iPod to a wide screen tv or projection screen.

    There are 6 great contact forms to choose from, all with security captchas.

    You can find it her: http://templatz.co/contact-forms.php

    1. / Reply

      Yes it is not responsive. But you can make it responsive if you’d like and share the link :) I warm you that the stripes won’t work properly on every browser when you try to make it responsive tough. So you might want to use a technique with breakpoints and fix sizes instead of percentages.

  15. / Reply

    seriously the coolest contact form I have seen ever.

    1. / Reply

      Did you come up with this idea by yourself? It’s okay to learn from someone elses source code to learn something. It’s important though, that you do actually learn something. Using code without understanding the mechanics sounds nerve-wracking. Speaking of sources, I cite them. Not just when or because I have to. I cite my sources because I want to. <3

      1. / Reply

        Of course I did come with the idea and code myself, and it’s kind of harsh to read that you doubt it. If I had copied it I doubt that Onextrapixel would have published it. Just look at my folio or other tuts I wrote if you think I don’t unerstand code I write :)
        Like everybody else I read other tuts, but this one is 100% mine. Also the syntax for HTML and CSS is a “standard” so yes, a gradient or an input looks the same on all tuts. That no copy, that’s valid code :)
        And I cite sources, juste look at the icon part and you’ll see

    • Raquel,
    • November 18, 2012
    / Reply

    wow you are really amazing Stefanie… and thanks for sharing your work

  16. / Reply

    sory i cant send email with this form, wheres is the send.php¿?

    • Edward DiSouza,
    • January 25, 2013
    / Reply

    Bonjour Stéphanie! After reading your amazing job on this form I was about to say “Wow, I love you…!” but, I already love my girlfriend… However, this is such an amazing coding masterpiece!!! Pretty clever, I must say. Thank you very very much for sharing. Merci beaucoup!

Leave a Reply

Your email address will not be published. Required fields are marked *

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


Iconfinder Coupon Code and Review

Iconfinder offers over 1.5 million beautiful icons for creative professionals to use in websites, apps, and printed publications. Whatever your project, you’re sure to find an icon or icon…

WP Engine Coupon

Considered by many to be the best managed hosting for WordPress out there, WP Engine offers superior technology and customer support in order to keep your WordPress sites secure…

InMotion Hosting Coupon Code

InMotion Hosting has been a top rated CNET hosting company for over 14 years so you know you’ll be getting good service and won’t be risking your hosting company…

SiteGround Coupon: 60% OFF

SiteGround offers a number of hosting solutions and services for including shared hosting, cloud hosting, dedicated servers, reseller hosting, enterprise hosting, and WordPress and Joomla specific hosting.