Styling Your Search Form with CSS
Blog » CSS/XHTML » Styling Your Search Form with CSSStyling Your Search Form with CSS
Today I would like to cover how to style your search field using background images in CSS. Previously I was using a different technique to style my forms and search fields, but this way seemed to be less of a head ache so I wanted to share it with those who are interested.
Original Approach
First let me go over my original approach which was using <input type="image" src="image-path"> as follows:
<form method="get" id="searchform" action="http://www.sohtanaka.com/"> <fieldset> <input type="text" value="" name="s" id="s" /> <input type="image" src="http://www.sohtanaka.com/wp-content/themes/st2008/images/btn_search2.gif" id="searchsubmit" value="Search" class="btn" /> </fieldset> </form>
This was all fine and dandy but there was one annoying issue. The image button would not align with the search input box and I would have to add a negative top margin to correct this issue. See below for an example.

Revised Approach
With this revised approach, I decided not to go with the type="image" and used the <button> tag, and added a background with CSS. This allowed both input text box and the button to naturally align. I also added a :focus pseudo class for the final touch (IE will not read this, so I added a conditional style specifically for IE to hide this effect). Below are some benefits of this method:
- Aligns naturally
- Only uses one image for buttons and input box
- :focus pseudo class for browsers that support it
- Added hover effect for button

HTML
<form method="get" id="searchform" action="http://www.sohtanaka.com/"> <fieldset class="search"> <input type="text" class="box" /> <button class="btn" title="Submit Search">Search</button> </fieldset> </form>
CSS
fieldset.search {
border: none;
width: 243px;
margin: 0 auto;
background: #222;
}
.search input, .search button {
border: none;
float: left;
}
.search input.box {
color: #fff;
font-size: 1.2em;
width: 190px;
height: 30px;
padding: 8px 5px 0;
background: #616161 url(search_bg.gif) no-repeat;
margin-right: 5px;
}
.search input.box:focus {
background: #616161 url(search_bg.gif) no-repeat left -38px;
outline: none;
}
.search button.btn {
width: 38px;
height: 38px;
cursor: pointer;
text-indent: -9999px;
background: #fbc900 url(search_bg.gif) no-repeat top right;
}
.search button.btn:hover {
background: #fbc900 url(search_bg.gif) no-repeat bottom right;
}
Conditional Comments for IE
<!--[if lte IE 7]> <link rel="stylesheet" type="text/css" href="ie.css" /> <![endif]-->
IE Style Sheet - ie.css
**EDIT** Ingo Chao commented that IE6+7 scrolls the background-image horizontally if the input gets more content, so my fix was to use a unique background image strictly for IE, and instead of aligning to the left, I reversed it and aligned it to the right to correct this bug.
.search input.box {
background: url(search_bg_ie.gif) no-repeat right bottom; /* Unique Input Box background image specifically for IE, and the background position must be aligned to the right*/
}
Additional Resources
- XHTML Strict - Jin Y
- Style Your Website’s Search Field with JS/CSS - Alen Grakalic
- CSS-Based Forms: Modern Solutions - Smashing Magazine
- Search: Visible and Simple - Jacob Neilson
Examples of Creative / Clean Search & Form Fields
Related Posts
Tags: Tutorial
This entry was posted on Tuesday, November 11th, 2008 at 2:03 pm and is filed under CSS/XHTML. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.













