Designing Search Boxes with HTML5 and CSS3

This entry was published on 5 November 2010 and may be out of date.

Search is one of the most important part of any website. Here, I will show a few practical techniques for designing search forms and a few tricks to build usable and good-looking search functionality.

Smashing Magazine did an excellent piece on Search Boxes which inspired me to write this post. Instead of listing various types of designs, I will show you how to build them!

Let’s get started!

Here, with the help of three simple examples, allow me to show how to code search boxes with HTML & CSS and how to spice things up with a bit of Javascript.

The example initially designed for this tutorial was too difficult for most people, so I have decided to start you off with a simple example to start off with. They get more and more complicated as you read along.

Example 1

[iframe /demo/search_boxes/index.html 550 100]

Techniques that are used here are:

  • Inner shadow with CSS3
  • Uses an image as the button, along with rollover effects

The Markup

<div id="searchBoxOne">
  <form action="?" method="get">
    <input type="text" />
    <input type="submit" value="Submit" />

It is a simple form wrapped in a div. It contains a textbox with class text and a submit button with class submit. Easy as pie.


#searchBoxOne {
    font-size: 16px;
    color: #999;
    padding: 6px;
    -moz-box-shadow:inset 2px 2px 5px #ccc;
    box-shadow:inset 2px 2px 5px #ccc;
    border: 1px solid #b8b8b8;
#searchBoxOne input.submit {
    background: url(images/01_submit.png) top left no-repeat;
    width: 67px;
    height: 32px;
    border: none;
    color: #dee4ff;
    cursor: pointer;
#searchBoxOne input.submit:hover,
#searchBoxOne input.submit.hover {
    background: url(images/01_submit.png) bottom left no-repeat;

A few points you should note:

  • The height and width of the button must match the size of the image. In case you are using image sprites, use half the height.
  • The cursor: pointer makes the button look more clickable to the users.
  • The :hover pseudo-class is for switching to the onhover state.

If you are not familiar with the CSS3 box-shadow property, you might find these helpful:

The only problem with this implementation is the fact that IE7-8 do not support the :hover pseudo-class. The workaround to the problem is a little bit of Javascript as illustrated below.

