Is there a way to style part of an input field's value?

Your suspicions are correct: styles will apply to the whole input only.

As styles can apply to the entirety of an element only, a solution will require at least one element per required colour.

Consider the division of the input field with respect to the point at which the user is making changes. There are three sections of the input:

  • that before the point at which changes are being applied
  • that after the point at which changes are being applied
  • that at the point the changes are being applied

You cannot achieve this with a single input element. And as the point at which the changes are being applied can change, the portions of the 'input' wrapped by the three elements will also change. JavaScript is required for a solution.

You should initially include a regular input element and forgo any of the required colouring. Use JavaScript to replace the input with a suitable container element. This can be styled to mimic an input element.

As changes occur, use JavaScript to identify the above-mentioned three divisions. Wrap them in suitable elements (spans would be ideal) and colour as needed.

Consider the following starting point for the generated replacement markup:

<div class="input">
  <span class="nonEdited before">foo</span>
  <span class="edited">fizz</span>
  <span class="nonEdited after">bar</span>
</div>

Use click, keydown and keyup events to figure out the three divisions for the input and to apply wrap the three portions of the faked input as required.


As others have said, you can't do this with styles and static markup.

You could probably do it with a Flash-based form.

But, if I had to this, I'd use jQuery to overlay divs, with the colorized text, atop the <input>.

Algorithm:

  1. Use a normal <input> with whatever default styles are desired. The contents of this input will never change except by user action.

  2. jQuery monitors that <input>. When it detects trigger word(s), it adds a <div> after the input and fills it with the trigger word(s) -- styled as desired. Probably one <div> per word or phrase is best.

  3. jQuery then positions the new <div>, absolutely, directly over the trigger word(s).
    Getting the trigger word(s) offset within the <input> might not even be necessary, because the previous words could also be in the overlay <div> -- either styled defaultly or with visibility: hidden.
    But, if only the trigger word(s) are desired in the overlay, then using a fixed-width font, like Courier, will help with the sub-positioning.

  4. Take care that the overlay does not interfere with the user trying to mouse or key to certain parts of the <input>. IE, probably don't want to cover any more of the <input> than necessary, and set a click() handler to relay focus.


Alternate, user friendly and simpler approach:

Rather than try to do funky, non-user-expected things to the input, take a page from Jakob Nielsen and from sites like StackOverflow.

Just have a plain ol' <input>, but underneath it, show the formatted text as it comes in.


You can achieve this with (a lot of effort and) a div with the contentEditable attribute present. This is how most web-based WYSIWYG editors achieve rich formatting of inputs. See here for more info: http://ajaxian.com/archives/on-browser-wysiwyg