Theming The Search Submit Button - A CSS Cross-Browser Compatible Solution

More sites these days are using a custom image like a magnifying glass, or the word 'GO' in a circle, instead of the default search submit button. Here's a way that you can do the same thing with the Drupal search function, and only have to use CSS - no PHP and no editing template files (well, almost).

The image on the left shows the default search submit button, and the image on the right shows the new search submit button that we'll replace it with.

The default search box and the new search box

It's really just a simple three step process:

  • Step 1: Create your image
  • Step 2: Add a conditional comment to your page.tpl.php file
  • Step 3: Add your CSS

Step 1: Create your image

The image can be of whatever you like, and is probably best in .jpg format.

Just make sure you save it into your theme's normal images folder.

For instance, if I am going to use an image of a magnifying glass called 'mag_glass.jpg' I would save it to '/sites/all/themes/mydrupalblog/images/mag_glass.jpg'

Step 2: Add a conditional comment to your page.tpl.php file

A conditional comment is just a small bit of code which we add to the page.tpl.php file in order to allow us to specifically target Internet Explorer with different CSS rules.

As you'll see in a second, this is necessary because Internet Explorer interprets our CSS differently, and we need to supply it with some extra rules to make it look right.

In short, you just need to add the following code to your page.tpl.php file directly after the opening body tag

<!--[if IE]><div id="IEroot"><![endif]-->

and then add the following directly before the closing body tag.

<!--[if IE]></div><![endif]-->

Basically, this creates a new div with an id of 'IEroot' which wraps around everything inside of our body tags if a user is browsing with Internet Explorer, and ignores it if a user is using any other browser like Firefox. This allows us to write CSS which targets the #IEroot, and know that it will only be used by IE - very handy.

For those who are interested, a detailed explanation of this method can be found in
this article over at positioniseverything.net.

Step 3: Add your CSS

Finally, we add the necessary CSS to our style.css file.

We'll start by adding the general rules which cover most browsers

#search-block-form input.form-submit, #search-form input.form-submit {
  height: 24px;
  width: 24px;
  cursor: pointer;
  text-indent: -9999px;
  border: none;
  background: url(images/mag_glass.jpg) no-repeat left top;
}

The above code covers both the search block and the search form on the main page. Just remember to change the height and width accordingly for your own image.

This now looks great in Firefox, but not so good in IE.

The search box in Firefox and the search box in IE

The problem is that IE will not text-indent the text on the submit button. Also, IE now completely removes the search submit button from the Advanced search fieldset on the main page.

The advanced search form in Firefox and IE

So, we need to find a sneaky way of making it look like the text has actually been removed from IE when it hasn't, and also sort out that missing search button.

The following code will do the trick:

#IEroot .block-search input.form-submit, #IEroot #search-form input.form-submit {
  width: 34px;
  font-size: 0;
  color: #fff;
  text-align: right;
}
#IEroot #search-form .search-advanced input.form-submit {
  width: 44px;
  text-indent: 0;
}

Using the #IEroot selector, we first tell IE to make the text very small by declaring 'font-size: 0;' (FIG 1). However, IE still won't remove the text completely, so we then create an area to the right of the magnifying glass image into which we can put the text. We do this by changing the width of the image and setting 'text-align: right;' (FIG 2). You will need to add 10px to the search block image width, and 20px to the advanced search form image width for this to work. Finally, we change the font color to match with our background, in this case white, and this completes the illusion (FIG 3).

Sorting out the search box in IE

Lastly, adding 'text-indent: 0;' to the #IEroot advanced search form gets IE to give us our submit button back :)

So far, I have tested this in Firefox, IE7, and IE6. It might seem like a slightly hackish solution, but it avoids any necessity to try and catch the search form by editing the template.php file and then have to setup extra .tpl.php files. It also uses a relatively small amount of CSS, and is (hopefully) quite easy to understand.

45 comments

themegarden.org June 19th, 2007 @ 3:03pm

