I am trying to create a “viewport” effect where I can drag a div around the screen. I want to have controls at the top but I am having issues with the dragged content moving over the controls div.
I looked around and found the following articles which explained a lot but i’m dumb.
https://www.w3.org/TR/CSS2/zindex.html
https://philipwalton.com/articles/what-no-one-told-you-about-z-index/
I have some code from the net that demonstrates the issue. I want the green rectangle to “move under” the other content div (with id “message”).
const content = document.getElementById('content');
const message = document.getElementById('message');
let isDragging = false;
let startX, startY, initialX, initialY;
content.addEventListener('mousedown', (e) => {
isDragging = true;
startX = e.clientX;
startY = e.clientY;
initialX = content.offsetLeft;
initialY = content.offsetTop;
content.style.cursor = 'grabbing';
message.innerHTML = "Mousedown, initial X: " + initialX + ", initialY: " + initialX;
});
document.addEventListener('mousemove', (e) => {
if (isDragging) {
const currentX = e.clientX;
const currentY = e.clientY;
const dx = currentX - startX;
const dy = currentY - startY;
content.style.left = `${initialX + dx}px`;
content.style.top = `${initialY + dy}px`;
}
});
document.addEventListener('mouseup', () => {
isDragging = false;
content.style.cursor = 'grab';
});
// Prevent text selection while dragging
content.addEventListener('mousedown', (e) => {
e.preventDefault();
});
#draggable {
position: relative;
margin: 0;
padding: 0;
height: 76vh;
display: flex;
justify-content: center;
align-items: center;
border: 1px inset;
}
#viewport {
position: relative;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
#content {
position: absolute;
width: 200px;
height: 150px;
color: white;
display: flex;
justify-content: center;
align-items: center;
cursor: grab;
user-select: none;
/* Prevent text selection */
background-color: green;
opacity: .99;
}
<div style="z-index: 4">
<div>
<span id="message">Other content</span>
</div>
</div>
<div id="draggable" style="z-index: 3">
<div id="viewport" style="z-index: 2">
<div id="content" style="z-index: 1">
DRAG ME
</div>
</div>
</div>
Is this a simple fix that I just can’t see?
Thanks in advance.