$(document).ready(function() {
    $("input.submit").bind('hover', function() {
    }, function() {

We are adding the class hover on the element on mouseover, which applies the CSS illustrated above – making sure that browsers that do not support the :hover pseudo-class also apply the hover effect.

Example 2

[iframe /demo/search_boxes/02.html 550 100]

Techniques that are used here are:

  • How to use rounded corners with the help of images
  • How to use images within the search form

Unfortunately, it is not possible to use the CSS Sliding Doors technique for the input fields without adding some extraneous markup. So I have decided to simply use an image for the background for the rounded corners.

I’ll be using the same HTML markup as before, with insignificant modifications for the sake of this tutorial. Let’s jump to the CSS stylesheet for this example.

#searchBoxTwo {
    font-size: 12px;
    color: #999;
    padding: 4px 10px 5px 30px;
    width: 313px;
    border: none;
    background: url(images/02_background.png) top left no-repeat;

#searchBoxTwo input.submit {
    display: none;

When adding images within input fields, make sure you add enough padding so that the text never overlaps the image.

The problem here is that due to the fact that there is a “value” inside the input field, when you click on it, the text does not disappear. You have to manually remove the text before you can type in your search term. This is a problem we will solve in the next example, along with a little HTML5 magic.

A major problem you will face is the fact that Webkit based browsers (Safari, Chrome etc) have some default properties that will make your design look rather odd when the input box comes to focus. Here’s a screenshot from Google Chome:

Google Chrome
Webkit renders funny. But we can fix this.

The workaround to this problem is a little bit of non-standard code in order to reset input boxes in Webkit.

Example 3

[iframe /demo/search_boxes/03.html 550 100]

Techniques that are used here are:

  • Rounded corners (border-radius) with CSS3
  • CSS3 gradients
  • HTML5 Search box and the placeholder attribute

The Markup

<div class="content">
<div id="searchBoxThree">
  <form action="?" method="get">
    <input type="search" placeholder="Search" />
    <input type="submit" value="Search" />

I have used <input type=”search” /> which is only supported by Webkit at the moment. All other browsers will render as <input type=”text” />. ((Mark Pilgrim’s Dive into HTML5 covers every base in complete detail.))


Since this is about to get a bit complicated, let me explain a wee bit at a time.

First off is the transparent box that encompasses the form. It is black with 20% opacity. Also contains a bit of drop shadow.

#searchBoxThree {
    -moz-border-radius: 5px;
    border-radius: 5px;
    background-color: rgba(0,0,0,0.2);
    position: relative;
    -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.2);
    -moz-box-shadow: 0 1px 2px rgba(0,0,0,.2);
    box-shadow: 0 1px 2px rgba(0,0,0,.2);

Next up is the Search box itself.  Safari has an interesting way of rendering Search Boxes. So we are going imitate that in all other browsers with CSS.

#searchBoxThree {
    border: 1px solid #6E93A9;
    -moz-border-radius: 15px;
    border-radius: 15px;
    height: 13px;
    padding: 2px 10px;
    width: 200px;
    color: #999;
    font-weight: normal;

#searchBoxThree {
    border: 1px solid #639bcf;

And finally, the submit button. I am using CSS3 Gradients combined with CSS pseudo-elements  to make a cool button.  ((Before you proceed any further, I would recommend reading up on Ethan Marcotte’s Everything You Wanted to Know about Gradients (And a Few Things You Didn’t).))

#searchBoxThree input.submit {
    background: -webkit-gradient(linear, left top, left bottom, from(#7dbe0a), to(#a2d93f));
    background: -moz-linear-gradient(top, #7dbe0a, #a2d93f);
    filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr='#7dbe0a', endColorstr='#a2d93f');
    color: #FFF;
    border: 1px solid #7ec115;
    height: 19px;
    line-height: 14px;
    text-shadow: 0 1px 1px rgba(0,0,0,.3);
    -webkit-border-radius: 5px;
       -moz-border-radius: 5px;
            border-radius: 5px;
    position: absolute;
    right: 4px;
    top: 3px;
    cursor: pointer;
 #searchBoxThree input.submit:hover {
    background: -webkit-gradient(linear, left top, left bottom, from(#a2d93f), to(#7dbe0a));
    background: -moz-linear-gradient(top, #a2d93f, #7dbe0a);
    filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr='#a2d93f', endColorstr='#7dbe0a');
 #searchBoxThree input.submit:focus,
 #searchBoxThree input.submit:active {
    background: -webkit-gradient(linear, left top, left bottom, from(#7dbe0a), to(#a2d93f));
    background: -moz-linear-gradient(top, #7dbe0a, #a2d93f);
    filter:  progid:DXImageTransform.Microsoft.gradient(startColorstr='#7dbe0a', endColorstr='#a2d93f');

And that is all the CSS3 magic you will need for this.

The placeholder attribute remains a gotcha at this point. So we are going to use little bit of Javascript to solve this issue. As HTML5 becomes adopted across all platforms, this bit of code ((Thanks to Ilia Draznin)) will become redundant.

$(document).ready(function() {

 if ($.browser.webkit) return false;
  target = $('input[type="text"], input[type="email"], input[type="search"]');

  target.each( function(i, el) {
  el = $(el);
  var ph = el.attr('placeholder');
  if (!ph) return true;

  el.attr('value', ph);

  el.focus( function(e) {
  if( el.val()==ph ) {
   el.attr('value', '');

  el.blur( function(e) {
  if( $.trim(el.val())=='' ) {
   el.attr('value', ph);

As one of the commenters pointed out, there is a non-jquery solution out there as well.


The above examples demonstrate that it is feasible to design websites with HTML5 and CSS3 as every technique used here is completely backwards compatible and degrades gracefully in older browsers. So there is absolutely no reason not to start using the new tools in our arsenal.

With a little bit of HTML and some simple CSS3, it is easy to design standard-compliant and cross-browser search boxes, just like anything else. I felt that most developers overlook the importance of the search box and create usability nightmares. So I thought a little sharing could save the planet, one usable search box at a time.

What you have learned:

  • How to add inner shadow to text boxes with CSS3
  • How to add rounded corners (with and without images)
  • How to use CSS pseudo-elements
  • How to use an image as the Submit button
  • How to use Javascript to add interactivity
  • How to use nothing but CSS to create beautiful and usable search forms.

I hope you found the snippets helpful. Please share experiences and samples from your own experiments. Suggestions are greatly appreciated.

Comments are closed.

25 responses to “Designing Search Boxes with HTML5 and CSS3

  1. You should also use a default background for non gradient-capable browsers:

    and then use the background-image:-moz-gradient(…); to overwrite it later. That keeps the background-color for older browsers.

    Well, all inputs should have the :focus and :hover with outline:none; added, because it’s default in webkit-based Browsers and isn’t looking well =)

  2. do you know there’s a (totally customizable with ::-webkit- properties for webkit browsers) just for that? and also, there’s a much better approach with no need of jQuery for the placeholder script that fixes some of the problems on your code here:

    Hope it helps.

    Greetings, Bart.

  3. Thank you for this page that u has been show slide good for me, i’ll to learn edit this slide into my website,

  4. I would like to update you, to add >>class=”search”<< 🙂

    I am an beginner, and had to search for a while, why ure code wont work (inputfield wont be modified by css (…searchBoxOne input.SEARCH)).