Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[selectors] :visible / :hidden #7489

Closed
bramus opened this issue Jul 12, 2022 · 4 comments
Closed

[selectors] :visible / :hidden #7489

bramus opened this issue Jul 12, 2022 · 4 comments

Comments

@bramus
Copy link
Contributor

bramus commented Jul 12, 2022

There is a mechanism to check an element’s visible status: Element.checkVisibility. I see some use-cases for a :visible selector, which would match elements whose Element.checkVisibility check returns true. :hidden would go hand in hand with that and select the opposite set of elements.

An example would be to “style the first visible item in a list of items that can be dynamically filtered”. To target said element, the selector would be :nth-child(1 of > :visible). Prior Art is jQuery’s :visible selector, but don’t have any numbers on how much it was used.

There are some considerations to keep in mind with such a selector, though:

  1. Performance: How performant is selecting all visible elements using :visible? My hunch would be that it’s not very performant.
  2. Loops: Doing something like :visible { opacity: 0; } would make an element no longer visible, thus the selector would become unmatched.

That second issue is a broader CSS issue which could be solved by limiting which CSS properties can be changed when such an element is targeted. Just like styling the pseudo ::first-line and styling highlights are limited to a set of allowed properties, these :visible/:hidden selectors could have a disallow-list of properties: display, opacity, …

Furthermore you wouldn’t be able to do anything really practical from a CSS point of view when targeting :hidden, but could use it in document.querySelectorAll() to select those elements for further processing.

@dbaron
Copy link
Member

dbaron commented Jul 12, 2022

While pseudo-elements have limited the set of properties that apply, we've never limited the properties for pseudo-classes before, and it's a somewhat different concept, since the limitation has to apply based on the selector used to match the rule, rather than the simpler model of applying to the thing (pseudo-element) being matched.

@tabatkins
Copy link
Member

Yeah, we can't meaningfully limit the set of properties you can apply via a pseudo-class. Not only is it actually a completely distinct and more complicated subject due to what you're filtering by, it doesn't extend.

If you have pseudo-classes :foo and :bar that can have their matching affected by properties, so you prevent rules using :foo from setting property foo and rules using :bar from setting property bar, then there's nothing preventing you from setting bar in a :foo rule, then using a :bar rule to respond to that and set foo, thus giving us the cyclic behavior we were trying to avoid initially. The end result of this is that we can't have separate lists of restricted properties, one per pseudo-class - we need a single list of properties that can affect any pseudo-class, and are restricted from being used in any property-affected pseudo-class. This not only becomes extremely restrict extremely quickly (you can't set opacity, display, etc since :visible would be affected by them), but it's not forward-compatible - if we added a new pseudo-class that needs to restrict an existing property, all existing rules with property-affected pseudo-classes that currently (validly) set that property would suddenly stop being able to do so.

So that idea is just permanently, unfixably dead in the water forever. If you want selectors that can be affected by properties/layout, you must build them on the same model as :hover - the detection is "late" (after a full page style/layout has completed) and is allowed to be preempted from looping by the browser.

@bramus
Copy link
Contributor Author

bramus commented Jul 18, 2022

If you want selectors that can be affected by properties/layout, you must build them on the same model as :hover - the detection is "late" (after a full page style/layout has completed) and is allowed to be preempted from looping by the browser.

Could this be the case here?

@bramus
Copy link
Contributor Author

bramus commented Jul 19, 2022

To answer myself here: No, this is not feasible and is explained in the wiki why

@bramus bramus closed this as completed Aug 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants