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

[css-conditional-4] selector() feature query function for selector support #3207

Closed
dbaron opened this issue Oct 12, 2018 · 21 comments

Comments

Projects
None yet
10 participants
@dbaron
Copy link
Member

commented Oct 12, 2018

I think one feature we should add to Conditional Rules Level 4 is a feature query function to test for selector support, presumably called selector().

I've started a draft of an explainer for this, from which I quote the relevant section:


Having feature queries based on selectors is probably the highest priority addition, both because it seems the most likely to be important in the near future, and because it is the simplest. It has come up recently because CSS authors using the features in the CSS Scrollbars Module Level 1 may want to query for support of those features, and may also want to query for support of the ::-webkit-scrollbar pseudo-element.

I believe a possible syntax for such a feature was discussed at one point early in the development of @supports, but I can't find meeting minutes of the discussion. I think the best way to extend the syntax is using a selector() function, as in:

@supports (scrollbar-width: thin) or selector(::-webkit-scrollbar) {
  #chatwindow { overflow: scroll; scrollbar-width: thin }
  #chatwindow::-webkit-scrollbar { width: 5px }
}

It is worth noting that this usage requires that the selector() feature query function not copy the quirks that are present in selector parsing, where all ::-webkit-* pseudo-elements behave as though they're supported (and allow the selector to parse). Instead, inside of the selector() feature query function, this quirk should not be present, and a selector() function containing a ::-webkit-* pseudo-element should only be true if the pseudo-element is actually supported.

Other than this, the function should work just as the tests for support/validity work in the rules on handling invalid selectors.

@tabatkins

This comment has been minimized.

Copy link
Member

commented Oct 12, 2018

I agree that this is useful and high-priority among possible @supports additions, and think that's the right syntax.

@inoas

This comment has been minimized.

Copy link

commented Oct 12, 2018

Great idea!

What about other selectors and matching them?

@supports selector(<) {
    // use imaginary future < selector
} else @supports selector(:visible) {
    // use imaginary future :visible selector
} else {
   // use some conventional selector
}

p.s.: no endorsement for those imaginary selectors

@tabatkins

This comment has been minimized.

Copy link
Member

commented Oct 12, 2018

selector(<) would likely fail; it doesn't match the selector grammar. But you could write selector(a < b) and it would match in a hypothetical world where we added that combinator.

selector(:visible) would definitely work, exactly the same as dbaron's other examples.

else is also something we should add: http://tabatkins.github.io/specs/css-when-else/ ^_^

@inoas

This comment has been minimized.

Copy link

commented Oct 12, 2018

so maybe selector-operand(<) {}? not sure forcing one to add virtual dom elements to check for selector operand support sounds so sane to me...

@tabatkins

This comment has been minimized.

Copy link
Member

commented Oct 12, 2018

? You don't have to add any elements. You just have to create a well-formed selector, so we can do a trivial "does this parse as a selector" check. You already know for a fact that a and b are valid tagname selectors.

@fantasai

This comment has been minimized.

Copy link
Collaborator

commented Oct 15, 2018

selector(* > *) would also work if you don't want to choose arbitrary tag names.

@ExE-Boss

This comment has been minimized.

Copy link
Contributor

commented Oct 16, 2018

I was planning to suggest this.

Also, when it comes to functional selectors, I presume that the brackets are necessary (eg. selector(::slotted(*)) will need to be used)

This will also go hand in hand with #3082, which would allow simplifying:

@supports selector(A) or selector(B) {
  // do stuff
}

to

@supports selector(A, B) {
  // do stuff
}

Where A and B are little supported selectors, eg. :matches() or :has().

@emilio

This comment has been minimized.

Copy link
Collaborator

commented Oct 16, 2018

I think I'd prefer if we just used the <selector> syntax. Using a <selector-list> looks like different arguments to the function, and it wouldn't be clear whether the semantics are all or any.

@emilio

This comment has been minimized.

Copy link
Collaborator

commented Oct 16, 2018

Plus the <selector> syntax can be extended later if needed, but not the other way around.

@emilio

This comment has been minimized.

Copy link
Collaborator

commented Oct 16, 2018

I meant <complex-selector>, btw.

@heycam

This comment has been minimized.

Copy link
Contributor

commented Oct 16, 2018

Should namespace prefixes in the selector be checked against the prefixes declared in the style sheet it's used in, or should all prefixes be allowed, since we're really just checking for syntactic correctness of selectors that the browser understands? And if we should be checking them against the declared prefixes, should any namespace prefix usage in a CSS.supports("selector(...)") call evaluate to false?

@ExE-Boss

This comment has been minimized.

Copy link
Contributor

commented Oct 16, 2018

I think we are just checking syntactic correctness, as *|* is a valid selector even without a @namespace declaration, IIRC.

@emilio

This comment has been minimized.

Copy link
Collaborator

commented Oct 16, 2018

A missing namespace is a parse error everywhere else, I'd rather be consistent on rejecting it, since not doing that introduces a special-case, and other APIs like querySelector already throw on that, like (for example, document.querySelector("a|b") throws, doesn't return null).

@emilio

This comment has been minimized.

Copy link
Collaborator

commented Oct 16, 2018

FWIW the namespace question came during the code review of https://bugzilla.mozilla.org/show_bug.cgi?id=1499386.

moz-wptsync-bot added a commit to web-platform-tests/wpt that referenced this issue Oct 17, 2018

Implement @supports selector() syntax.
This implements the selector(<complex-selector>) syntax for @supports.

See w3c/csswg-drafts#3207 for explainer and
discussion.

Probably would should wait for that to be sorted out to land this, or maybe we
should put it behind a pref to get the code landed and change our
implementation if the discussion there leads to a change.

Differential Revision: https://phabricator.services.mozilla.com/D8864

bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1499386
gecko-commit: 631545ef79251ea54347ebcb76420b7c1c9ba333
gecko-integration-branch: autoland
gecko-reviewers: heycam

dbaron added a commit to dbaron/css-supports-functions that referenced this issue Oct 17, 2018

moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Oct 17, 2018

Bug 1499386 - Implement @supports selector() syntax. r=heycam
This implements the selector(<complex-selector>) syntax for @supports.

See w3c/csswg-drafts#3207 for explainer and
discussion.

Probably would should wait for that to be sorted out to land this, or maybe we
should put it behind a pref to get the code landed and change our
implementation if the discussion there leads to a change.

Differential Revision: https://phabricator.services.mozilla.com/D8864

--HG--
extra : moz-landing-system : lando

moz-wptsync-bot added a commit to web-platform-tests/wpt that referenced this issue Oct 18, 2018

Implement @supports selector() syntax.
This implements the selector(<complex-selector>) syntax for @supports.

See w3c/csswg-drafts#3207 for explainer and
discussion.

Probably would should wait for that to be sorted out to land this, or maybe we
should put it behind a pref to get the code landed and change our
implementation if the discussion there leads to a change.

Differential Revision: https://phabricator.services.mozilla.com/D8864

bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1499386
gecko-commit: 631545ef79251ea54347ebcb76420b7c1c9ba333
gecko-integration-branch: autoland
gecko-reviewers: heycam

jamienicol pushed a commit to jamienicol/gecko that referenced this issue Oct 18, 2018

Bug 1499386 - Implement @supports selector() syntax. r=heycam
This implements the selector(<complex-selector>) syntax for @supports.

See w3c/csswg-drafts#3207 for explainer and
discussion.

Probably would should wait for that to be sorted out to land this, or maybe we
should put it behind a pref to get the code landed and change our
implementation if the discussion there leads to a change.

Differential Revision: https://phabricator.services.mozilla.com/D8864

emilio added a commit to emilio/servo that referenced this issue Oct 18, 2018

Bug 1499386 - Implement @supports selector() syntax. r=heycam
This implements the selector(<complex-selector>) syntax for @supports.

See w3c/csswg-drafts#3207 for explainer and
discussion.

Probably would should wait for that to be sorted out to land this, or maybe we
should put it behind a pref to get the code landed and change our
implementation if the discussion there leads to a change.

Differential Revision: https://phabricator.services.mozilla.com/D8864

emilio added a commit to emilio/servo that referenced this issue Oct 18, 2018

style: Implement @supports selector() syntax.
This implements the selector(<complex-selector>) syntax for @supports.

See w3c/csswg-drafts#3207 for explainer and
discussion.

Probably would should wait for that to be sorted out to land this, or maybe we
should put it behind a pref to get the code landed and change our
implementation if the discussion there leads to a change.

