-
Notifications
You must be signed in to change notification settings - Fork 659
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] Feature detection for descriptors #2463
Comments
I agree that being able to detect descriptor support is valuable. I would have thought it belongs in CSS Conditional. |
Yeah, it's Conditional - this is precisely why we took care to include arbitrary functional terms in the @supports grammar which resolve to unknown, so we can add more types of support-testing in the future. (Need to also be able to test for types, like if "1foo" is a |
Something like |
@tabatkins Did you mean to write: @supports descriptor(@font-face, font-display: block) { ... } |
Maybe. We have a clear syntax extension path if we want to, but why do we need to test if |
Yes, I did mean that.
Yeah, one could do that, but given that UAs will have explicit parsers for each value type for Typed OM purposes, we'll be able to expose that directly, if it makes one's intent clearer. |
Sure, but when you want to use a value, you're going to use it somewhere. And it is possible that the UA supports that value without supporting it where you planned to use it. For instance, a newer version of a property may accept % and length while the old one only took %. The browser you're in does not yet support the length version yet, but does support the new fancy length unit you want to use in places where it does support length. In that sense, while |
The |
It'd be nice to have this for @supports descriptor(@property, syntax: "<color>") { ... } |
Yeah, |
Especially in [css-properties-values-api] currently implemented by Chrome, |
Is it possible to do a CSS |
I like the I also wonder if there are any traps regarding some descriptors depending on other descriptors. For example, the following is hard to evaluate if we don't also know the
For syntax |
It's syntactically valid in either case, we would just invalidate the rule as a whole if |
Of course, but my point was that checking for parsing validity alone isn't enough to do what people (/ @yisibl) want for For example |
Hm, that's true. Validity of Editted to add: wait no that's not the case, it does check for known non-terminals. The problem is just that we don't support the |
Just want to mention my syntax suggestion from #5929 here: @supports (@page { size: 10cm; }) {
...
} That would work like the existing parsing checks for properties and selectors, so no new logic here. It only requires to extend the syntax of Sebastian |
We also need a way to query support for
Through the same general syntax. I like @SebastianZ's suggestion above and it does lend itself nicely to detection of Also there have been proposals about at-rules that would be nested inside other at-rules or regular CSS rules. We should take that into account when designing this syntax, so we don't need to add more ad hoc syntax in the future to cover these use cases. |
@bramus good point, yes they do. |
We can't test CSS properties without a value. So allowing to check descriptors without a value seems inconsistent. |
Yeah, was coming here to bring up that same point; I don't think we need or want this syntax: @supports (@font-face{ src; }) {
// yay webfonts
} I didn't think about nested at-rules, hm. That's in a weird middle ground; it's not as trivial as "do we support this at-rule" nor is it as hands-off as "does this successfully parse". Instead you have to maintain a somewhat more complex side-list of "do we support this at-rule inside of this other at-rule", which is precisely the sort of thing that can easily get out-of-date or be missed when updating things (especially for catch-alls like @media or @supports). I suspect we might want to leave this out, and just stick with asking for a single level of support. So in other words, I think we want to limit things to just:
|
I was also thinking about this. But should this be restricted to at-rules? We could check any block I guess @supports (:foo { bar: baz; }) Like |
We can't do naked testing of style rules; it's the same problem as Nesting, where the grammar of properties and style rules overlap. But yeah, testing for selectors and properties separately is fine. |
Thinking more about it, I am not feeling totally comfortable with introducing a syntax that only checks the at-rule's name. It definitely looks nicer that way but I fear it may let authors conclude that they can use the rule without limitations. Though it doesn't cover any info about its descriptors or its syntax. Authors don't win anything if they test for an at-rule that way but the descriptors or the syntax they use isn't supported. Sebastian |
Sure, they can test for an at-rule and miss a descriptor, but the same is true of existing property tests; you can easily test for a simple version of a property and fail to realize that the more complex version you're using in your actual styles isn't supported. That's a risk authors take when they're weighing the competing concerns of terseness/readability vs accuracy, and it's not something we need to work too hard to protect people from, imo. (Fun fact: an early proposal for @supports, way back when, worked by having no test in the prelude; instead you tagged individual properties in the contained styles with a !keyword, and it matched based on whether those properties parsed or not. No repetition at all, but what was being matched was a lot less clear up-front.) I think the trade-off of accuracy vs terseness in allowing just the at-rule name is reasonable here. Most of the time, the mere presence of the at-rule is a sufficient test. When there have been gradual upgrades to an at-rule's feature set and you need to discriminate between support levels, the full-fat version of the query is there for you, but I don't think we need to force that on everyone the rest of the time. For example, I do not want people to have to write out that full (Properties, on the other hand, change their value set pretty regularly, and are a lot shorter to write, so the trade-offs of requiring the full |
Then something like It seems a bit strange to mix both properties and at-rule blocks in naked |
Different blocks have different requirements - the child rules in @Keyframes use a different prelude syntax than style rules. Can't really be generic here. There's also the question of "why?" - what does putting an entire style rule into an @supports test achieve? If it's testing selectors, we already have |
For consistency: if we allow at-rules but not style rules, it will probably be confusing for authors. |
I don't think I agree? They're pretty different things. I suspect authors will be fine.
Apologies, I'm not sure what you're asking here. |
So you said "Different blocks have different requirements - the child rules in |
In that example it's not any sort of special thing. You just literally feed the entire contents of the query (everything between the parens) into the parser and see if there are any parsing errors. That's just fine! No special-casing required, just possibly adding a mode to your existing parser to flag parsing errors rather than just silently dropping them. This is very distinct from a special-case syntax for testing rule nesting. |
Quick note to everyone here: Be mindful to surround at-rules with backticks in discussions to avoid pinging people with that GitHub account name! Sebastian |
The CSS Working Group just discussed
The full IRC log of that discussion<emilio> topic: feature detection for descriptors<emilio> TabAtkins: seems reasonable to ask for this given we can do it for properties <emilio> ... as @rules grow you might want to be able to test for given descriptors <emilio> ... there's a suggestion that we add a new @supports query to test for descriptors <lea> github: https://github.com//issues/2463 <emilio> ... I'd describe the two that I think we should add <emilio> ... and lea has other ideas <emilio> ... I think we should test for general @-rule support <emilio> ... so "can you identify this rule at all" <emilio> ... the other one should be a more complex one for testing for a whole @rule <emilio> q+ <TabAtkins> @supports (@rule) {...} <TabAtkins> and @supports (@rule { desc: value; }) {...} <fantasai> TabAtkins was summarizing https://github.com//issues/2463#issuecomment-1015709662 right? <TabAtkins> yes <emilio> lea: I think the only additional thing I proposed is that we shouldn't have to add random descriptors to see if the browser supports particular descriptors or what not <emilio> ... so test for support for e.g. @Property or so <chris> q+ <TabAtkins> emilio: Regarding testing the whole rule <oriol> q+ <Rossen_> ack emilio <TabAtkins> emilio: It's a bit weird, because we don't track parse errors, we just drop <TabAtkins> emilio: We could od that potentially, but it goes against th eprinciple <TabAtkins> q+ <TabAtkins> emilio: I think it would be nicer to do somethign else, but not sure what else could be <TabAtkins> emilio: Don't have a generic idea for it <TabAtkins> emilio: Like would great for `font-face-descriptor(desc: value)` but then you'd need it for each <TabAtkins> emilio: Just scares me if it gets out of sync <emilio> chris: wanted to check where we are in nested at rules <Rossen_> ack chris <fantasai> emilio: Another related concern, some rules are related <fantasai> emilio: so if you parse an at-rule in an @supports block ... <fantasai> emilio: should we consider position in the style sheet? <Rossen_> ack oriol <emilio> ack oriol <emilio> oriol: it seems strange to me the including-the-whole-at-rule <emilio> ... because parens would accept a weird set of syntax <emilio> ... and this seems a bit inconsistent / confusing to authors to me <TabAtkins> (I'm fine with an `at-rule()` function, fwiw.) <emilio> ... because they might want to test for style rules <emilio> ... but we're not supporting that, so I'd prefer another function <emilio> ... or an option for testing general rules that could be an at-rule() or general rule <emilio> ... but mixing some but not all rules, and also property-declarations in parens would be a strange mix <Rossen_> ack TabAtkins <emilio> TabAtkins: emilio's point about the whole rule testing is a very reasonable point and I don't want to do this if it requires special cases <emilio> ... I'd like to instrument the existing parser if possible <fantasai> emilio: Even with instrumentation, it can still get out of sync <fantasai> emilio: e.g. someone forgets to propagate the error <fantasai> emilio: so even if set just a boolean that indicates parser error <fantasai> emilio: if don't set it at the right time, is a problem <fantasai> emilio: It wouldn't be a whole new parser, just concerned about sync <emilio> TabAtkins: connected to that, there's chris' question about nesting <emilio> ... if you have per-at-rule descriptor function then you don't get nested at-rules for free <emilio> ... the other question was about context <emilio> ... I'd say we should specify what the parsing context is for this <emilio> ... which would be the generic top-level stylesheet context, so @import would fail <emilio> ... and re oriol's point I'm totally fine with `at-rule()` or something if you think it's less fair <oriol> Yeah it think that's better <Rossen_> ack dbaron <emilio> dbaron: I think when I wrote the @supports proposal the way I had envisioned extending them is that we'd add new functions for other points where CSS drops things <emilio> ... so at the point where the CSS parser says "oh, that is invalid so we drop it as a unit", that seems sensible to add a function for <emilio> ... and I think it's a bit weird to put a whole rule inside @supports <TabAtkins> q+ <emilio> ... that said I think TabAtkins' argument about nesting is interesting, because the approach I was thinking of at the time doesn't allow you to test for such things <emilio> ... so I have mixed feelings about it <Rossen_> ack fantasai <emilio> fantasai: regarding the TabAtkins' generic top-level context I think that'd be confusing to authors, I think it'd be more understandable and useful to authors if we allowed both that or anything that's in the prelude, so that e.g. @import would count as supported <emilio> ... I think it'd be less confusing to authors <emilio> ... and I can see use cases for doing that if you want to do something conditional in whether some extended at-import syntax is supported <emilio> ... I also wanted to say about dbaron's comment that it would be better to have the nested syntax rather than having many functions <emilio> ... I'd prefer parenthesis rather than a function, I think it'd be a little bit cleaner and easier to type <emilio> q+ <TabAtkins> @supports at-rule(@foo) {...} and @supports at-rule(@foo, desc: value) {...} <emilio> ack TabAtkins <Rossen_> ack TabAtkins <emilio> TabAtkins: thanks dbaron for all that context. If we follow those premises we also avoid emilio's concerns. In that context perhaps we could do something like what I typed above in the chat <emilio> ... it doesn't address nesting right now but we can extend it if needed <fantasai> s/many functions/many custom functions per at-rule/ <emilio> ... we also don't and probably won't have many at-rules that are inconsistently nested <faceless> Surely @supports (@import) should always fail, as @import must be the first rule? So if you precede it with @supports, it's not valid? <miriam> q+ <fantasai> faceless, I don't think @supports queries should be sensitive to position <Rossen_> ack emilio <lea> faceless: is there a use case for @supports(@import)? Literally every browser supports @import, no? <fantasai> emilio: @supports(@import) { } and then not put an @import inside <TabAtkins> Not as a positive test, as a negative test. <fantasai> TabAtkins: My proposal is not parsing, just is this at-rule in your list of recognize at-rules <fantasai> emilio: fantasai it might be useful to test e.g. @supports(@import "" layer) or something <fantasai> emilio: though for layer you could check to @layer <fantasai> emilio: I think having a generic at-rule() function is better than having function per at-rule <fantasai> TabAtkins: The downside is it wouldn't allow testing the prelude of an at-rule <Rossen_> ack miriam <emilio> miriam: prelude seem important for several things like layers and container <fantasai> miriam: That was my question, because preludes seem important for many things, such as @layer and @container <emilio> ... so it seems odd to leave it <emilio> fantasai: I see that at-rule() as an improvement to having a function per at-rule <emilio> ... but I don't see how that is better than just dropping the whole css syntax <TabAtkins> If we wanted to add it, could have the form `at-rule(@foo prelude stuff)`; when there's >1 token there we test full prelude parsing <emilio> ... it'd cover handling the prelude / descriptors / nested at-rules / etc <emilio> ... so I don't understand why we'd go for the function rather than the proposal that was on the issue <emilio> TabAtkins: emilio and dbaron explained why that wasn't great <emilio> ... you'd need to detect whether there's a parse error somewhere in a rule needs intrumenting the parser <emilio> ... whether testing whether something is dropped entirely or not is easy and can be done with no possibility of missing things <Rossen_> q? <Rossen_> ack fantasai <emilio> ... because we definitely drop things that are invalid and is detectable, but detecting whether an inner descriptor failed to parse inside an at-rule requires special-casing <emilio> Rossen: does that answer your question elika? <emilio> fantasai: yes <TabAtkins> @supports at-rule(@foo) {...} and @supports at-rule(@foo, desc: value) {...} <emilio> TabAtkins: proposal is having the at-rule function with two syntax variants: `at-rule(@Keyword)` and `at-rule(@Keyword, descriptor)` <emilio> fantasai: not against that but I have a question about how do we extend to the prelude <emilio> TabAtkins: posted that up as well, we could have it drop the whole prelude in there or something <emilio> fantasai: but prelude might include commas <emilio> ... if you want something not in the prelude you're going to need a semi-colon <lea> what about descriptor values? at-rule(@Keyword, descriptor, value)? <emilio> TabAtkins: alright let's use semi-colons <fantasai> emilio: Meant to write descriptor:value <emilio> lea: would there be a way to test for @rule <name> or so? <emilio> TabAtkins: that's the prelude extension we were discussing above <TabAtkins> at-rule(@Keyword; desc:value) <emilio> dbaron: so to clarify you wouldn't extend it to put the whole at-rule inside right? <emilio> TabAtkins: right, or we just drop it and if we drop descriptors inside then it'd test true <emilio> ... I think we should resolve on the keyword and descriptor variants and we can extend to support the whole prelude <emilio> RESOLVED: Add an `at-rule` function with syntax `at-rule(@Keyword)` or `at-rule(@Keyword; descriptor: value)` |
@tabatkins Should this issue have a “Needs Edits” label? I looked into the specs and didn't find a mention of the Context: https://codepen.io/propjockey/pen/OJdJmya?editors=1100 — right now developers have to test for “features that co-exist” with the at-rule implementations in order to test the at-rule support. It would be awesome to have a better way to do this, and I think the sooner it would be possible to do so — the better, as more potential at-rules would get covered by this. |
Currently,
@supports
andCSS.supports
only supportproperty: value
pairs. The only way for web developers to detect support for a certain descriptor in an at-rule is to use JavaScript. For example:(from https://bugzilla.mozilla.org/show_bug.cgi?id=1296373#c6)
It would be good if CSS can test whether a user agent supports a
descriptor: value
pair.See also a related issue in Chromium: https://bugs.chromium.org/p/chromium/issues/detail?id=600137
Tagged as "unknown/future spec" for now, because I'm not sure if we should extend
@supports
(which is incss-conditional
), or develop a new mechanism for it.The text was updated successfully, but these errors were encountered: