/*
utility function to create a new DOM element of type (`t`),
assign various attributes (`a`) and append as a child of `p`
*/
const create=function(t,a,p){
let el = ( typeof( t )=='undefined' || t==null ) ? document.createElement( 'div' ) : document.createElement( t );
let _arr=['innerHTML','innerText','html','text'];
for( let x in a ) if( a.hasOwnProperty( x ) && !~_arr.indexOf( x ) ) el.setAttribute( x, a[ x ] );
if( a.hasOwnProperty('innerHTML') || a.hasOwnProperty('html') ) el.innerHTML=a.innerHTML || a.html;
if( a.hasOwnProperty('innerText') || a.hasOwnProperty('text') ) el.innerText=a.innerText || a.text;
if( p!=null ) typeof( p )=='object' ? p.appendChild( el ) : document.getElementById( p ).appendChild( el );
return el;
};
/*
shorthand utility to find a cell by querying
the data attributes for row and column
*/
const getcell=function(r,c){
return document.querySelector('td[ data-row="'+r+'" ][ data-col="'+r+'" ]');
};
let gs=10; // grid size
let o={}; // empty options
let tbl=create('table',o,document.getElementById('grid-container'));
// manipulate the CSS variable which helps govener grid display
let root=document.documentElement;
root.style.setProperty( '--size', gs );
// construct rows and columns
for( let a=1; a <= gs; a++ ){
let row=create('tr',o,tbl);
for( let b=1; b <= gs; b++ ){
create('td',{'data-row':a,'data-col':b},row);
}
}
// manipulating individual cells
getcell(3,3).style.background='lime';
getcell(5,5).classList.add('banana');
:root{--size:10;}
table{ width:100%; }
td{width:calc( calc( 100% / var( --size ) ) - 4px );height:calc( calc( 100vh / var( --size ) ) - 4px );border:1px solid red;margin:2px; }
.banana{background:yellow}
<div id='grid-container'></div>