Adding interactivity to your web pages can make the user experience more engaging and dynamic. One of the most practical UI features is the draggable element, which allows users to click and move an object around the screen. In this tutorial, we will build a custom draggable element using pure HTML, CSS and JavaScript.
This component can be useful for interactive dashboards, UI experiments, draggable widgets or even games. Let’s break it down step by step.
HTML Structure
We’ll begin with the basic HTML layout.
<div class="container">
<div class="draggableElement">Drag me!</div>
</div><div class="container">→ acts as the parent wrapper for our draggable element. It ensures we have a defined area where the element exists.<div class="draggableElement">→ this is the box that users can grab and drag around. We’ve also added the text"Drag me!"to guide users.
This minimal HTML ensures our focus stays on styling and functionality. The HTML is intentionally simple because all the magic of movement will happen through CSS for styling and JavaScript for drag functionality.
CSS Styling
Next, we’ll style the draggable element and its container for a clean and responsive design.
.container, .draggableElement{
display: flex;
align-items: center;
justify-content: center;
}
.container {
min-height: 100vh;
min-width: 250px;
position: relative;
}
.draggableElement {
position: absolute;
cursor: grab;
width: 150px;
height: 150px;
font-size: 18px;
color: #fff;
border-radius: 30px;
font-family: 'Calibri';
transition: transform .3s;
background-color: #10344d;
}
.dragging {
transform: scale(.9);
cursor: grabbing !important;
}- Flexbox alignment → both
.containerand.draggableElementusedisplay: flex; align-items: center; justify-content: center;to perfectly center content. .container→ stretches full viewport height (100vh) withposition: relativeso the draggable element can be absolutely positioned inside it..draggableElement→ styled as a square box (150px × 150px) with rounded corners, dark blue background andcursor: grabto indicate interactivity.- Transition effect → we added
transition: transform .3sto make scaling smooth while dragging. .draggingclass → slightly scales the element (transform: scale(.9)) and changes the cursor tograbbing, giving real-time feedback during dragging.
With CSS, we’ve not only made the box visually appealing but also enhanced usability by showing visual cues when the element is being dragged.
JavaScript Functionality
Finally, we’ll add interactivity with JavaScript to make the box draggable.
const draggableElement = document.querySelector('.draggableElement');
let offsetX = 0, offsetY = 0;
draggableElement.addEventListener('mousedown', function (e) {
// Preventing default behavior to avoid unwanted selections
e.preventDefault();
// Calculating initial offsets
offsetX = e.clientX - draggableElement.getBoundingClientRect().left;
offsetY = e.clientY - draggableElement.getBoundingClientRect().top;
// Adding the 'dragging' class to apply styling changes
draggableElement.classList.add('dragging');
// Adding event listeners for mousemove and mouseup
document.addEventListener('mousemove', dragElement);
document.addEventListener('mouseup', stopDragging);
});
function dragElement(e) {
// Updating the element's position based on mouse movements
draggableElement.style.left = `${e.clientX - offsetX}px`;
draggableElement.style.top = `${e.clientY - offsetY}px`;
}
function stopDragging(e) {
// Preventing default behavior to avoid unwanted selections
e.preventDefault();
// Removing the 'dragging' class to revert styling changes
draggableElement.classList.remove('dragging');
// Removing event listeners to stop tracking mouse movements
document.removeEventListener('mousemove', dragElement);
document.removeEventListener('mouseup', stopDragging);
}- Selecting the element →
document.querySelector('.draggableElement')targets our draggable box. - Offsets calculation → when the mouse is pressed (
mousedown), we calculate the exact distance (offsetX,offsetY) between the mouse pointer and the box’s top-left corner. This prevents the element from “jumping” during drag. - Adding dragging feedback →
.draggingclass is applied so the element visually scales down and cursor changes. - Moving the element →
mousemoveupdates theleftandtopCSS values in real-time, repositioning the element as per cursor movement. - Stopping the drag → on
mouseup, we remove both the event listeners (mousemoveandmouseup) and reset styles by removing.dragging.
The JavaScript ensures smooth drag functionality while handling edge cases like accidental text selection or cursor jumps. We also clean up event listeners after dragging, making the code efficient.
With just a few lines of HTML, CSS and JavaScript, we have created a fully functional draggable element that enhances user interaction. This component is flexible—you can use it for widgets, modals, popups or interactive elements in your projects.
By combining CSS transitions for smooth animations and JavaScript for interactivity, you’ve built a reusable feature that works across modern browsers.



