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-4] Rescope :has to static CSS rather than .querySelector #3925

Closed
fantasai opened this issue May 11, 2019 · 13 comments
Closed

[selectors-4] Rescope :has to static CSS rather than .querySelector #3925

fantasai opened this issue May 11, 2019 · 13 comments

Comments

@fantasai
Copy link
Collaborator

There are no implementations of :has() in .querySelector and the like. However, we do have implementations of :has() in PDF renderers: https://www.princexml.com/doc-refs/#sel-logical

The spec should be updated to reflect this.

@SelenIT
Copy link
Collaborator

SelenIT commented May 11, 2019

The linked document also lists the :contains() pseudo-class, which seems to have gone from the specs at some point before 2005, as supported. Is its implementation status also still relevant?

Honestly, as a web developer, I would prefer something less general that can be safely used in styling (like :has-children() or :has-following-siblings() mentioned here) to the powerful general mechanism that can't be used in the context it's most needed because of possible performance implications. Maybe it's not late to introduce them into the current module (and probably to postpone the whole "selector profles" thing to some future levels, to keep the current level simple and more developer-friendly)?

@shaunrashid
Copy link

shaunrashid commented May 11, 2019

I prefer brevity when it comes to CSS. I would prefer :contains() for the syntax because it makes sense to me to read as "x contains y". But :has works too, especially if it matches how PDF renderers use it and if :contains() could be used to match text within an element.

@bkardell
Copy link
Contributor

@fantasai what would you update? Wouldn't a PDF renderer fit the same profile?

@SelenIT
Copy link
Collaborator

SelenIT commented May 12, 2019

Please. Don't fix what is not broken yet, and it's unclear if it ever gets broken in the future. Don't make simple things complicated. There is no evidence that the "CSS profiles" concept is anything more than a purely theoretical question. Anywhere in practice, there is just CSS.

The impossibility to style elements depending on their content or following siblings is a real problem that web developers have suffered from for years. The slowness of the selector that only perhaps would be implemented in the future is not (although the slowness of its script-based alternatives that web devs currently have to resort to probably is!). Please, help solving the real problem. If :has() can't be reasonably done so that web devs could safely use it for styling, than please give the web devs anything that can instead.

Even if :has() was implemented in JS-only context, it would be merely kind of a syntactic sugar: document.querySelectorAll('a:has(img)') is not that more readable for a JS developer than [...document.querySelectorAll('a')].filter(el => el.querySelector('img')). It's styling where it would be a game-changer and totally worth implementation effort, just like already existing content-aware selectors like :focus-within. Please, help the web developers to solve the real problem!

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed Rescope :has to static CSS rather than .querySelector, and agreed to the following:

  • RESOLVED: Mark this as at risk and optional, remove profile
