I am posting my code using canvas here on SO but I am also creating a working sample on JSFiddle here.
<!DOCTYPE html>
<html>
<head>
<title>StackOverflow test bed</title>
<script type="text/javascript">
function drawGrid() {
var cnv = document.getElementById("cnv");
var gridOptions = {
minorLines: {
separation: 5,
color: '#00FF00'
},
majorLines: {
separation: 30,
color: '#FF0000'
}
};
drawGridLines(cnv, gridOptions.minorLines);
drawGridLines(cnv, gridOptions.majorLines);
return;
}
function drawGridLines(cnv, lineOptions) {
var iWidth = cnv.width;
var iHeight = cnv.height;
var ctx = cnv.getContext('2d');
ctx.strokeStyle = lineOptions.color;
ctx.strokeWidth = 1;
ctx.beginPath();
var iCount = null;
var i = null;
var x = null;
var y = null;
iCount = Math.floor(iWidth / lineOptions.separation);
for (i = 1; i <= iCount; i++) {
x = (i * lineOptions.separation);
ctx.moveTo(x, 0);
ctx.lineTo(x, iHeight);
ctx.stroke();
}
iCount = Math.floor(iHeight / lineOptions.separation);
for (i = 1; i <= iCount; i++) {
y = (i * lineOptions.separation);
ctx.moveTo(0, y);
ctx.lineTo(iWidth, y);
ctx.stroke();
}
ctx.closePath();
return;
}
</script>
</head>
<body onload="drawGrid()">
<canvas id="cnv" width="500" height="500"></canvas>
</body>
</html>
Using the canvas approach you can make the grid size dynamic by changing the separation parameter.
However, if your grid size is going to be static I feel that maybe you don't need to draw the grid. Just for the sake of displaying a grid to the user you could use CSS to repeat a background image as demonstrated in the fiddle here. That will also be good on page performance.
it's very easy to do using canvas, that's what I recommend. I'm responding quickly on mobile here, but you should get the idea even if the psuedocode below isn't EXACTLY right:
you'll have a loop something like:
// "Ctx" is your canvas context
// "Width," "Height," and other vars that start with a capital letter are set according
// to your canvas size or preference
var i;
for (i=0; i < Height; i += GridSize) {
ctx.lineWidth(1.0+((i%10)==0));
ctx.moveTo(0,i);
ctx.lineTo(Width,i);
ctx.stroke();
}
for (i=0; i < Width; i += GridSize) {
ctx.lineWidth(1.0+((i%10)==0));
ctx.moveTo(i,0);
ctx.lineTo(i,Height);
ctx.stroke();
}
Note that for this particular grid you have to use widths and heights of the form n x 80 + 1 (with n being any integer) if you want the grid to start and end with a thick stroke.
Building on Ben Crowhurst's example, you can do this with repeating-linear-gradient too. Here's my solution using css. I used variables to give you an idea of what does what.
Another way is to let JavaScript create the SVG for you. I'm about to show how to create a smaller, 4x4 grid composed of SVG rectangles so you can see the grid's details:
First, you add an empty SVG representing the grid to your HTML and then fill that grid with SVG rectangles in JavaScript:
let grid = document.getElementById("svg_grid");
let startX = 5;
let startY = 5;
let rectWidth = 60;
let rectHeight = 60;
let nrOfColumns = 4;
let nrOfRows = 4;
let horizontalPadding = 5;
let verticalPadding = 5;
let strokeWidth = 2;
let rectX = startX;
for (let colIdx = 0; colIdx < nrOfColumns; colIdx++) {
let rectY = startY;
for (let rowIdx = 0; rowIdx < nrOfRows; rowIdx++) {
let rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
rect.setAttribute("x", rectX);
rect.setAttribute("y", rectY);
rect.setAttribute("width", rectWidth );
rect.setAttribute("height", rectHeight);
rect.setAttribute("style", "fill:blue;stroke:green;stroke-width:" +
strokeWidth +";fill-opacity:0.1;stroke-opacity:0.6");
// Rounded corners
rect.setAttribute("rx", "3%");
rect.setAttribute("ry", "3%");
grid.appendChild(rect);
rectY += rectHeight + verticalPadding;
}
rectX += rectWidth + horizontalPadding;
}
// Resize the grid to fit its containing rectangles
let svgWidth = startX + nrOfColumns * (horizontalPadding + rectWidth + strokeWidth);
let svgHeight = startY + nrOfRows * (verticalPadding + rectHeight + strokeWidth);
grid.setAttribute("width", svgWidth);
grid.setAttribute("height", svgHeight);
rowCols has 15 values because we do not need to render the last block because it automatically gets created if you have defined the width of the row. In my case we have cols.length * 100