JSFiddle - React, Tailwind, and code Playground

HTML

<div id="container">
    <div id="selection"></div>
    
    <div class="selectable">A</div>
    <div class="selectable">B</div>
    <div class="selectable">C</div>
    <div class="selectable">D</div>
    <div class="selectable">E</div>
    <div class="selectable">F</div>
    <div class="selectable">G</div>
    <div class="selectable">H</div>
</div>

CSS

#container {
    margin: 40px;
    padding: 10px;
    border-style: solid;
}

#selection {
    display: none;
    position: absolute;
    background: lightblue;
    border-color: blue;
    border-width: 1px;
    border-style: solid;
    opacity: .5;
}

* {
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    cursor: default;
}

.selectable {
    font-size: 3em;
    background-color: lightgray;
    border-radius: 10px;
    display: inline-block;
    width: 100px;
    line-height: 100px;
    margin: 10px;
    text-align: center;
}

.selectable.mark {
    background-color: yellow;
}

JavaScript

(function() {
    var beginX, beginY; // a posição do vértice fixo
    var active; // se a seleção está ativa (visível)
    var selection = document.getElementById("selection"); // o elemento
    var limit = document.getElementById("container").getBoundingClientRect();
    
    window.onmousedown = function (e) {
        // se o clique foi fora do limite, não continuar
        if (e.clientX > limit.right || e.clientX < limit.left ||
            e.clientY > limit.bottom || e.clientY < limit.top) {
            return;
        }
        
        beginX = e.clientX;
        beginY = e.clientY;
        active = true;
        selection.style.display = "block"; // deixar a div visível
        window.onmousemove(e); // forçar a atualização de posição (função abaixo)
    };
    
    window.onmousemove = function (e) {
        if (active) {
            // cx,cy = a posição do segundo vértice
            // é a posição do mouse limitada pelo limite
            var cx = Math.max(Math.min(e.clientX, limit.right), limit.left);
            var cy = Math.max(Math.min(e.clientY, limit.bottom), limit.top);
            
            // x,y,w,h = o retângulo entre os vértices
            var x = Math.min(beginX, cx);
            var y = Math.min(beginY, cy);
            var w = Math.abs(beginX - cx);
            var h = Math.abs(beginY - cy);
            
            // aplicar a posição e o tamanho
            selection.style.left = x+"px";
            selection.style.top = y+"px";
            selection.style.width = w+"px";
            selection.style.height = h+"px";
            
            // procurar elementos selecionados
            var list = document.getElementsByClassName("selectable");
            for (var i = 0; i < list.length; ++i) {
                var rect = list[i].getBoundingClientRect();
                if (rect.bottom > y && rect.top < y+h &&
                    rect.right > x && rect.left < x+w) {
                    list[i].classList.add("mark");
              ...