w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.49k stars 660 forks source link

[css-selectors] Add pseudo for active/valid file drop targets #9205

Open argyleink opened 1 year ago

argyleink commented 1 year ago

Problem: JavaScript is required to change the style of a file input if you want to show feedback that the input is a valid drop target. Currently, authors must add multiple JS listeners to file type inputs to "do their best" to show the user the UI is expecting the file drop / is a valid drop location. Without this JS, users have to guess / assume / or notice that tiny subtle hover effect (which I never noticed until I watched the below demom video demo which is quite zoomed).

<input 
    type="file" 
    ondragenter="this.classList.add('dropping')" 
    ondragleave="this.classList.remove('dropping')" 
         ondrop="this.classList.remove('dropping')"
>

<style>
input[type=file].dropping {
  /* … */
}
</style>

would become ✨

<input type="file">

<style>
input[type=file]:drop-target {
  /* … */
}
</style>

https://github.com/w3c/csswg-drafts/assets/1134620/a5ff29fc-2aca-4555-901f-ff5a1ab7b175

Link to Codepen

Proposal: :drop-target Remove the JS requirement and expose the state the browser is keeping private.

input[type="file"] {
  /* … */

  &:drop-target {
    outline: 2px dashed Highlight;

    @media (prefers-reduced-motion: no-preference) {
      animation: drop-zone 1.5s ease-out infinite;
    }
  }
}

This selector would activate when the user's drag coordinates are intersecting with the elements bounds, and would deactivate when the user moves the file off of the element. This selector is up for discussion about whether it should work for all inputs/elements, or just the file input.

This could also be combined with :has() so forms and UIs can know if there is a drag event happening on a child element, and it can compliment the state by reducing noise (for example):

fieldset:has(:drop-target) :not(:drop-target) {
  opacity: .5;
}

Resources: https://www.w3.org/TR/selectors-4/

romainmenke commented 1 year ago

This selector would activate when the user's drag coordinates are intersecting with the elements bounds, and would deactivate when the user moves the file off of the element.

Maybe another state is needed to indicate all drop targets on a page when a user is dragging a file around.

If there is some time between seeing a file upload field and finding the file you need to upload, you might have forgotten where the actual file upload is. Highlighting all drop targets when the cursor intersects with the window might also be helpful.

andrejsharapov commented 1 year ago

I once observed the trend that most teach platforms strictly forbid the use of attributes in the html, such as onclick and onfocus, and advised to use js, but the code above breaks this view. 🧐

tayfunerbilen commented 1 year ago

Since :has() not fully ~supported~ by browsers, Instead of input If we can use :drop-target for parent, it would be more effective I guess.

alexreardon commented 1 year ago

Hi @argyleink,

I love and share your desire to make drag and drop in browsers easier to work with for engineers. I think there is so much that can and should be done to make the browser powered drag and drop easier for engineers to work with.

Initial thoughts on this proposal

For simple use cases, :drop-target could be helpful. However, for medium to complex cases I don't see :drop-target being helpful, and it could actually be confusing and unhelpful.


I am super open to changing my mind on this! These are my initial thoughts 😊