arendjr
arendjr

Reputation: 719

Mismatch in text width between div and textarea

I'm trying to create a textarea control in which it is possible to mention other users. The feature is pretty much similar to the one found in Facebook, and the implementation is similar too. When the user types an "@", a dropdown is presented from which a user can be selected which is then displayed with a highlight in the textarea. To be able to selectively render highlights in the textarea, I'm using an overlay div with the same text, but with span tags to create highlights.

The overlay has the same width, the same font and font-size, the same letter-spacing, same line-height, etc., to make sure all highlights will align properly with the text in the textarea. All the text in the overlay div, except for the highlights themselves, is transparent to avoid artifacts of rendering anti-aliased text over text.

This all works pretty well, except that when there is a mention highlight, the text in the highlight is somehow just slightly less wide than the text below it in the textarea, which causes a very slight mismatch. Worse, this small mismatch accumulates when there are multiple highlights, and it can sometimes cause a line to wrap in the textarea but not in the div, after which the whole illusion just falls apart.

I have verified that all text rendering options are exactly the same for the text in the textarea and in the overlay and in the highlights. All have equal font, font-size, letter-spacing, line-height, there's no margin, border or padding on the highlights, etc.. I have also looked in the WebKit Inspector to see if I might have missed any properties that could still affect text rendering, but couldn't find any. Simply put, I can't explain where this slight rendering difference comes from.

Please note that the rendering difference does not occur as long as the overlay doesn't contain any highlights.

I have also tried only rendering the overlay and not rendering the textarea at all (instead of having the overlay be transparent outside of the highlights), but this has the nasty side-effect that I won't see any cursor anymore.

Is there some CSS property that I still might have overlooked or is there some other reason why breaking the text into multiple spans would cause the total width of the text to slightly differ from an uninterrupted text node? Any suggestions would be greatly appreciated!

Update: For any others who might run into this problem, it's illustrated in the following jsfiddle: http://jsfiddle.net/brt8w85z/5/

<style type="text/css">
.parent {
    text-rendering: optimizeLegibility;
    position: relative;
}

textarea {
    border: 0;
    color: #000;
    resize: none;
}

.overlay {
    color: transparent;
    pointer-events: none;
}

textarea,.overlay {
    font-family: Helvetica,sans-serif;
    font-size: 12px;
    left: 10px;
    letter-spacing: normal;
    margin: 0;
    padding: 0;
    position: absolute;
    top: 10px;
    width: 200px;
}

.highlight {
    background-color: #00f;
    color: #fff;
}
</style>
<div class="parent">
    <textarea>Tom Kleijn, Mark van der Velden and Arend van Beelen</textarea>

    <div class="overlay"><span class="highlight">Tom Kleijn</span>, <span class="highlight">Mark van der Velden</span> and <span class="highlight">Arend van Beelen</span></div>
</div>

The problem can be fixed by adding "text-rendering: geometricPrecision" to the "textarea,.overlay" rule.

Upvotes: 0

Views: 452

Answers (1)

arendjr
arendjr

Reputation: 719

Seems I have found the solution myself: On the body there's a definition of "text-rendering: optimizeLegibility". Setting this back to "text-rendering: geometricPrecision" on the textarea fixed the problem. The reason this was not obvious before was because the WebKit Inspector did not show the inherited text-rendering on the textarea, even though it does so for (most?) other inherited properties.

Upvotes: 2

Related Questions