Nice trick, I mean hack.
It's always a fun to fight with IE

Laurence June 19th, 2007 @ 4:00pm

I'm not sure I'd use the word fun ;-)

ragaskar August 2nd, 2007 @ 11:52pm

Clean CSS solutions are loads better than wacky template hacks that subvert the form api. Great bit of code! Thanks!

Fiasst October 2nd, 2007 @ 5:22pm

Ive used a custom search form before. Can't remember where I found it but It's very handy!

Just create a new page template called 'search-theme-form.tpl.php' and add the below PHP to your template.php file:

/**** Custom search form ****/
function phptemplate_search_theme_form($form) {
return _phptemplate_callback('search-theme-form', array('form' => $form));
}

Example of your custom search form:

<input type="text" name="searchfield" class="txt" title="Search" onfocus="inputc(this,'Search')" onblur="inputr(this,'Search');" value="Search" />
<input type="submit" name="op" id="edit-submit" title="go" value="go" />
<input type="hidden" name="form_id" id="edit-search-theme-form" value="search_theme_form" />
<input type="hidden" name="form_token" value="<?php print drupal_get_token('search_theme_form'); ?>" />
Adam October 4th, 2007 @ 11:09am

Fiasst, you probably found that bit of code here, and I couldn't agree more it is very handy!

Rene Hache November 1st, 2007 @ 10:32pm

Laurence,

Thanks for the tip. I have a few of questions about your tip and I'm wondering if you could answer them:

-- The IE width is 10px more than the regular (ie 34px vs 24px). Why 10px? Is it always 10px more than whatever works in FF? Basically, how did you figure out that difference?

-- Can you get rid of the conditional IE DIV if you use conditional IE CSS?

Thanks,
Rene

Secret Owl April 4th, 2008 @ 1:48am

Thanks a load mate, really helped my css-uneducated ass out! I should probably stop obsessing over little details, though; tis unhealthy.

Kyle April 14th, 2008 @ 5:25am

Nice trick - although, I should point out: No need for the additional div - just add that CSS you'd like for IE-only in between the comments (where you have the div). This will overwrite your "real" css file, and avoids extra markup! (You just have to make sure that the commented CSS comes after the link to your stylesheet).

Mike April 24th, 2008 @ 10:17am

This rollover image submit button would probably serve 'most' peoples needs..

<input type="image" src="images/search.gif" onmouseover="this.src='images/searchon.gif'" onmouseout="this.src='images/search.gif'" alt="Hello World" title="Hello World"/>

Simple :)

Tom Taylor June 4th, 2008 @ 10:09am

If you cant add a div for IE and use conditional tags, just use the underscore hack for IE Only:

_font-size: 0;
_color: #fff
_text-align: right;
_padding-right:2px;

Mozilla, Opera and Safari will ignore any CSS dec's with an underscore before them! ;)

Kyle June 4th, 2008 @ 3:47pm

Worked like a charm! Thanks!

hazır kayan yazı June 20th, 2008 @ 3:12pm

css Cursor examples , Properties , Attribute - - http://css-lessons.ucoz.com/cursor-css-examples.htm

freebird July 31st, 2008 @ 5:18pm

thanks for the tip -- this is exactly what I was looking for.

Guest August 4th, 2008 @ 12:39pm

If the objective is to just push the text out of the way, you can just add :

line-height: 5;

to the submit input and avoid any hack

kktc August 23rd, 2008 @ 9:05am

Thanks m8 .

miki September 25th, 2008 @ 11:42pm

Hi,
you can add

letter-spacing:100px;

then you need only one pixel more of input width :)
regards

Clint Eagar October 2nd, 2008 @ 5:55pm

@ Fiasst

How do I adapt this for D6?

/**** Custom search form ****/
function phptemplate_search_theme_form($form) {
return _phptemplate_callback('search-theme-form', array('form' => $form));
}
Friend October 10th, 2008 @ 6:18pm

