skip to Main Content

I have this code that displays 2 grids of images (the images are small sections of a larger picture). Currently the grids are displayed at the top and underneath on a page – I want to superimpose them. The second grid images (‘frontlayer’) are partially transparent.

const backlayer = document.querySelector('.backlayer');
const numberOfItems = 16;
for (let row = 0; row < 4; row++) {
  for (let col = 0; col < 4; col++) {
    let cell = document.createElement('div');
    cell.classList.add('cell');
    backlayer.appendChild(cell);
  }
}

const cells = backlayer.querySelectorAll('.cell');
for (let i = 0; i < numberOfItems; i++) {
  var xpos = i % 4;
  var ypos = (i - xpos) / 4;
  var myurl = "url(https://picsum.photos/id/1015/200/200?" + ("X" + xpos) + "/" + ("Y" + ypos) + ")";
  cells[i].style.setProperty('--bg', myurl);
}

// below section for top transparent layer

const frontlayer = document.querySelector('.frontlayer');
const numberOfItems2 = 4;
for (let row = 0; row < 2; row++) {
  for (let col = 0; col < 2; col++) {
    let cell = document.createElement('div');
    cell.classList.add('cell');
    frontlayer.appendChild(cell);
  }
}

const cells2 = frontlayer.querySelectorAll('.cell');
for (let i = 0; i < numberOfItems2; i++) {
  xpos = i % 2;
  ypos = (i - xpos) / 2;
  var myurl2 = "url(https://picsum.photos/id/1016/200/200?" + ("X" + xpos) + "/" + ("Y" + ypos) + ")";
  cells2[i].style.setProperty('--bg', myurl2);
}
.backlayer {
  width: 100vmin;
  height: 100vmin;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(4, 1fr);
  gap: 1v0min;
}

.backlayer>* {
  border: 0 solid;
  background-image: var(--bg);
  background-size: cover;
  background-position center center;
}

.frontlayer {
  width: 100vmin;
  height: 100vmin;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-template-rows: repeat(2, 1fr);
  gap: 1v0min;
  position: absolute
}

.frontlayer>* {
  border: 1v0min solid;
  background-image: var(--bg);
  background-size: cover;
  background-position center center;
}
<div class="backlayer"></div>
<div class="frontlayer"></div>

Might not be the best HTML there so I apologise about that but it does work, just can’t seem to position the two grids over each other. There is plenty of examples here how to do this with single static images but nothing that deals with the grid aspect and I just can’t figure out how to change the existing examples to work with my situation.

TIA, Pete

2

Answers


  1. To make the grids stack on top of each other you just need one div that includes both grids, you make them both position absolute and the parent div position relative, like so:

    .parentDiv{
      position:relative;
    }
    .backlayer {
      position: absolute;
      width: 100vmin;      
      height: 100vmin;
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      grid-template-rows: repeat(4, 1fr);
      gap: 1vmin;
    }    
    .frontlayer {
      position: absolute;
      z-index: 1;
      width: 100vmin;
      height: 100vmin;
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      grid-template-rows: repeat(2, 1fr);
      gap: 1vmin; 
    }
    

    The grid you want in front gets z-index:1;

    HTML should look like this:

    <div class="parentDiv">
      <div class="backlayer"></div>
      <div class="frontlayer"></div>
    </div>
    
    Login or Signup to reply.
  2. You can stack different layers with grids by using Subgrid to allow the child layers to inherit the grids. This means: define a grid once, share it through multiple children.

    In your case you would wrap the backlayer and frontlayer with a parent where the grid is defined and have both layers inherit the grid. Then, depending in what layer the cells are, you can span them accordingly.

    const backlayer = document.querySelector('.backlayer');
    const numberOfItems = 16;
    for (let row = 0; row < 4; row++) {
      for (let col = 0; col < 4; col++) {
        let cell = document.createElement('div');
        cell.classList.add('cell');
        backlayer.appendChild(cell);
      }
    }
    
    const cells = backlayer.querySelectorAll('.cell');
    for (let i = 0; i < numberOfItems; i++) {
      var xpos = i % 4;
      var ypos = (i - xpos) / 4;
      var myurl = "url(https://picsum.photos/id/1015/200/200?" + ("X" + xpos) + "/" + ("Y" + ypos) + ")";
      cells[i].style.setProperty('--bg', myurl);
    }
    
    // below section for top transparent layer
    
    const frontlayer = document.querySelector('.frontlayer');
    const numberOfItems2 = 4;
    for (let row = 0; row < 2; row++) {
      for (let col = 0; col < 2; col++) {
        let cell = document.createElement('div');
        cell.classList.add('cell');
        frontlayer.appendChild(cell);
      }
    }
    
    const cells2 = frontlayer.querySelectorAll('.cell');
    for (let i = 0; i < numberOfItems2; i++) {
      xpos = i % 2;
      ypos = (i - xpos) / 2;
      var myurl2 = "url(https://picsum.photos/id/1016/200/200?" + ("X" + xpos) + "/" + ("Y" + ypos) + ")";
      cells2[i].style.setProperty('--bg', myurl2);
    }
    .container {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      grid-template-rows: repeat(4, 1fr);
      gap: 2vmin;
      width: 100vmin;
      height: 100vmin;
    }
    
    .layer {
      display: grid;
      grid-template-rows: subgrid;
      grid-template-columns: subgrid;
      grid-area: 1 / 1 / 5 / 5;
    }
    
    .backlayer .cell {
      grid-area: span 1 / span 1;
    }
    
    .frontlayer .cell {
      grid-area: span 2 / span 2;
    }
    
    .cell {
      grid-area: span 1 / span 1;
      border: 0 solid;
      background-image: var(--bg);
      background-size: cover;
      background-position center center;
      opacity: 0.5;
    }
    <div class="container">
      <div class="layer backlayer"></div>
      <div class="layer frontlayer"></div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search