16

Developing an application where I must highlight characters inputted in an input[type=text]. Characters can be spaces and tabs too. That is a reason I do not want to give a color to a text, but a background color, so that my users know that there's something written inside an element.

I have got nothing to aid you answering, but the hand-made picture of what I want to achieve and a jsfiddle link where I will try along with people who don't mind helping me achieving my goal for free.

What I want to achieve with my question

Hashem Qolami
  • 97,268
  • 26
  • 150
  • 164
Davit
  • 1,394
  • 5
  • 21
  • 47

2 Answers2

30

::first-line pseudo-element (for Webkit browsers)

One option is using ::first-line pseudo-element, as follows:

input[type="text"]::first-line {
    background-color: gold;
}

WORKING DEMO.

I should note that this only works on Webkit web browsers including Safari, Chrome and Opera15+.

According to CSS level 2 spec:

5.12.1 The :first-line pseudo-element

The :first-line pseudo-element can only be attached to a block container element.

However CSS level 3 spec states that:

7.1. The ::first-line pseudo-element

In CSS, the ::first-line pseudo-element can only have an effect when attached to a block-like container such as a block box, inline-block, table-caption, or table-cell.

Hence, based on CSS level 3 spec ::first-line is applicable to inline-block elements. Since Webkit based web browsers display <input> element as inline-block we can use the pseudo-element on inputs in order to select the text.

Whereas some other web browsers (including Firefox) display input as inline and this is why ::first-line has no effect on input elements on such web browsers.

I've made up a tiny test to show the computed style of display property of input element.

Multiple text-shadow values

This doesn't seem to be a real solution, but we can fake the effect by using multiple text-shadow values as follows:

input[type="text"] {
    text-shadow: 0 0 50px gold,
                 0 0 50px gold,
                 0 0 50px gold,
                 0 0 50px gold,
                 0 0 50px gold,
                 0 0 50px gold,
                 0 0 50px gold,
                 0 0 50px gold,
                 0 0 50px gold,
                 0 0 50px gold;
}

WORKING DEMO (Or something fancier)

Content Editable <div> & ::first-line

As an option, you can use contenteditable attribute for a <div> element, and use appearance property to apply the useragent default stylesheet of text inputs to the <div> element, as follows:

<div contenteditable="true" class="text-input form-control">
    text with background-color
</div>

Then, you can use :first-line pseudo-element to assign the background color:

.text-input {
    display: inline-block;
    width: auto;
    min-width: 200px;

    -webkit-appearance: textfield;
    -moz-appearance: textfield;
    appearance: textfield;

    white-space: nowrap;
}

.text-input:first-line {
    background-color: gold;
}

WORKING DEMO

Disadvantages:

  • You have to disable the Enter key for the <div> element and/or submit the form by pressing that via JavaScript.

jQuery version:

$('.text-input').keypress(function(e){
    if (event.keyCode == 10 || event.keyCode == 13) {
        e.preventDefault();
        // Submit the form
    }
});

UPDATED DEMO.

Redesign entirely by JavaScript

Finally, you can use JavaScript to create/adjust the colored box beneath the input element.

In this approach, we wrap the <input> by a relative positioned wrapper having a zero-width colored child and then we remove the input from document normal flow by using absolute positioning and put that over the colored box.

As we start typing in the text input, the same content will be inserted to the nether colored box, So the width of the colored box matches the width of the text.

And one more thing:

The input shouldn't have any border, background or even default appearance. And it's better to wrap the colored box itself by another element, and apply the proper styles to that element to make it look like a real input element.

That's it!

Here is a sort of implementation of the above logic using jQuery highlightTextarea plugin. It may not look good for the <input> elements as it's designed for <textarea>s.

Community
  • 1
  • 1
Hashem Qolami
  • 97,268
  • 26
  • 150
  • 164
  • Great, I'm amazed. Do you mind telling how can it can work with Mozilla too? (FF >= 27.x) – Davit Mar 02 '14 at 18:07
  • I'm testing your answer using OSX and Firefox latest, it's not exactly working. I'll accept your answer but maybe you could confirm that it's my software issue, and it's fine with other systems? – Davit Mar 02 '14 at 18:16
  • @Davit Sorry for the late response. It seems this only work on Webkit based web browsers as `` is an empty HTML tag. However, there are Javascript solutions to achieve the same effect. I'll keep looking for the reason and I'll update the answer. – Hashem Qolami Mar 02 '14 at 18:21
  • Okay thanks. I'll accept your answer now, and if you could find something then please update your answer. Otherwise, I'm very thankful to you! – Davit Mar 02 '14 at 18:22
  • @Davit Just updated the answer; Added more details and alternatives. – Hashem Qolami Mar 02 '14 at 20:35
  • 1
    thank you a lot. I'll see if I can award a bounty to your answer. That's amazing what you did. I can't start bounty on SO today, but ASA it's available I'll check what I can do. – Davit Mar 03 '14 at 10:10
  • @Davit Don't mention it :) If you needed a hand (e.g. for implementing the JavaScript solution), just let me know. – Hashem Qolami Mar 03 '14 at 10:21
  • 1
    +1 Personally, I like the `text-shadow` work around, and it does work (and looks pretty good) on Firefox. Not quite so good on IE. – ScottS Mar 04 '14 at 20:48
1
  • For selecting the content of an input (with highlight), use: el.select().
  • For css manual highlight, see @HashemQolami answer.
yaya
  • 7,675
  • 1
  • 39
  • 38