Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

203
Visualizações
How to create a scrollable/touchable grid in CSS and JS?

I'm interested in how I can make a grid with an undetermined amount of columns and rows that I can put inside another div and have it not spill into others objects or mess with the parent size.

I want it to be square and I'm using Tailwind CSS but I can adapt to SCSS or vanilla CSS. Also I want it to be touchable/moveable with a mouse on desktop and touch capable devices.

How would I go about accomplishing this?

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

Assuming I've understood your question correctly, here is one way you could do it. I haven't tested it with a touch device but it shouldn't be hard to modify it to also respond to touch events.

const items = [
  ['a0', 'a1', 'a2'],
  ['b0', 'b1', 'b2'],
  ['c0', 'c1', 'c2']
];

let html = '';
for (let rowItems of items) {
  html += '<div class="row">';
  for (let item of rowItems) {
    html += '<div class="item">';
    html +=   item;
    html += '</div>';
  }
  html += '</div>';
}

const viewElem = document.querySelector('#view');
const outputElem = document.querySelector('#output');
outputElem.innerHTML = html;



let mouseStartPos = null;
let startOffset = null;

outputElem.addEventListener('mousedown', e => {
  outputElem.classList.remove('animate');
  mouseStartPos = {
    x: e.clientX,
    y: e.clientY
  };
  startOffset = {
    x: outputElem.offsetLeft - viewElem.offsetLeft,
    y: outputElem.offsetTop - viewElem.offsetTop
  };
});

window.addEventListener('mouseup', e => {
  mouseStartPos = null;
  startOffset = null;

  outputElem.classList.add('animate');
  const xGridOffset = -1 * Math.max(0, Math.min(Math.round((outputElem.offsetLeft - viewElem.offsetLeft) / -100), items.length - 1));
  const yGridOffset = -1 * Math.max(0, Math.min(Math.round((outputElem.offsetTop - viewElem.offsetTop) / -100), items[0].length - 1));
  outputElem.style.left = `${xGridOffset * 100}px`;
  outputElem.style.top = `${yGridOffset * 100}px`;  
});

window.addEventListener('mousemove', e => {
  if (mouseStartPos) {
    const xOffset = mouseStartPos.x - e.clientX;
    const yOffset = mouseStartPos.y - e.clientY;
    outputElem.style.left = `${-1 * xOffset + startOffset.x}px`;
    outputElem.style.top = `${-1 * yOffset + startOffset.y}px`;
  }
});
#view {
  width: 100px;
  height: 100px;
  overflow: hidden;
  
  border: 2px solid blue;
}

#output {
  position: relative;
}

.row {
  display: flex;  
}

.item {
  display: flex;
  min-width: 100px;
  width: 100px;
  height: 100px;
  box-sizing: border-box;
  
  justify-content: center;
  align-items: center;
  border: 1px solid red;
}

#output.animate {
  transition: left 1s ease 0s, top 1s ease 0s;
}
Drag it!<br/>
<br/>
<div id="view">
  <div id="output"></div>
</div>

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda