13

Is there a way to dynamically detect in javascript which grid column and row an element is in, in a CSS grid?

I have a grid that I set up with three breakpoints so that it either has 4, 3, or 2 columns.

What I want to do is if a user clicks in a cell, dynamically overlay a new element in the cell immediately to the right of the cell that was clicked, except if it's in the right-most column, in which case the overlay element will go in the cell to the left.

I know I can use grid-column and grid-row to specify the cell I want to put the new thing in, but in order to be able to use that, I need to know the column and row of the cell that was clicked.

How can I dynamically determine that?

2

1 Answer 1

9

Here. Bind it to a click, but you can have access to this function any way you like. Click on block to see if it is last columns or not. The function accepts current grid-template-columns so it will work on any breakpoint.

//Add click event for any child div of div = grid
$(document).ready(function() {
  $('.grid').on('click', 'div', function(e) {  
    GetGridElementsPosition($(this).index(), $(this)); //Pass in the index of the clicked div
  });
});

function GetGridElementsPosition(index, element) {

  //Get the css attribute grid-template-columns from the css of class grid
  //split on whitespace and get the length, this will give you how many columns
  const colCount = $('.grid').css('grid-template-columns').split(' ').length;
  const colPosition = index % colCount;
  const rowPosition = Math.floor(index / colCount);
  
  /* determine if it is a last column */
  if (colPosition==(colCount-1)) {
    $(element).html('row:'+rowPosition+'. col:'+colPosition+'. Last column');
  } else {
    $(element).html('row:'+rowPosition+'. col:'+colPosition+'. Not last column');
  }

}
.grid {
  display: grid;
  grid-template-columns: repeat( 3, 1fr );
  grid-row-gap: 1em;
  grid-column-gap: 1em;
}

.grid div {
  height: 2em;
  background: blue;
  color: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="grid">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

Sign up to request clarification or add additional context in comments.

4 Comments

Interesting, did this solution helps you?
I ended up not actually having to do what I was describing, I set up the grid items to do a "card flip" kind of animation to keep the additional element in the same grid cell as what was clicked. But the key $('.grid').css('grid-template-columns').split(' ').length was exactly what I was looking for.
This is a good try at an answer, but unfortunately it won't handle anything more complex, like cells that span multiple columns, auto-fit, minmax, etc. AFAIK, there is no convenient way to get the resulting row/col indices that the browser computes for an element.
Unfortunately this only works if all cells are the same size (as V. Rubinetti points out)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.