JSFiddle - React, Tailwind, and code Playground

HTML

<div id="main">
    <h1>Responsive <br/>D3 "Semantic Zooming" grid <br/> with Scales</h1>
    <div class="intgraph" />
</div>

CSS

line.grid {
    fill: none;
    stroke: #9ecae1;
    stroke-width: 1.5px;
}
svg { 
    display:block; /* required for firefox to give valid
    height and width used values for getComputedStyle()
    see https://bugzilla.mozilla.org/show_bug.cgi?id=874919 
    */
    border: solid 1px gray;
    margin:1em;
    height:calc(100% - 2em);
    width: calc(100% - 2em);
}
div{
    height: 100%;
}

JavaScript

var w = 400,
    h = 400,
    gridSpacing = 10,
    vLines, 
    hLines;

/*** Create scales to handle zoom coordinates ***/

var xScale = d3.scale.linear()
               .domain([0,w]);
var yScale = d3.scale.linear()
               .domain([0,h]);
   //ranges will be set later based on the size
   //of the SVG

/*** Configure zoom behaviour ***/
var zoomer = d3.behavior.zoom()
                .scaleExtent([0.1,10])
        //allow 10 times zoom in or out
                .on("zoom", zoom);
        //define the event handler function

function zoom() {
    console.log("zoom", d3.event.translate, d3.event.scale);
    
    //the zoom behaviour has already changed
    //the domain of the x and y scales
    //so we just have to redraw using them
    drawLines();
}
function drawLines() {
    //put positioning in a separate function
    //that can be called at initialization as well
    vLines.attr("x1", function(d){
            return xScale(d);
        })
        .attr("y1", yScale(0) )
        .attr("x2", function(d){
            return xScale(d);
        })
        .attr("y2", yScale(w));
        
    hLines.attr("x1", xScale(0))
        .attr("y1", function(d){
            return yScale(d);
        })
        .attr("x2", xScale(h))
        .attr("y2", function(d){
            return yScale(d);
        });
}


/** Initialize SVG ***/
var svg = d3.select(".intgraph").append("svg:svg")
        .attr("width", w)
        .attr("height", h);
//these will be over-written with CSS

var graph = svg.append("g")
        .attr("class", "graph")
        .call(zoomer); //Attach zoom behaviour.

// Add a transparent background rectangle to catch
// mouse events for the zoom behaviour.
// Note that the rectangle must be inside the element (graph)
// which has the zoom behaviour attached, but must be *outside*
// the group that is going to be transformed.
var rect = graph.append("rect")
    //.style("fill", "none") 
        //make transparent (vs black if commented-out)
   ...