A way to count columns in a responsive grid

I think the easiest way without brute force is to consider a simple division. You can easily find the width of the container and each column is defined by minmax(300px,1fr) and we know the gap. Using all these information the calculation should be done like below:

If we will have N columns then we will have N-1 gaps. We also know that W should at least be 300px and cannot be more than a value (we will call Wmax).

Let's suppose the gap is equal to 10px.

If N=2 and each column is equal to 300px we will have the container width equal to 300px*2 + 10px*1 = 610px.

If N=3 and each column is equal to 300px we will have 300px*3 + 10px*2=920px.

Now it's clear that if the container width is between 610px and 920px we will have 2 columns because there is no space to hold 3 columns but enough space to hold 2 columns that we expand to fill the remaining space (using 1fr) so Wmax in this case is (920px - 10px)/2 = 455px. In other words, the width will vary from 300px to 455px when having 2 columns.

So if we take the formula 300px*N + 10px*(N-1) = Wc with Wc our container width you will see that N is equal to 2 when Wc=610px and 3 when Wc=920px and between we will have a result in [2,3] so we simply round the value to the smallest one (2 in this case) and we will have our column number.

Here is a basic example:

var gap = 10;
var minW = 200;

var Wc = document.querySelector('.grid').offsetWidth;
var N = Math.floor((Wc+gap)/(minW+gap));
console.log(N);


window.addEventListener('resize', function(event){
   Wc = document.querySelector('.grid').offsetWidth;
   N = Math.floor((Wc+gap)/(minW+gap));
   console.log(N);
});
.grid {
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(200px,1fr));
  grid-gap:10px;
}
span {
  min-height:50px;
  background:red;
}
<div class="grid">
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
</div>

In case you don't know the value of gap and min-width you can consider getComputedStyle() to get the different values. In this case, the N should already be an Integer because grid-template-columns will give us the computed width of each column (in practice, we will still have some fraction due to rounding ).

var grid = document.querySelector('.grid');

var gap = parseFloat(window.getComputedStyle(grid,null).getPropertyValue("column-gap"));
var minW = parseFloat(window.getComputedStyle(grid,null).getPropertyValue("grid-template-columns"));

var Wc = document.querySelector('.grid').offsetWidth;
var N = (Wc+gap)/(minW+gap);
console.log(N);


window.addEventListener('resize', function(event){
   Wc = document.querySelector('.grid').offsetWidth;minW = parseFloat(window.getComputedStyle(grid,null).getPropertyValue("grid-template-columns"))
   N = (Wc+gap)/(minW+gap);
   console.log(N);
});
.grid {
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(200px,1fr));
  grid-gap:10px;
}
span {
  min-height:50px;
  background:red;
}
<div class="grid">
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
</div>

One way to get the number of rows/columns of a css grid is by using the grid-template-rows or grid-template-columns from the computed style of the grid window.getComputedStyle(grid).

The returned values are always transformed to separated pixel values (e.g. 20px 20px 50px), where each value represents the size of the respective column/row. All that's left to do is splitting up the string into an array and counting the number of values.

const gridComputedStyle = window.getComputedStyle(grid);

// get number of grid rows
const gridRowCount = gridComputedStyle.getPropertyValue("grid-template-rows").split(" ").length;

// get number of grid columns
const gridColumnCount = gridComputedStyle.getPropertyValue("grid-template-columns").split(" ").length;

console.log(gridRowCount, gridColumnCount);

Here is the full snippet (Codepen):

function getGridData () {
    // calc computed style
  const gridComputedStyle = window.getComputedStyle(grid);
  
  return {
    // get number of grid rows
    gridRowCount: gridComputedStyle.getPropertyValue("grid-template-rows").split(" ").length,
    // get number of grid columns
    gridColumnCount: gridComputedStyle.getPropertyValue("grid-template-columns").split(" ").length,
    // get grid row sizes
    gridRowSizes: gridComputedStyle.getPropertyValue("grid-template-rows").split(" ").map(parseFloat),
    // get grid column sizes
    gridColumnSizes: gridComputedStyle.getPropertyValue("grid-template-columns").split(" ").map(parseFloat)
  }
}

window.addEventListener("DOMContentLoaded", outputGridData);
window.addEventListener("resize", outputGridData);

function outputGridData () {
  const gridData = getGridData();
  output.textContent = `
    Rows: ${gridData.gridRowCount}
    Columns: ${gridData.gridColumnCount}
    Rows sizes: ${gridData.gridRowSizes}
    Column sizes: ${gridData.gridColumnSizes}
  `;
}
#grid {
  display: grid;
  grid-gap: 20px;
  grid-template-columns: repeat(auto-fill, 200px);
}


#output {
  white-space: pre-wrap;
}

.A, .B, .C {
  font-family: Arial;
  font-weight: 600;
  font-size: 2rem;
  border-radius: 50% 50%;
  width: 80px;
  height: 80px;
  text-align: center;
  line-height: 80px;
  box-shadow: -3px 5px 20px -3px #AAA;
  border: solid 10px #fff;
  color: #fff;
}

.A {
  background: #ffc300;
}

.B {
  background: #c70039;
}
.C {
  background: #581845;
}
<div id="output"></div>
<div id="grid">
 <div class="A">A</div>
 <div class="B">B</div>
 <div class="C">C</div>
 <div class="A">A</div>
 <div class="B">B</div>
 <div class="C">C</div>
  <div class="A">A</div>
 <div class="B">B</div>
 <div class="C">C</div>
 <div class="A">A</div>
 <div class="B">B</div>
 <div class="C">C</div>
</div>