Thank you! Exactly what I needed as I only want to swap the search button and don't really feel it's necessary to add more template & tpl.php complexity.

Miles November 3rd, 2008 @ 1:54am

Great hack, thank you so much for this.

Cheers,
Miles

Ousjah November 19th, 2008 @ 1:31pm

Thanks.I have tested this in Firefox, IE7, and IE6, fortnately it worked fine. The text has been removed from IE when it hasn't ....fine. But it's not removed in Opera 9.26. Can anyone figure out something to prevent it from showing.

#IEroot .block-search input.form-submit, #IEroot #search-form input.form-submit {
width: 34px;
font-size: 0;
color: #fff;
text-align: right;
}
#IEroot #search-form .search-advanced input.form-submit {
width: 44px;
text-indent: 0;
}

Guest November 21st, 2008 @ 3:51am

> letter-spacing:100px;

the best one as for me =)

thx, miki.

Pieter Bezuijen November 21st, 2008 @ 1:41pm

Very handy and clear article! My theme is based on Garland, which has a function for a seperate 'fix-ie.css' stylesheet. I think that's much better than the extra div. Maybe you could add a note about that?

Ousjah November 24th, 2008 @ 2:42pm

miki......
Thanks so much....appreciate it so much.

........> letter-spacing:100px;........

Did work perfectly for me too...
Great help thanks.

iWishIeWorkedRight December 3rd, 2008 @ 9:23pm

Thanks for the tip awesome code! I needed something that would work in ie6 since input [ type="text"] doesnt work with ie. Funny thing, I have been using css for a few years and using a class for the input types never occurred to me, I guess it has something to do with the fact that i always figure out the hard way to do things first, then go back and do it the easy way.

You could also hide the text using a something like this:

input.submit {
  display: inline;
  border: 1px solid #666666;
  width: 145px;
  height: 0;
  background:url(images/formBG.png) repeat-x center center;
  padding-top: 35px;
  overflow: hidden;
}

It works in Safari, and it should work in ie 6 considering I use it to hide text when creating nav bars. just set the padding to a value larger than the height of the image used for the button.

RecipesLover December 23rd, 2008 @ 7:08am

Well have you tried your code iWishIeWorkedRight?
cause i try it on ie and it's not working

Daniel Nordstrom January 9th, 2009 @ 10:23am

letter-spacing... That's genius. Thanks! :)

Guest Muy Agradecido January 22nd, 2009 @ 5:06am

Great way of hack IE... my god, how i hate that browser. Again, thank, because that way of hacking (adding conditional tags in the beginning and at the bottom of the body) is great for any kind of fix you have to do to the dammed IE!!! I cant realize why i don't find that way of hacking some projects ago... Great site by the way. Saludos desde Argentina!

ionz149 February 1st, 2009 @ 10:14pm

Many thanks for a great solution!

kat neville February 20th, 2009 @ 3:45pm

Hi there, thanks for posting this... but it doesn't solve the problem when you have a few sitting next to one another... It also doesn't work if you have your button on an image background, or if you want to centre it underneath something.

have you considered using the button tag instead? You can use the text indent for both ie6 and ie7 and it works in firefox as well.

I use

<button class="skinName" type="submit">text here instead of alt</button>

A few important points on this... You HAVE to put the closing button tag in full. Doing a self closing tag on a button makes it not work in ie7/ie6. You don't have to put any text in between the open and close, but it's nice to have it there as alt text.

Hope that's useful!

Martin March 30th, 2009 @ 7:13am

Oh man Cross-Browsers are killing me. Now when IE8 is out I have to do all the hacks from IE6-IE8, yes I know IE6 is still kicking, however most of my clients don't want to upgrade and it has to be perfect on their browser first.

Thank You for great info,
Martin

SteffenR April 21st, 2009 @ 1:08pm

