views:

2491

answers:

5

For some reason most modern browsers will stop applying their default input border style to text boxes if you give them a background image. Instead you get that ugly inset style. From what I can tell there's no CSS way to apply the default browser style either.

IE 8 doesn't have this problem. Chrome 2 and Firefox 3.5 do and I assume other browsers as well. From what I've read online IE 7 has the same problem, but that post didn't have a solution.

Here's an example:

<html>
<head>
  <style>
    .pictureInput {
      background-image: url(http://storage.conduit.com/images/searchengines/search_icon.gif);
      background-position: 0 1px;
      background-repeat: no-repeat;
    }
  </style>
<body>
  <input type="text" class="pictureInput" />
  <br />
  <br />
  <input type="text">
</body>
</html>

In Chrome 2 it looks like this: http://www.screencast.com/users/jadeonly/folders/Snagit/media/d4ee9819-c92a-4bc2-b84e-e3a4ed6843b6

And in Firefox 3.5: http://www.screencast.com/users/jadeonly/folders/Snagit/media/d70dd690-9273-45fb-9893-14b38202ddcc

Update: JS Solution: I'm still hoping to find a pure CSS-on-the-input solution, but here's the workaround I'll use for now. Please note this is pasted right out of my app so isn't a nice, stand alone example like above. I've just included the relevant parts out of my large web app. You should be able to get the idea. The HTML is the input with the "link" class. The large vertical background position is because it's a sprite. Tested in IE6, IE7, IE8, FF2, FF3.5, Opera 9.6, Opera 10, Chrome 2, Safari 4. I need to tweak the background position a couple pixels in some browsers still:

JS:

 $$('input.link').each(function(el) {
   new Element('span',{'class':'linkIcon'}).setText(' ').injectBefore(el);
   if (window.gecko) el.setStyle('padding', '2px 2px 2px 19px');
 });

CSS:

input.link { padding-left: 19px; }
span.linkIcon { z-index: 2; width: 19px; height: 19px; position: absolute; background-image: url(img/fields.gif); background-position: 1px -179px; background-repeat: no-repeat; }

Update: CSS Close Enough Solution: Based on the suggestion from kRON here's the CSS to make the inputs match FF and IE in Vista which makes a good choice if you decide to give up on pure defaults and enforce one style. I have modified his slightly and added the "blueish" effects:

CSS:

input[type=text], select, textarea {
    border-top: 1px #acaeb4 solid;
    border-left: 1px #dde1e7 solid;
    border-right: 1px #dde1e7 solid;
    border-bottom: 1px #e3e9ef solid;
    -moz-border-radius: 2px;
    -webkit-border-radius: 2px;
    padding: 2px;
}
input[type=text]:hover, select:hover, textarea:hover, input[type=text]:focus, select:focus, textarea:focus {
    border-top: 1px #5794bf solid;
    border-left: 1px #c5daed solid;
    border-right: 1px #b7d5ea solid;
    border-bottom: 1px #c7e2f1 solid;
}
select { border: 1px; }
A: 

Hey, try this. It's a little hackish but it seems to work for me.

border: 0; border: 1px solid #abadb3;

The 'border:0' will kill the default border on the input, and the following rule will make it look the way you want.

Alex Morales
Sorry I wasn't clear. That would work if I simply wanted it to have a solid border, but what I want it for it to look the way it does in the browsers when there is no style. I want the native, default border style. For example, see the style in Firefox: http://www.screencast.com/users/jadeonly/folders/Snagit/media/d70dd690-9273-45fb-9893-14b38202ddcc
Jade Ohlhauser
+1  A: 
varl
That makes it look closer, but not the same. And it's not just the static look. The default input style in Firefox gets a hover and focus effect. In Chrome the focus effect is always applied, even on the changed border we're talking about, because the effect seems to be around the border (outline?) instead of changing the border itself.
Jade Ohlhauser
I do hope that someone comes along with more elegant solutions, because mine are rather crude. I updated my first solution above with another, although it's not really a solution, more of a workaround.
varl
Thanks for the suggestion. While I still hope this stack overflow question leads to complete solution, I can use your suggestion to get closer. Except for IE8. It's the one browser I tested not affected by this bug, but then your idea which makes Chrome and Firefox better, makes IE8 now break and also lose the style and hover effect.
Jade Ohlhauser
The updated solution should not break IE8 since it leaves the inputs completely alone.
varl
It's what I'll do for now. I've implemented it with JS so I can still just have the input with a class in the HTML: $$('input.link').each(function(el) { new Element('span',{'class':'linkIcon'}).setText(' ').injectBefore(el); });If you don't mind, I'd like to leave the question open to see if there is a "pure CSS just on the input" solution out there. Partly because this just frustrates so much i.e. WhyTF does setting a background affect the border?!
Jade Ohlhauser
This has been dealt with before on stack overflow which lead to this link:http://www.456bereastreet.com/lab/styling-form-controls-revisited/text-input-single/Originally posted in: http://stackoverflow.com/questions/880152/input-background-colour-destroys-styling
varl
Here's the article: http://www.456bereastreet.com/archive/200701/styling_form_controls_with_css_revisited/ and the soul crushing quote: "My intention with that article (and its follow-up, Styling even more form controls) was to show that attempting to use CSS to make form controls look similar across browsers and operating systems in an exercise in futility. It simply cannot be done."
varl
+2  A: 

When you change border or background style on text inputs They revert back to the very basic rendering mode. Text inputs that are os-style are usually overlays (like flash is) which are rendered on top of the document.

I do not believe there is a pure CSS fix to your problem. Best thing to do - in my opinion - is to pick a style that you like and emulate it with CSS. So that no matter what browser you're in, the inputs will look the same. You can still have hover effects and the like. OS X style glow effects might be tricky, but I'm sure it is doable.

@Alex Morales: Your solution is redundant. border: 0; is ignored in favor of border: 1px solid #abadb3; and results in unnecessary bytes transferred across the wire.

sholsinger
A: 

@sholsinger

My answer isn't redundant. The border:0 clears the border style on the input. The following style applies the new style to the input. As in cascading style sheets ;)

Alex Morales
+2  A: 

This is the CSS that I use that can provide the default look back:

input, select, textarea {
    border-top: 1px #acaeb4 solid;
    border-left: 1px #dde1e7 solid;
    border-right: 1px #dde1e7 solid;
    border-bottom: 2px #f1f4f7 solid;
    -moz-border-radius: 2px;
    -webkit-border-radius: 2px;
}

You could also apply :active and give the controls that blueish hue once they're selected.

kRON
Useful, thanks!
Daniel Fone
That looks really good in IE, Firefox, and Safari on Vista. Chrome and Opera have different defaults as do some other operating systems.But, your suggestion is the one I'll use if I decide to give up and just enforce a style. So while this doesn't technically answer the question, thanks a lot for sharing.
Jade Ohlhauser
np ;)! If you can parse the user-agent param from the request header, you could conditionally reference CSS that contain browser-specific declarations. Each would have it's own `input, select, textarea {}` where you could emulate the *deafult* look. Doing things right often takes a lot of work :)!
kRON