Now, I do know what you’re pondering. Yet one more CSS pseudo-class… However I feel this suggestion is reasonably cool.
Earlier this yr, it was proposed so as to add a brand new pseudo-class, :drag, that might allow builders to use types when a component is being actively dragged by the consumer. Presently, CSS lacks a mechanism to detect drag interactions, making it troublesome to handle UI behaviors that rely upon this motion with out counting on JavaScript.
No JavaScript! I like the concept of getting a pseudo-class devoted to this operate reasonably than going by the classList.toggle() route.
However, how would this work, although?
To know, you first should know that the HTML Drag and Drop API. A number of the occasions it fires embody:
drag(fires each few milliseconds when the factor is dragged),dragstart(occasion fires on the preliminary drag), anddragend(occasion fires when the dragging the factor stops).
Let’s take a fast have a look at how these drag-and-drop occasions work in JavaScript so as to perceive how they’d translate in CSS. Think about we now have seven button components in a
We will make all the .menu-bar draggable by slapping an attribute on it:
For our CSS, we merely give the is-dragging class some styling, which might be utilized solely when the factor is dragged or moved:
In CSS, we are able to arrange an .is-dragging class that we’ll set on the factor with JavaScript when it’s within the technique of being dragged. These are the types we apply to the factor when that’s occurring:
.is-dragging {
box-shadow: 0 4px 12px rgba(0 0 0 / 0.15);
background: #fff;
remodel: translate(1px);
opacity: 0.2;
scale: 1.2;
}
And right here’s the JavaScript to toggle between the beginning of the mouse drag and its finish. It listens for a dragstar occasion and provides the .is-dragging class to the .menu-bar. And once we drop the .menu-bar, the dragging enjoyable stops and the .is-dragging class is eliminated:
menuBar.addEventListener("dragstart", (occasion) => {
occasion.goal.classList.add("is-dragging");
});
menuBar.addEventListener("dragend", (occasion) => {
occasion.goal.classList.take away("is-dragging");
});
Our output would look one thing like this. Drag the dropdown factor to see:
Not unhealthy! When the menu bar is dragged, it retains a picture of itself in its authentic place that's styled with the .is-dragging class. And whereas we had been completely capable of knock this out with JavaScript, how cool would it not be to have that proposed :drag pseudo-class to summary all that script-y stuff:
.menu-bar:drag {
cursor: grabbing;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
background: #fff;
remodel: translate(1px);
opacity: 0.2;
scale: 1.2;
}
+1 for efficiency! +1 for one much less dependency! +1 for maintainability!
How concerning the preview picture?
Do you know we are able to fashion the precise factor itself because it’s being dragged across the display screen? That’s referred to as the preview picture and we are able to exchange it with a
It’s just a bit extra JavaScript utilizing the dataTransfer.setDragImage() operate:
const dragPreview = doc.createElement("div");
dragPreview.textContent = "📦 Dragging...";
dragPreview.fashion.cssText = `
background: #fff6d6;
border: 2px dashed orange;
border-radius: 0.5rem;
colour: #333;
padding: 0.5rem 1rem;
`;
doc.physique.appendChild(dragPreview);
// This replaces the default drag preview
occasion.dataTransfer.setDragImage(dragPreview, 0, 0);
// Take away after the occasion fires
setTimeout(() => dragPreview.take away(), 0);
Right here’s the place I’ll exit on a limb and recommend one other CSS pseudo particularly for that ::drag-image. Think about having the ability to sidestep all that JavaScript and straight-up write the types in CSS:
::drag-image {
content material: "📦 Dragging...";
padding: 0.5rem 1rem;
background: #fff6d6;
colour: #333;
border: 2px dashed orange;
border-radius: 0.5rem;
}
I suppose it might be a pseudo-class as an alternative, nevertheless it appears like a pseudo-element makes extra sense since we’re speaking a couple of particular object reasonably than a state.
I opened a problem for that — give it a thumbs-up for those who’d discover it helpful to have a ::drag-image pseudo-element like that. The CSSWG is already slated to debate the :drag proposal. If that will get baked into the specs, then I’d push for the pseudo-element, too.
Ideas?
Yea or nay for drag-related pseudos? Would you attain for one thing like that, or do you're feeling steps on JavaScript’s toes an excessive amount of?
