JSFiddle - React, Tailwind, and code Playground

by Graham Dixon

HTML

<div class="container">

</div>

CSS

.container {
              outline: none;
            -webkit-user-select: none !important;
            -moz-user-select: none !important;
            -ms-user-select: none !important;
            user-select: none !important;
            cursor: text;
    color: transparent;
    text-shadow: 0 0 0 black;
}
.line {
  display: inline-block;
}

span>.blinking-cursor:first-child {
  padding-left: 0px;
}

span.blinking-cursor {
  font-weight: bold;
  font-size: auto;
  color: #2E3D48;
  text-shadow: 0 0 0 transparent;
  -webkit-animation: 1s blink step-end infinite;
  -moz-animation: 1s blink step-end infinite;
  -ms-animation: 1s blink step-end infinite;
  -o-animation: 1s blink step-end infinite;
  animation: 1s blink step-end infinite;
  padding-left: 0px;
  width: 5px;
  display: inline;
  max-width: 6px;
  overflow: hidden;
  padding: 0px;
  margin: 0px;
  margin-left: -1px;
  margin-right: -4.4px;
  font-size: 100%;
  margin-top: 0px;
}

@keyframes "blink" {
  from,
  to {
    color: black;
  }
  50% {
    color: transparent;
  }
}

@-moz-keyframes blink {
  from,
  to {
    color: black;
  }
  50% {
    color: transparent;
  }
}

@-webkit-keyframes "blink" {
  from,
  to {
    color: black;
  }
  50% {
    color: transparent;
  }
}

@-ms-keyframes "blink" {
  from,
  to {
    color: black;
  }
  50% {
    color: transparent;
  }
}

@-o-keyframes "blink" {
  from,
  to {
    color: black;
  }
  50% {
    color: transparent;
  }
}

JavaScript

// get a range from the current cursor position
const createRange = function(e, editor, scrollX, scrollY) {
    // different environments use different methods to get to the same(ish) values
    var range, textNode, offset, isIe;
    // restore scroll position on the editor (focus/blur can knock the scroll pos back to 0)
    editor.scrollLeft = scrollX;
    editor.scrollTop = scrollY;
    // switch to get the correct range from point method
    if (document.caretPositionFromPoint) {
        // standard uses caretPositionFromPoint
        range = document.caretPositionFromPoint(e.pageX, e.pageY);
        textNode = range && range.offsetNode;
        offset = range && range.offset;
    } else if (document.caretRangeFromPoint) {
        // webkit uses caretRangeFromPoint
        range = document.caretRangeFromPoint(e.pageX, e.pageY);
        textNode = range && range.startContainer;
        offset = range && range.startOffset;
    } else if (document.body.createTextRange) {
        // mark as IE type (returns textNode's parent as textNode)
        isIe = true;
        // random id to mark position
        var posId = ("-%%%-"+ ("" + Math.random()).slice(6) +"-%%%-");
        // create a range and align with current cursor position
        textNode = document.body.createTextRange();
        console.dir(textNode);
        // textNode.offsetTop = e.pageY;
        // textNode.offsetLeft = e.pageX;
        // picks up element (textElement at position)
        textNode.moveToPoint(e.pageX, e.pageY);
        // place id into the node so we can discover the offset
        textNode.text = posId;
        // get the node the text is contained in
        textNode = textNode.parentElement();
        // position of the id marker in the textContent
        offset = textNode.textContent.indexOf(posId);
        // remove id marker
        textNode.textContent = textNode.textContent.replace(posId, "");
        // set the range to the textNodes.textContent container span
        range...