Draggable Elements

Dragging an element around the screen is something that is pretty firmly in the territory of JavaScript. You’ll want access to DOM events like clicks and mouse movement. But we’re here to talk CSS trickery so let’s get it done in HTML and CSS alone!

Just to be clear, even when we pull this off in HTML and CSS, all we’re getting done is making the element draggable around the screen. If you actually need to do something as a result of that dragging, your back in JavaScript territory.

This trick comes by way of Scott Kellum. Scott has done a number of my absolute favorite CSS tricks over the years, like this super simple @keyframes setup that bounces an element off the viewport edges like an old school screensaver, to an impressive Sass-powered parallax technique.

There really just one CSS thing that can help us with click-and-drag, and that’s the browser UI we get on desktop browsers when we use the resize property. Here’s a <div> where we use it (along with overflow: hidden; which is a prereq for it to work):

If you’re looking at the demo a desktop browser, you’ll be able to grab the bottom right corner of that and drag it around.

Now here’s the real trick.

We can put that resizeable element into another container. That container will grow in height naturally as the resizeable element changes height. It will change it width naturally because of width: min-content;.

Now we have a parent element that resizes along with the resizeable element. That matters because we can put other stuff in that parent element that moves along with it. I’ll drop a big ol’ ✖ in there and position it right on top of the resizer, with pointer-events: none; on it so I can still do the resizing:

Now if we make sure the resizing element is hidden via opacity: 0; it appears as if we’ve made a draggable element out of nowhere! We might need to jiggle the numbers a bit to get things lining up, but it’s doable: