JSFiddle - React, Tailwind, and code Playground

HTML

<div>
    <span class="input-mask">999-99-9999</span><input maxlength="10" type="text" value="" />
</div>

CSS

input { margin:0; outline: none; border-radius: 4px; height:16px; border: 2px solid black; padding: 4px; font-weight:bold; font-size: 14px; width:81px; text-align: left; font-family: Consolas, Monaco, monospace; }
.mask-literal { color: black; }

JavaScript

var spn = document.getElementsByTagName("span")[0],
    inp = document.getElementsByTagName("input")[0],
    cs  = window.getComputedStyle(inp, null),
    i   = cs.length,
    txt = "textContent" in document.body ? "textContent" : "innerText",
    ignore
while (i--) {
    var s = cs[i];
    
    // Copy all styles from <input> to <span> and <button>
    if (s && s != "cssText" && s.slice(0,6) != "column" && s != "-ms-wrap-margin")
        spn.style.setProperty(s, cs.getPropertyValue(s), null);
}

// wrap each character in <span class="input-mask"> with another <span>
spn.innerHTML = spn.innerHTML.replace(/./g, "<span>$&</span>")
                   .replace(/<span>\/<\/span>/g, '<span class="mask-literal">/</span>');

// Presto's & Gecko's <input> elements are `display:inline`
spn.style.display = 'inline-block';

spn.style.position = 'absolute';
spn.style.borderColor = "transparent";
spn.style.backgroundColor = "transparent";
spn.style.color = "lightgray";
spn.style["-webkit-text-fill-color"] = null;
spn.style.pointerEvents = "none";
spn.contentEditable = true;
spn.onfocus = function () {
    setCaret(inp, getCaret(spn));
}
inp.onkeypress = function() {
    var evt = arguments[0] || window.event,
        chr = String.fromCharCode(evt.which || evt.keyCode),
        pos = getCaret(inp);

    if (!evt.which && !evt.keyCode)
        return;
    
    if (pos !== 2 && pos !== 5) {
        if (isNaN(chr))
            return false;
        else if (pos === 1 || pos === 4) {
            window.setTimeout(function () {
                insertTextWithoutDestroyingUndo(inp, "/");
            }, 0);
        }
    }
    else
        return chr === "/";
}
inp.onkeydown = function () {
    var pos,
        evt = arguments[0] || window.event,
        key = evt.which || evt.keyCode,
        len = inp.value.length;

    /* fix for IE */
    ignorePC = true;
    pos = getCaret(inp);
    ignorePC = false;
    
    if ((key === 46 && pos != len -1) || key === 8 && pos != len)
       ...