A grid is implemented using the CSS flexbox. Example:
The number of rows in this example is 4 because I fixed the container width for demo purposes. But, in
The only way to move around up and down that arises less unwanted complication to my knowledge is having the count of boxes per row and changing the indexes. The only problem is you need to calculate the boxcount on both window load and resize event.
var boxPerRow=0;
function calculateBoxPerRow(){}
window.onload = calculateBoxPerRow;
window.onresize = calculateBoxPerRow;
Now if you want a very simple way to get the number of boxes in a row without even caring about the size of neither the container nor the boxes, forget margins and paddings, you can check how many boxes are aligned with the first box comparing the offsetTop property.
The HTMLElement.offsetTop read-only property returns the distance of the current element relative to the top of the offsetParent node. [source: developer.mozilla.orgl]
You can implement it like below:
function calculateBoxPerRow(){
var boxes = document.querySelectorAll('.item');
if (boxes.length > 1) {
var i = 0, total = boxes.length, firstOffset = boxes[0].offsetTop;
while (++i < total && boxes[i].offsetTop == firstOffset);
boxPerRow = i;
}
}
Full working example:
(function() {
var boxes = document.querySelectorAll('.item');
var boxPerRow = 0, currentBoxIndex = 0;
function calculateBoxPerRow() {
if (boxes.length > 1) {
var i = 0,
total = boxes.length,
firstOffset = boxes[0].offsetTop;
while (++i < total && boxes[i].offsetTop == firstOffset);
boxPerRow = i;
}
}
window.onload = calculateBoxPerRow;
window.onresize = calculateBoxPerRow;
function focusBox(index) {
if (index >= 0 && index < boxes.length) {
if (currentBoxIndex > -1) boxes[currentBoxIndex].classList.remove('active');
boxes[index].classList.add('active');
currentBoxIndex = index;
}
}
document.body.addEventListener("keyup", function(event) {
switch (event.keyCode) {
case 37:
focusBox(currentBoxIndex - 1);
break;
case 39:
focusBox(currentBoxIndex + 1);
break;
case 38:
focusBox(currentBoxIndex - boxPerRow);
break;
case 40:
focusBox(currentBoxIndex + boxPerRow);
break;
}
});
})();
.grid {
display: flex;
flex-wrap: wrap;
align-content: flex-start;
width: 50%;
height: 200px;
background-color: #ffffd;
padding: 10px 0 0 10px;
}
.item {
width: 50px;
height: 50px;
background-color: red;
margin: 0 10px 10px 0;
}
.active.item {
outline: 5px solid black;
}
[You need to click on this page so that it can recieve the arrow keys]