The full IRC log of that discussion <dael> Topic: Rescope :has to static CSS rather than .querySelector
<dael> github: https://github.com//issues/3925
<dael> fantasai: It was pointed out nobody impl :has not even in query selection. Spec should align with reality and not say you can use it. it is impl in Prince XML so maybe needs to stay in spec but scope to PDF renderers
<dael> florian: I think we discussed in the past and wanted to ban it from PDF engines as well b/c worry it would creep out of that narrow use case and we'd be stuck for compat reasons. Or something along those lines. Couldn't find minutes
<dael> fantasai: We did. And that's why it explicitly says shouldn't be used in CSS but reality is that's not what's happening
<dael> Rossen_: If this is reality than what fantasai suggested makes sense
<dael> Rossen_: Any additional comments or challenges to this?
<dael> florian: Okay changing .querySelector but not sure about PDF render
<dael> fantasai: Reused a definition about static not dynamic
<dael> florian: Does [list of things] count?
<bkardell_> q+
<dael> fantasai: Up to impl if it counts
<dael> Rossen_: It is impl specific
<dael> fantasai: If you don't like this division either we remove and people are non-conforment or we convince more people to impl. So what do you want to do?
<dael> florian: Since existing impl violates spec about if they should impl and if we put a feature in the spec saying this is a thing you may or may not want to impl sure. I don't know if static render definition makes a difference, but if browsers aren't worried about creeping out sure
<dael> dauwhe: Other instances of infections creeping out?
<dael> florian: Intentionally yes, accidentaly not sure
<dael> dauwhe: Seems low risk
<dael> fantasai: It's not we dont' want this in browsers, it's that no one has figured out how to do it in a performant way.
<dael> fantasai: If a browser figures out how to do it we'd be happy
<dael> florian: Keep in spec, remove profile distinction, mark at risk
<florian> q+
<dael> Rossen_: Have enough features not implemented, reducing that is a great goal. Lingering things in spec that's an idea that won't happen isn't good. There's history in github and repos that people could find. I'd move forward to drop now and if people want to make a case they will
<gregwhitworth> +1 to what Rossen_ said
<dael> bkardell_: Sorry, didn't have sound early in call. We added distinction between profiles b/c it could easily be impl in JS in theory. I think we hear people saying it doesn't add much, I disagree with that. Isn't the way the spec is written, I thought it was specifically because if a vendor wanted to experimentally impl in full profile that's okay. Is that not the case?
<dael> florian: Spec says browsersplease don't do this. We didn't want someone to ship while others didn't know how. If that was a good idea is sep. question, but spec says must not impl in CSS< only JS.
<dael> florian: To Rossen_ point it's not just not going to happen, it's not going to happen prob in browsers, but it is happening in other vendors with the name. We put at risk, push to L5 if we go to rec
<dael> Rossen_: Should we then spec other features in JS library?
<dael> florian: It's a feature we specced rendered by a CSS. Just not a browser
<dael> bkardell_: It's in jQuery for same reason, because it was in CSS when it was rewritten
<dael> florian: Maybe we go to rec with 2 impl, jQuery and Prince. A bit of a stretch
<dael> florian: I feel bad removing it after it's impl in several places and freeing up the namespace doesn't sound nice.
<gregwhitworth> bkardell_: is that really the order of things, I thought jQuery had it prior to any spec text existing
<dael> fantasai: I think disingenuous to remove completely given there is an impl of something standardized. Seems like we only put things in spec if a browser impl but another non-browser impl isn't worthy. If this was webkit not Prince we wouldn't talk about drop
<dael> bkardell_: What if Webkit only did it for print stylsheets
<dael> fantasai: We be conforment to spec
<dael> bkardell_: I think florian just said it would violate current spec
<dael> florian: Yes b/c extra restriction
<dael> AmeliaBR: Question now is this whole idea of live vs snapshot profiles, is it impl anywhere? No one is impl things for .querySelector that's not for CSS. Only UA that does .has is as a css selctors. That part of spec needs reconsider, but what direct? .has is not in spec or drop the profile idea?
<dael> florian: I'd go with later and mark at-risk
<dael> fantasai: and optional
<dael> florian: I don't know what difference it makes but okay
<dael> fantasai: Means not required to conform
<dael> bkardell_: So Prince is in violation?
<dael> florian: Is now, but if we do this it wouldn't be
<dael> bkardell_: Can someone recap? Remove the profile notion and mark at risk and options?
<hober> fwiw i agree with rossen_, but i'm also okay with moving it from L4 to L5 as a compromise
<dael> fantasai: At risk makes it easier to remove later. It's a process thing. Optional means you can be conforment to module without doing this
<dael> AmeliaBR: It's separate module you can impl or not but it's tucked inside main selectors
<dael> fantasai: Yeah. When first did profiles there were many features, but now there's just this one
<dael> bkardell_: If someone impl for .querySelector only it's okay?
<dael> fantasai: Yes
<dael> bkardell_: And a print stylesheet or static processing engine that's okay?
<dael> fantasai: Yes
<dael> bkardell_: sgtm
<dael> Rossen_: Nearing consensus. Any other additional thoughts before we move this to L5 and mark at risk?
<dael> AmeliaBR: How is @supports selector supposed to work with selectors impl only in JS and not CSS. Separate issue.
<dael> florian: Another point. In past other proposed selectors such as focus-inside that were initially rejected by bodies because we have :has. We can rebuff with saying browsers don't do it. Can now with intent to impl
<dael> bkardell_: Begs the question of lots of documented use cases of possible withins that are solved by this. 100 withins is not wonderful thing
<dael> fantasai: I think we should tackle that in separate issue
<dael> fantasai: There's various approaches we can take
<bkardell_> also sgtm to tackle in another issue
<dael> Rossen_: Agree. Objections to resolve by move this to L5 and mark at risk and optional
<bkardell_> +1 to leave in l4
<dael> fantasai: Leave in L4. It is impl. This isn't even CR yet. We're not trying to trim to 2 implementations yet.
<dael> florian: At risk is enough.
<dael> Rossen_: That's fine. Mark this as at risk and optional
<dael> RESOLVED: Mark this as at risk and optional, remove profile
@Jamesernator
Copy link

Jamesernator commented Jul 31, 2019

I dunno if any engine implementors are here but is there any reason browsers have at not least implemented the partial version of just :has(> childSelector) and :has(+ siblingSelector)?

This would solve a lot of developer's use cases while still leaving the door open for :has(descendentSelector) if it proves feasible.

@ExE-Boss
Copy link
Contributor

ExE-Boss commented Aug 8, 2019

@SelenIT
The following is more performant:

Array.from(document.querySelectorAll('a img', img => {
	let el = img;
	while (!!(el = el.parentElement)) {
		if (el.localName.toLowerCase() == 'a') return el;
	}
	return null;
});

@Jamesernator
That would solve my use case.


See also #3345

@SelenIT
Copy link
Collaborator

SelenIT commented Aug 8, 2019

@ExE-Boss agree, this would be more suitable in most practical cases (though this seems to have a slightly different semantics in the unlikely case of nested a elements). I guess it also can be rewritten as a one-liner like Array.from(document.querySelectorAll('a img'), img => img.closest('a')) which would be probably even more performant. But my example was there just to illustrate the point that JS developers probably won't benefit from the new sub-syntax for the tree structure logic as much as CSS developers would benefit from content-depending styling of elements.

SelenIT added a commit that referenced this issue Feb 3, 2020
Remove the notion of Live and Snapshot Profiles and mark `:has()` as "at risk" and "optional", according to the [resolution]()#3925 (comment) to #3925
tabatkins added a commit that referenced this issue Feb 3, 2020
[selectors-4] Mark :has() as at risk and optional, remove profile (solves #3925)
@fantasai fantasai closed this as completed May 6, 2022
@oleedd
Copy link

oleedd commented Dec 1, 2022

Why is :has() risky? Difficult to implement is not risky, it is about problematicity.

@SelenIT
Copy link
Collaborator

SelenIT commented Dec 1, 2022

Good point! Since we already have two shipped implementations in two most popular engines, does marking :has() as "at-risk" still make any sense?

@Marat-Tanalin
Copy link

And it’s not even difficult to implement.

@SebastianZ
Copy link
Contributor

I've created #8168 to update the at-risk info in that spec.

Sebastian

@tabatkins
Copy link
Member

"At-risk" is a W3C term of art that has meaning only in terms of the W3C Process; marking a feature as "at-risk" allows us to drop it from the spec after it's reached a "stable" level (like Candidate Rec) without as much rigamarole as adding or changing a feature normally would require.

But, yes, the at-risk list in Selectors is out-of-date; thanks for the issue, @SebastianZ

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment