ИМХО тут будет проблема не в добавке тега с цветом, а в сдвиге каретки при вводе из за изменение контента. Компактного решения я не вижу. С document.getSelection походу практически та же проблема будет.
Обернуть текст в span с цветом можно любым быдлокодингом типа:
function wrapText(str, index, count, color){
return [
str.substr(0,index),
'<span style="color:',
color,
'">',
str.substr(index,count),
'</span>',
str.substr(index+count)
].join("");
}
document.querySelector('div').addEventListener('input', function() {
var s=this.innerText;
this.innerHTML=wrapText(s, s.length-1,1,"red");
}
Но это ничего не решает в случае с редактируемым контентом ...