Differential Revision: https://phabricator.services.mozilla.com/D8864
@css-meeting-bot

This comment has been minimized.

Copy link
Member

commented Oct 23, 2018

The CSS Working Group just discussed Selector feature query function for selectors.

The full IRC log of that discussion <mstange> Topic: Selector feature query function for selectors
<Rossen> github: https://github.com//issues/3207
<mstange> dbaron: When we discussed @supports back w hen we originally did it, one of the things we talked about that we maybe want to have support for more than querying for values
<mstange> dbaron: There may be more important use cases
<mstange> dbaron: Next addition would be testing for selectors
<mstange> dbaron: If you have three comma-separated selectors, the entire rule is supposed to get dropped if any of tehm is unrecognized.
<mstange> dbaron: This is painful because you don't get good negation operations.
<mstange> ... It has also come up recently when looking at scrollbar styling.
<mstange> ... @supports is useless for existing scrollbar styling use cases
<mstange> ... because some of them use selectors
<mstange> ... We all agree on what the syntax of testing for selectors should be, which is, it should be a function called selector.
<mstange> ... We want to allow combinators.
<mstange> ... There are currently some quirks related to ::-webkit pseudo elements
<mstange> ... There is a quirk that makes all ::-webkit pseudo elements not invalidate the selector
<mstange> ... We do not want to carry over this quirk to @supports selector
<mstange> heycam: There is an open question about namespace testing
<myles_> https://bugs.webkit.org/show_bug.cgi?id=189089
<mstange> dbaron: This turns out to be a bug in existing @supports because we didn't define it for content: attr(?)
<mstange> ... We should figure out how it interacts with @namespace prefix declarations
<mstange> TabAtkins: I'm fine with not having them
<mstange> ... I definitely do not want to look at namespace, should either fail or pass always
<mstange> fantasai: I agree
<mstange> dbaron: I would lean towards saying the always succeed and act as they always match the namespace
<mstange> emilio: I would like to argue for the opposite, we sohuld actually look at the namespaces in the stylesheet
<mstange> emilio: If you are testing for a selector that you actually use inside your @supports rule, that's what you want.
<mstange> ... It also doesn't require any special cases in the implementation.
<mstange> Bert: Isn't that the point, to ask whether you support "this type of selector", not "this particular selector"?
<dbaron> s/Bert/plinss/
<mstange> emilio: I would argue that if it's an unknown namespace, you should not go into the @supports rule
<mstange> emilio: Invalid namespaces are invalid, they drop the whole rule
<mstange> emilio: just doing syntactic checking is inconsistent with other DOM APIs that throw on invalid selectors
<mstange> emilio: Like .matches
<mstange> TabAtkins: Can we make them always invalid?
<mstange> emilio: I'd prefer that over making them always valid
<mstange> dbaron: There's a risk with newly-supported selectors in the future
<mstange> emilio: Please don't introduce a special case
<mstange> TabAtkins: The matches function always ignores namespaces, because it always throws when there's a namespace
<mstange> emilio: because there's no stylesheet
<mstange> fantasai: There's a rule in the matches spec that talks about namespaces, but it doesn't make it invalid
<mstange> dbaron: The other thing about the selector functions is that at some point the drafts of those functions had a namespace argument that got dropped.
<mstange> heycam: With CSS prefixes on the DOM node, no namespace prefixes are going to succeed except * or |
<mstange> TabAtkins: That same behavior seems fine to have for @supports
<mstange> fantasai: That doesn't make sense
<mstange> fantasai: I want to check whether I support a selector. Any selector that I'm using in my stylesheet, I should be able to put it into @supports
<mstange> emilio: I agree.
<mstange> fantasai: Which is not what TabAtkins is saying.
<mstange> fantasai: .supports would still return "yes I support namespaces"
<mstange> ... it's not about "Does querySelector" support this
<mstange> fantasai: We're checking things at the syntactic level
<mstange> fantasai: I'd be ok with checking the namespace whether it resolves
<mstange> emilio: I would prefer to look at the namespace map, if it's around
<mstange> emilio: Then we don't conditionally need to make all namespaces valid in some cases.
<mstange> emilio: The rules in @supports should be the same rules as for regular parsing.
<mstange> TabAtkins: What do you think about changing the regular parsing rule of "bad namespaces" kill the rule?
<mstange> futhark: I tend to agree for regular namespaces. If we're not checking namespaces, I prefer that we actually allow namespaces.
<mstange> emilio: So either check the namespace map as normal, or always succeed.
<mstange> dbaron: We need another resolution first, which is to create level 4 of CSS conditional rules
<mstange> ... unless we want to put this in level 3
<mstange> Resolved: Create CSS conditional rules level 4
<mstange> Resolved: Accept selector feature functions for selector support in @supports, accepting a single complex selector as an argument.
<mstange> dbaron: Do we want a resolution or two about the namespace thing?
<heycam> the namespace prefix issue is https://github.com//issues/3220
<mstange> fantasai: For the namespace we've resolved that they're not always invalid.
<mstange> Resolved: Namespaces are either always valid or valid when they're declared.
@jonjohnjohnson