another hack to fight against IE6/IE7 is shown here:
http://www.productivedreams.com/ie-not-intepreting-text-indent-on-submit...
in Addition to your css you have to add the following lines

.class_input {
...
font-size: 0px;
display:block;
line-height: 0px;
...
}

#IEroot is no longer needed..

Mizzinc July 21st, 2009 @ 2:00am

Sweeeeeet piece of CSS.

Thank you.

Guest July 23rd, 2009 @ 12:17am

dooodes

you don't need hack to hide the text :-((( what the hell

-> input type = "button or submit" id="(your styling id)" value=" Leave empty here" <-

simple solution :-|

add the css part to the button and there won't be no text stuff :-|

Sun Location July 23rd, 2009 @ 1:29am

THanks for this css example :)

janamills July 27th, 2009 @ 3:37am

thanks for this just what i was looking for!

krizalis August 11th, 2009 @ 6:30am

Hi,

I think you could use this solution as well:

width:24px;
height:24px;
border: none;
background: transparent url(images/mag_glass.jpg) no-repeat center;
overflow: hidden;
text-indent: -999px;
font-size: 0px;
display:block;
line-height: 0px;
Marcus September 4th, 2009 @ 3:54pm

Thank you so much!!! This has helped me tremendously! Great tric.. i mean hack

Steven iphone H... October 9th, 2009 @ 12:39am

Thanks dude! This trick helped me alot for IE 7 :) THAAANKS!

Random November 11th, 2009 @ 12:05pm

I'm having just a minor issue, when I click over the search button a dotted border appears over the center of the button. I've tried with outline:none; but it doesn't work.

Regards.

James December 9th, 2009 @ 12:35am

I haven't tested this thoroughly, but using text-indent: -999px; line-height: 100em; seems to work just fine on all browsers. Line-height would almost suffice, but Firefox doesn't like it so you toss in the negative text-indent.

Cheers.

Guest March 11th, 2010 @ 10:26am

Or you just remove the Value by using a single line of jquery in your scripts.js:

$(document).ready(function() {

$(".form-submit").val("");

});
works for all Browsers, no text-indent etc needed.
regards

Guest April 21st, 2010 @ 12:17am

All the tips suggesting to remove the value are bad for accessibility, someone who is using a screen reader will have no idea what this input field is for - this includes the tips to use stuff like height:0 and font-size:0; since these are known to hide text from some screen readers, the best solutions just move it out of the way, such as the big line heights and text indent.

Sarandi May 14th, 2010 @ 6:16pm

Hey there - thanks for this tutorial. I have found that a better way to do the conditional css in Drupal is to add the condition statement in your theme.info file like this:

conditional-stylesheets[if IE][all][] = ie.css

The first set of brackets is the browser condition; in this case, it is every instance of IE. I name the corresponding css file whatever the condition statement is, for example:

lteie6.css
gtie5.css

where "lt" is less than and "gt" is greater than.

Ron June 14th, 2010 @ 1:58am

This was helpful but I found something that may be a lot simpler when trying this out.

I was still seeing the text over the picture so I just added

padding-left:80px;

and this fixed it so my final code was

form input.button-submit {
  height: 31px;
  width: 45px;
  background: url(files/you-image.png) no-repeat;
  border: none;
  text-indent: -9999px;
  padding-left:80px;
  /* padding pushes it out of view on IE*/
}

Let me know if there is a reason this doesn't work?
seems to be a nice simple solution.
test it in IE8, FF, SA

Guest July 5th, 2010 @ 9:47am

This works best for me, so long as your button isnt too big.

input[type=submit]
{
float: right;
border: 0px;
width: 178px;
height: 70px;
letter-spacing: 9999px;
text-indent: 9999px;
overflow: hidden;
cursor: hand;
background: url('../images/submit.gif') top right no-repeat;
}

Tested in I.E, 7, IE 8 FF, Opera, Moz. (Who cares about IE6 these days?

Steve

Comments are closed

If you want to ask a question or have something to add please contact me.