Nice tutorial. There’s one problem with your button solution though. With your CSS styled button, there’s no text shown if the styles are taken off (since you left the value empty). So if the user had their styles and images disabled, the button would be blank and wouldn’t say anything. I haven’t been able to find a way to hide the value using css (unless I’m missing something). I’d definitely suggest using the graphical button and your 1st solution to adjust the layout issue.
Zach, good catch! It didn’t dawn on me until you mentioned it~
I replaced the input with a
<button>tag, and also added a text-indent of -9999px to shove it off of the page when styles are enabled. Seems to be working for me now~ Let me know what you thinkThanks for the input!
**Edit** Although I did notice when all images are turned off the button and the text is not visible..
Ill see if I can come up with a solution…
Here is my two cents on this “what if images are turned off” scenario. If images are turned off, most likely the search is not the only thing they will be missing out on, there will be far more important factors of websites that the users will miss. So for those who are disabling styles, images, javascript, they are most likely used to things not working and not showing up as it should be. That is their loss, since 80% of websites depend on these elements anyways. This is similar comparison to designing for those with legacy browsers (IE4,5,etc). Their loss.
I like your site design. Nice post on input boxes. I found your site when I was searching Google for the :focus css code. Too bad it doesnt work on IE…
the issue you were seeing comes from the UA weird handling of inputs in ‘normal’ layout. the submit button and the text input are ‘managed’, but the image input is not. so text and submit line up but image is off by a fair margin.
easy fix for this is to force the issue by using divs:
.left {float:left;}
.stxt {padding:0px;}
.simg {padding:0px;}
.simg input {margin-left:4px;}
.stxtinpt {height:20px;padding:0px;padding-left:4px;border:1px solid black;}
…
IE6+7 scrolls the background-image horizontally if the input gets more content.
In IE6, we’ve found that background-attachment:fixed helps.
IE7 needs background-attachment fixed; background-repeat:repeat; plus handmade values for background-position we did not fully understand.
Doesn’t look ok in Opera.
This is really helpful. I’ve been using wordpress themes where they using some creative text boxes, but never knew the technique behind that.
looks broken in ff3/win2000.
just remove “fixed” from the background property:
.search input.box {
color: #fff;
font-size: 1.2em;
width: 190px;
height: 30px;
padding: 8px 5px 0;
background: #616161 url(search_bg.gif) repeat left top;
margin-right: 5px;
}
The support of the online community is a beautiful thing
. As you can see I am not perfect and let some bugs pass by, you guys have reminded me to proof better and have forced me to come up with a solution quick! :-p Thank you all for the suggestions!
Ingo:
your solution using the fixed background attachment had a strange issue with IE 7 where it wanted to start the image from 0px 0px on top of my browser screen (not starting at the 0 point of the input box).
To get around this issue, I decided to align right instead of aligning left, I also had to revise the image tailoring it specifically to IE7.
this did the trick and fixed our bug, but Im wondering if there is a better solution for getting around this?
Hanz:
Sorry for that, I was trying to fix these bugs on the fly instead of correcting them locally then publishing :-p
Hey… I don’t know if anyone has pointed this out yet, but there is an excellent article on A List Apart about using the tags for forms and using small javascript and CSS to show the labels inside the form input fields only when deselected… That method seems to be better than the graphical one you are currently using as it is more compliant with screen reader software and degrades a little better potentialy?
Check out the article and see what you think:
http://www.alistapart.com/articles/makingcompactformsmoreaccessible/
Mike, I appreciate your suggestion! I will be looking into this, it looks very promising
Nice article, thanks.
Great post! Thanks for css tips&tricks
Found another glitch. If you type something into the field, but it then loses focus, the Search graphic appears again underneath the entered text. Looks a bit messy. I suppose the only work around for this would be to check for entry by Javascript, thus making the solution less elegant.
Hello,
This is nice, although I don’t really see the necessity of this technique. Vertical align problem? Using the vertical-align property (with a value in pixels, positive or negative, if needed) will solve it for the most part. It may allow for imprecision of 1px, so it’s not perfect, but it’s decent. Hover effect? You can do that with a bit of JS, by changing the value of the src attribute.
So I’d stick with
Note that using is not an issue. The issue here, accessibility-wise, is that you hide text to replace it with a background image. Whatever the technique used for this, whatever the content that is hidden and replaced by a background image (link content, heading content, button content…), it won’t ever be accessible. Just because it’s not using a standard way of saying «ok, this is a graphic, and it’s an equivalent for this text». The only existing standard ways to do this are IMG elements with alt attributes, and OBJECT elements with fallback content—relevant content, not «Install Flash Player or be damned.»
(HTML 5 plans for the OBJECT element to be able to display an image, like the IMG element does, but then the OBJECT element could have HTML-formated fallback content instead of a plain text alt attribute.)
So: use BUTTON with an image in it (and alt text), or a INPUT of type “image”, and JavaScript for the hover effect. You may even use some inline JavaScript, it might make things easier (don’t listen to the separation zealot, you’re already tying your presentation and content together by using TEXT AS AN IMAGE where you could be using text, right?).
Well, looks like HTML code is stripped from comments, not escaped for display. My second paragraph makes no sens now.
Thanks.. works great as far as eye can see ^_^ except for (the windows version of) safari.. or i must have done sumtin wrong.. dunno.. used it on http://mentorion.nl
Hi, nice article. I’ve read other articles regarding forms, using buttons as opposed to inputs, etc, and it seems there’s a problem with using the button tag. If I could only recall what it was.. anyone else have an idea? I think it had something to do with IE (doesn’t it always) - possibly only reading one button on a page, so you never know which button was actually pressed, if there’s more than one button on a page - I think that’s it. And possibly that it returns the value of the button not the name, I think. But there are issues with it, unfortunately, as it really is a great form element!
Thanks! you helped me a lot. I used your code on my website and it’s simply COOL