JSFiddle - React, Tailwind, and code Playground

HTML

<div id="root"></div>

CSS

#root {
    position: absolute;
    top: 5px;
    bottom: 25px;
    left: 5px;
    right: 25px;
}
.item {
    background: #000;
}
.item.active {
    background: #00F;
}

JavaScript

var navigation =
{
    "active": 0,
    "root": document.getElementById("root"),
    "items": root.getElementsByClassName("item")
};

navigation.move = function (x, y, currentidx, items)
{
    var x0 = items[currentidx].getBoundingClientRect().left;
    var y0 = items[currentidx].getBoundingClientRect().top;

    var best = 0;
    var bestidx = currentidx;

    for (var i = 0; i < items.length; i++)
    {
        var score = (items[i].getBoundingClientRect().left - x0) * x + (items[i].getBoundingClientRect().top - y0) * y;
        if (score > 0 && (score < best || best === 0))
        {
            best = score;
            bestidx = i;
        }
    }
    return bestidx;
}

document.onkeydown = function (evt)
{
    var x = 0, y = 0;
    switch (evt.keyCode)
    {
        case 37: x = -1; break;
        case 38: y = -1; break;
        case 39: x = 1; break;
        case 40: y = 1; break;
        default:
            return;
    }
    navigation.items[navigation.active].classList.remove("active");
    navigation.active = navigation.move(x, y, navigation.active, navigation.items);
    navigation.items[navigation.active].classList.add("active");
};

for (var i = 0; i < 10; i++)
{
    var e = document.createElement("div");
    e.classList.add("item");
    e.style.left = Math.round(Math.random() * 10) * 10 + "%";
    e.style.top = Math.round(Math.random() * 10) * 10 + "%";
    e.style.width = "20px";
    e.style.height = "20px";
    e.style.position = "absolute";
    navigation.root.appendChild(e);

    if (i == navigation.active)
    {
        e.classList.add("active");
    }
}