A: 

I have done this a few times. I have the background image inside a div and use css to position the input field accordingly.

Have a peek at the following site I created that used this technique and use the code: http://www.ukoffer.com/ (Right hand side Newsletter)

Keith Donegan
+3  A: 

You don't need the div element, you can assign a background to the input directly.

Edit: Here is the working code. I tested it, but you'll have to adjust it for your needs. As far as I can tell, everything here is needed.

input {
    background: #FFF url(test.png) no-repeat bottom right;
    width: 120px;
    height: 20px;
    line-height:20px;
    padding:0;
    text-indent:3px;
    margin:0;
    border: none;
    overflow:hidden;
}

Edit2: I'm not quite sure why I'm getting downvoted, but this method should work unless you need an image bigger than the input element itself. In that case, you should use the extra div element. However, if the image is the same size as the input, there is no need for the extra markup.

Edit3: Ok, after bobince pointed out a problem, I'm getting a little closer. This will be work in IE6&7 and it's close in FF, but I'm still working on that part.

input {
    background: #FFF url(test.png) no-repeat 0px 0px;
    background-attachment:fixed;
    width: 120px;
    height: 20px;
    line-height:20px;
    padding:0px;
    text-indent:3px;
    margin:0;
    border: none;
}
body>input {
    background-position:13px 16px;
}

Edit4: Ok, I think I got it this time, but it requires use of a CSS3 selector, so it won't validate as CSS 2.1.

input { 
    background: #FFF url(test.png) no-repeat 0px 0px;
    background-attachment:fixed;
    width: 120px;
    height: 20px;
    line-height:20px;
    padding:0px;
    text-indent:3px;
    margin:0;
    border: none;
}
body>input { 
    background-position:13px 16px;
}
body>input:enabled { 
    background-position:9px 10px;
}

body>input will target everything except for IE6, body>input:enabled will target any form elements that aren't disabled for all browsers except for IE 6, 7, & 8. However, because :enabled is a CSS3 selector, it doesn't validate as CSS2.1. I wasn't able to find an appropriate CSS2 selector that would allow me to separate IE7 from the other browsers. If not validating (yet, until the validator switches to CSS3) is a problem for you, then I think your only option is the extra div element.

VirtuosiMedia
Try moving the cursor left again after typing a load of characters. The ‘overflow: none’ isn't doing anything, the only real change you've made is the right-alignment, which swaps bad rendering in the case when the cursor is on the right of a long bunch of text for bad rendering when on the left.
bobince
Ah, I see now. Let me look into that. I didn't catch the left side problem.
VirtuosiMedia
background-attachment: fixed; makes IE6 work properly, but moves the background image in FF and IE7.
VirtuosiMedia
Yes, ‘fixed’ positions a background image relative to the viewport (IE6 used to get this wrong). You *could* compensate with background-position if you knew the exact position of the input, but that's rather ugly and precludes liquid layout.
bobince
Having a fixed width input also precludes a liquid layout, but I think that's what he's looking for. I'm getting closer with using child selectors. I can now get it to render correctly in IE 6 and 7, but it's still a little off in FF.
VirtuosiMedia
+1  A: 

Have you evaluated using background image like this:

<style type="text/css"> 
  input{ 
  background-color: #AAAAAA; 
  background-image: url('http://mysite.com/input.gif'); 
  border: 0px; 
  font-family: verdana; 
  font-size: 10px; 
  color: #0000FF; 
}

Rutesh Makhijani
It doesn't work as good in my opinion. The background image is contained in the actual input field "box", thus you would need to make the input field bigger to accommodate this.
Keith Donegan
In the example he gave, all he has done to the input is put rounded corners and an inner shadow. You don't need to make it bigger to do that.
VirtuosiMedia
I have tried this, but doesn't work in IE :(
Darryl Hein
? This suffers from the same problem the OP's code has, of the background slipping as the input scrolls.
bobince
+4  A: 

I'd do it this way:

<style type="text/css">
div.custom {
    background:url(/images/input-bkg-w173.gif) no-repeat;
    padding:8px 5px 4px 5px;
}
div.custom input {
    background-color: #fff;
    border:none;
    font-size:10px;
}
</style>
<div class="custom"><input type="text" class="custom" size="12" /></div>

You just have to adjust the padding values so everything fits correctly. It is - in my eyes- definitely the best solution since in any other case you're working with a whole input field. And the whole input field is - by definition - a box where users can enter text.

If you can rely on JavaScript you could wrap such div-Elements around your input fields programatically.

Edit: With jQuery you could do it this way:

$( 'input.custom' ).wrap( '<div class="custom"></div>' );

CSS:

div.custom {
    background:url(/images/input-bkg-w173.gif) no-repeat;
    padding:8px 5px 4px 5px;
}
input.custom {
    background-color: #fff;
    border:none;
    font-size:10px;
}

And your HTML:

<input class="custom" ... />
okoman
This is what I have been doing now...I was hoping for a better way since it's every text field on the site :(
Darryl Hein
Oh, I'd better read questions twice. Nevertheless added "It's the best solution" ;-)
okoman
+1. The script-assisted version is nice for keeping your markup simple. Also you can use two nested divs with ‘slding doors’ left/right backgrounds to get a variable-size input rather than having to fix the width.
bobince
A: 

AFAIK, the background scrolling problem can be solved either in Firefox and friends, OR Internet Exploder; but not make everyone happy at once.

I would normally have said to style the input directly, but now that I think of it that div example doesn't sound too bad and should take care of your background image scrolling problem.

In that case you'd set a div as position:relative, and put the input inside it with proper padding and width (or 100% width if padding is 0), background transparent, and put an image on the div.

faB
A: 

okoman has gotten the CSS aspect correct. May I suggest using a <label> to improve the semantic structure of the markup?

<label id="for-field-name" for="field-name">
    <span class="label-title">Field Name <em class="required">*</em></span>
    <input id="field-name" name="field-name" type="text" class="text-input" />
</label>

<style type="text/css">
    label, span.label-title { display: block; }
</style>

Not only is this more accessible, but it provides numerous hooks that you can use for any type of DOM manipulation, validation or field-specific styling in the future.

Edit: If you don't want the label title displayed for some reason, you can give it a class of 'accessibility' and set the class to display: none; in the CSS. This will allow screen readers to understand the input but hide it from regular users.

Mark Hurd