Danny 🎠 6 days ago
I LOVE THE NEW DESIGN SO MUCH AAAAAAAAAAH
nick 🤞 6 days ago
the new designs are finally here! still a few rough edges here and there, but we'll smooth them out. if you spot any bugs, tell us <3

Draggable box

Written by Danny • 10.06.2025
Have you ever wondered "how to drag a div around"? Or create a realistic browser-design, which also can be dragged around like a real browser window? That's what Mel asked in our wishlist (Hi Mel!) and I hope this tutorial will help you!

1️⃣ HTML:
We'll create a simple box (#dfdrag) with a header (#handle) you can drag.
<div id="dfdrag">
	<div id="handle">Drag me around!</div>
	<div class="content">
		This is a draggable box. Try moving it around! ♥️
	</div>
</div>
#dfdrag is the box we want to move.
#handle is the area you click to drag it.
.content holds the inner content.
2️⃣ CSS:
We want the box to be centered on the screen, look nice, and be easy to grab.
html, body {
	height: 100%;
	margin: 0;
	background: #333;
	overflow: hidden;
}

#dfdrag {
	width: 300px;
	height: 200px;
	background: #ececec;
	border: 2px solid #333;
	font-family: sans-serif;

	/* Optional: centering vertically and horizontally */
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
}

#handle {
	background: #3764ff;
	color: #fff;
	padding: 10px;
	cursor: move;
	user-select: none;
}

.content {
	padding: 15px;
}
transform:translate(-50%, -50%) centers the box both horizontally and vertically.
cursor:move gives visual feedback that the area is draggable.
3️⃣ JavaScript:
<script>
const dragTarget = document.getElementById("dfdrag");
const handle = document.getElementById("handle");

let isDragging = false;
let offsetX = 0, offsetY = 0;

handle.addEventListener("mousedown", function(e) {
	const rect = dragTarget.getBoundingClientRect();      // get box position
	const computed = window.getComputedStyle(dragTarget); // get styles
	const originalTransform = computed.transform;         // store original transform

	dragTarget.style.position = 'absolute';   // switch to absolute to move freely
	dragTarget.style.left = rect.left + "px"; // set current horizontal position
	dragTarget.style.top = rect.top + "px";   // set current vertical position
	dragTarget.style.margin = "0";            // remove margin
	dragTarget.style.transform = "none";      // remove centering

	offsetX = e.clientX - rect.left;
	offsetY = e.clientY - rect.top;

	isDragging = true;                        // enable dragging
	document.body.style.userSelect = "none";  // prevent text selection while dragging
});

document.addEventListener("mousemove", function(e) {
	if (isDragging) {
		const x = e.clientX - offsetX;        // calculate new horizontal position
		const y = e.clientY - offsetY;        // calculate new vertical position
		dragTarget.style.left = x + "px";     // move box horizontally
		dragTarget.style.top = y + "px";      // move box vertically
	}
});

document.addEventListener("mouseup", function() {
	isDragging = false;
	document.body.style.userSelect = "auto";
});
</script>

4️⃣ Full Example:
<!DOCTYPE html>
<html>
<head>
<title>Draggable Box</title>
<meta charset="UTF-8">
<style>
html, body {
	height: 100%;
	margin: 0;
	background: #333;
	overflow: hidden;
}

#dfdrag {
	width: 300px;
	height: 200px;
	background: #ececec;
	border: 2px solid #333;
	font-family: sans-serif;

	/* Optional: centering vertically and horizontally */
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
}

#handle {
	background: #3764ff;
	color: #fff;
	padding: 10px;
	cursor: move;
	user-select: none;
}

.content {
	padding: 15px;
}
</style>
</head>
<body>

<div id="dfdrag">
	<div id="handle">Drag me around!</div>
	<div class="content">
		This is a draggable box. Try moving it around! ♥️
	</div>
</div>

<script>
const dragTarget = document.getElementById("dfdrag");
const handle = document.getElementById("handle");

let isDragging = false;
let offsetX = 0, offsetY = 0;

handle.addEventListener("mousedown", function(e) {
	const rect = dragTarget.getBoundingClientRect();      // get box position
	const computed = window.getComputedStyle(dragTarget); // get styles
	const originalTransform = computed.transform;         // store original transform

	dragTarget.style.position = 'absolute';   // switch to absolute to move freely
	dragTarget.style.left = rect.left + "px"; // set current horizontal position
	dragTarget.style.top = rect.top + "px";   // set current vertical position
	dragTarget.style.margin = "0";            // remove margin
	dragTarget.style.transform = "none";      // remove centering

	offsetX = e.clientX - rect.left;
	offsetY = e.clientY - rect.top;

	isDragging = true;                        // enable dragging
	document.body.style.userSelect = "none";  // prevent text selection while dragging
});

document.addEventListener("mousemove", function(e) {
	if (isDragging) {
		const x = e.clientX - offsetX;        // calculate new horizontal position
		const y = e.clientY - offsetY;        // calculate new vertical position
		dragTarget.style.left = x + "px";     // move box horizontally
		dragTarget.style.top = y + "px";      // move box vertically
	}
});

document.addEventListener("mouseup", function() {
	isDragging = false;
	document.body.style.userSelect = "auto";
});
</script>

</body>
</html>

Changelog

17.06.2025
- code simplified for better flexibility
- added more comments