This comment has been minimized.

Copy link

commented Nov 7, 2018

I know we are talking about syntax for a feature query, and a lot has already been brought up, but wanted to make sure it was addressed that previously the concept of a "selector" query was mentioned to match a selector against the current state of the document.

In #112 (comment) @tabatkins said...

@fantasai So if we pretend there's a selector() function that is true if something on the page matches that selector, I think you'd write:

@when selector(body.toc-inline) or (media(width < 28em) and not selector(body.toc-sidebar)) {
/* inline ToC styling /
} @else {
/
sidebar ToC styling */
}

Figured it worth mentioning, even if some other syntax like query() could be better.

Edit - I know this is unrelated apart from possible naming/syntax similarities that should be kept in mind.

@tabatkins

This comment has been minimized.

Copy link
Member

commented Nov 7, 2018

Yeah, that's a completely unrelated proposal.

@astearns astearns removed the Agenda+ F2F label Nov 13, 2018

@astearns

This comment has been minimized.

Copy link
Member

commented Nov 13, 2018

From the IRC log above:

RESOLVED: Create CSS conditional rules level 4
RESOLVED: Accept selector feature functions for selector support in @supports, accepting a single complex selector as an argument.
RESOLVED: Namespaces are either always valid or valid when they're declared.

@ExE-Boss

This comment has been minimized.

Copy link
Contributor

commented Jan 1, 2019

So, what’s the progress on writing a spec for this?

I’m asking because Mozilla wants to ship this in bug 1513643.

@emilio

This comment has been minimized.

Copy link
Collaborator

commented Jan 2, 2019

We're not shipping it without writing the spec.

emilio added a commit to emilio/csswg-drafts that referenced this issue Mar 28, 2019

dbaron added a commit to dbaron/csswg-drafts that referenced this issue Mar 29, 2019

[css-conditional-3][css-conditional-4] Create a css-conditional-4 dra…
…ft, and dispose of the features in css-conditional-3 marked for moving to level 4.

There were two commented-out features in css-conditional-3 marked as
being deferred to level 4.  These are removed from the draft, but NOT
added in css-conditional-4, because:

- the `@import` `supports()` syntax is already in
  https://drafts.csswg.org/css-cascade-4/#at-ruledef-import

- the addition of an `@document` rule is probably no longer desirable
  given the discussion and removal in
  https://bugzilla.mozilla.org/show_bug.cgi?id=1035091 which was the
  only implementation.

Also correct a few bits of metadata in css-conditional-3.

This is being done as part of the resolution in
w3c#3207 (comment)

dbaron added a commit that referenced this issue Mar 29, 2019

[css-conditional-3][css-conditional-4] Create a css-conditional-4 dra…
…ft, and dispose of the features in css-conditional-3 marked for moving to level 4. (#3777)

There were two commented-out features in css-conditional-3 marked as
being deferred to level 4.  These are removed from the draft, but NOT
added in css-conditional-4, because:

- the `@import` `supports()` syntax is already in
  https://drafts.csswg.org/css-cascade-4/#at-ruledef-import

- the addition of an `@document` rule is probably no longer desirable
  given the discussion and removal in
  https://bugzilla.mozilla.org/show_bug.cgi?id=1035091 which was the
  only implementation.

Also correct a few bits of metadata in css-conditional-3.

This is being done as part of the resolution in
#3207 (comment)

emilio added a commit to emilio/csswg-drafts that referenced this issue Mar 31, 2019

@dbaron dbaron closed this in #3774 Apr 12, 2019

dbaron added a commit that referenced this issue Apr 12, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.