JSFiddle - React, Tailwind, and code Playground
by Darby Rathbone
HTML
<div class='editparent'>
<div class='edit' contentEditable='true'></div>
<div class='editover' contentEditable='false'></div>
</div>
<span id='caret' class='caret'>│</span>
CSS
*{
padding:0px;
margin:0px;
}
html,body{
position:absolute;
overflow-x:hidden;
top:0px;
bottom:0px;
left:0px;
right:0px;
width:100%;
height:100%;
}
.caret{
color:rgba(50,10,10,.8);
user-select: none;
pointer-events:none;
margin-left:1.5px;
transform:translate(-50%,0%);
top:0px;
left:0px;
width:auto;
height:auto;
position:absolute;
visibility:hidden;
}
.editparent {
margin:2px;
width:100%;
height:100%;
border:solid 1px black;
position:relative;
}
.edit {
user-modify:read-write-plaintext-only;
color:rgba(0,0,0,0);
position:absolute;
width:100%;
height:100%;
top:0px;
left:0px;
right:0px;
bottom:0px;
}
.editover {
user-select: none;
position:absolute;
word-wrap:break-word;
width:100%;
height:100%;
top:0px;
left:0px;
pointer-events:none;
right:0px;
bottom:0px;
}
JavaScript
var edits = document.getElementsByClassName('edit');
function flash(r){
var sel = getSelection();
try{
var c = sel.getRangeAt(0).getClientRects()[0];
}catch(err){console.error( err);}
if(typeof c ==='undefined'){
c= sel.focusNode.getClientRects()[0];
}
if(sel.type ==='Caret')
{ document.getElementById('caret').style.visibility ='visible';
document.getElementById('caret').style.left =c.left+'px';
document.getElementById('caret').style.top =c.top+'px';
}
// ctx.fillRect(c.left,c.top,c.width,c.height);
clearTimeout(clearing);
clearing = setTimeout(clear,500);
}
var flashing,
clearing;
edits[0].addEventListener('blur',function(){
clearInterval(flashing);
clear();
});
edits[0].addEventListener('focus',function(){
flashing = setInterval(flash,1000);
});
var clear = function clear(e){
document.getElementById('caret').style.visibility = 'hidden';
};
addEventListener('mouseup',flash);
addEventListener('keyup',flash);
addEventListener('input', function (e) {
if (e.target.classList.contains('edit')) {
document.querySelector('.editover').innerHTML = "";
document.querySelector('.editover').innerHTML = e.target.innerHTML;
flash();
}
});