Skip to content

Commit e35a74c

Browse files
diekuskbabbitt
andauthored
Re-scopes at-rule (#1231)
* Adds security-privacy questionnaire * Update AtRuleFeatureDetection/security-privacy-questionnaire.md Co-authored-by: Kevin Babbitt <kbabbitt@microsoft.com> * Update AtRuleFeatureDetection/security-privacy-questionnaire.md Co-authored-by: Kevin Babbitt <kbabbitt@microsoft.com> * Update AtRuleFeatureDetection/security-privacy-questionnaire.md Co-authored-by: Kevin Babbitt <kbabbitt@microsoft.com> * Rescopes at-rule down to test to just `at-rule(@foo)` Removed use cases from the explainer. Detect whether an at-rule, with optional prelude and/or block, is supported based on this resolution: w3c/csswg-drafts#6966 (comment) Detect whether a given declaration is supported within an at-rule block based on the proposed @supports-condition w3c/csswg-drafts#12622 (comment) * Update explainer.md * Addresses TAG comments - Addresses TAG comments found [here](w3ctag/design-reviews#1176 (comment)) - moves previous capabilities to non-goals based on the new `@supports-condition` at-rule * Update explainer.md * Update explainer.md --------- Co-authored-by: Kevin Babbitt <kbabbitt@microsoft.com>
1 parent 9afa5af commit e35a74c

1 file changed

Lines changed: 11 additions & 153 deletions

File tree

AtRuleFeatureDetection/explainer.md

Lines changed: 11 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,18 @@ There have been many scenarios described that call for feature detection of at-r
5555

5656
Allow authors to feature-detect newly introduced at-rules.
5757

58-
Allow authors to feature-detect new enhancements to existing at-rules, such as:
59-
- New media query features and other additions to at-rule preludes
60-
- New descriptors that may be introduced to rules such as `@font-face`
61-
6258
At-rule feature detection should be available in all contexts where CSS allows conditioning based on support
6359
of a feature. This includes, but is not limited to,
6460
`@supports`, `CSS.supports()`, `@import ... supports()`, and `@when supports()`.
6561

6662
### Non-goals
6763

64+
- Allow authors to feature-detect new enhancements to existing at-rules, such as:
65+
- New media query features and other additions to at-rule preludes
66+
- New descriptors that may be introduced to rules such as `@font-face`
67+
- Detect non at-rules like `@charset`:
68+
69+
#### CSS `@charset`
6870
The CSS `@charset` rule, despite its appearance, is
6971
[not an at-rule](https://drafts.csswg.org/css-syntax/#charset-rule).
7072
Rather, `@charset` is a marker that can appear only as the first few bytes of a stylesheet file. It signals to
@@ -82,13 +84,16 @@ CSS is to use UTF-8.
8284

8385
Accordingly, this explainer does not propose making `@charset` feature-detectable using `at-rule()`.
8486

87+
#### Context Aware feature detection
88+
As [mentioned before](#detect-whether-an-at-rule-name-is-recognized-at-all), the `at-rule()` feature returns true if the at-rule name is recognised in any context. This introduces the risk of false positives. As per CSSWG resolutions [#12622](https://github.com/w3c/csswg-drafts/issues/12622) and [#6966](https://github.com/w3c/csswg-drafts/issues/6966#issuecomment-3205037703) the new `@supports-condition` at-rule is introduced as a way to define and name complex support queries, including the ones that need to account for context.
89+
8590
## Proposed Approach
8691

87-
The `at-rule()` function can be used for feature detection in the following ways:
92+
The `at-rule()` function can be used for feature detection in the following way:
8893

8994
### Detect whether an at-rule name is recognized at all
9095

91-
In its simplest form, the `at-rule()` function can be passed just an at-rule name.
96+
The `at-rule()` function can be passed just an at-rule name.
9297
The result is true if the implementation would recognize it as an at-rule in any context, false otherwise.
9398
This form is useful for detecting entire new features implemented as at-rules, including features such as
9499
[`@starting-style`](https://www.w3.org/TR/css-transitions-2/#defining-before-change-style)
@@ -116,153 +121,6 @@ that do not appear at top-level stylesheet context.
116121
}
117122
```
118123

119-
It may also be useful as a shorter alternative to the second form for feature-detecting at-rules that are only
120-
valid when nested inside another at-rule, such as
121-
[`@swash`](https://www.w3.org/TR/css-fonts/#font-feature-values-syntax)
122-
and other font feature value types within `@font-feature-values`.
123-
124-
```css
125-
@supports at-rule(@swash) {
126-
@font-feature-values Foo {
127-
@swash { pretty: 1; cool: 2; }
128-
}
129-
p {
130-
font-family: Foo;
131-
font-variant-alternates: swash(cool);
132-
}
133-
}
134-
@supports not(at-rule(@swash)) {
135-
/* Fall back to something else. */
136-
@font-face FooButNotAsCool {
137-
/* ... */
138-
}
139-
p {
140-
font-family: FooButNotAsCool;
141-
}
142-
}
143-
```
144-
145-
However, authors should consider the possibility of such an at-rule later becoming valid in a new and different
146-
context, which may result in a false positive. For example, one might write `@supports at-rule(@top-left)`
147-
intending to detect support for the `@top-left` rule nested within `@page`. But later, if a new feature comes
148-
along that implements a nested `@top-left` at-rule for a different purpose, the feature query would return true
149-
on implementations that *do* support this new feature but *do not* support `@page`.
150-
151-
### Detect whether an at-rule, with optional prelude and/or block, is supported
152-
153-
This form resembles existing use of feature detection in CSS. An at-rule block, including optional prelude
154-
and/or declaration block, is passed as the function parameter. If the at-rule block is accepted by the
155-
implementation *without relying on
156-
[forgiving catch-all grammar](#special-case-the-forgiving-grammar-of-media-queries)*,
157-
the support query returns true; otherwise it returns false.
158-
159-
This is useful for detecting new enhancements to existing at-rules. Often it is not necessary to pass the entire
160-
at-rule that the author intends to use; an abbreviated subset can be "close enough" to make the right decision.
161-
162-
```css
163-
/* Are style queries supported at all? */
164-
@supports at-rule(@container style(color: green)) {
165-
/* Yes - use them to emphasize green cards. */
166-
@container style(color: green) and not style(background-color: red) {
167-
.card {
168-
font-weight: bold;
169-
transform: scale(2);
170-
}
171-
}
172-
}
173-
```
174-
175-
The parsing test is performed as if the given at-rule block were the first and only content in a stylesheet.
176-
That allows for at-rules with positional requirements, such as `@import`, to be tested:
177-
178-
```css
179-
/* Import styles into a named layer. */
180-
/* If the implementation does not support layer(), this at-rule will be ignored. */
181-
@import "layered-styles.css" layer(my-layer);
182-
183-
/* If the implementation does not support layers, fall back to unlayered styles. */
184-
@import "unlayered-styles.css" supports(not(at-rule(@import "test.css" layer(test))));
185-
```
186-
187-
#### Special case: The forgiving grammar of media queries
188-
189-
"Forgiving catch-all grammar" refers to cases where it would be undesirable for an entire at-rule to be
190-
thrown away just because a small part of it is unrecognized. One example is in media queries:
191-
192-
```css
193-
@media (max-width: 800px and not(fancy-display)) {
194-
/* ... */
195-
}
196-
```
197-
198-
The implementation does not recognize the `fancy-display` media feature. But since the author is testing that
199-
the page is *not* on a fancy display, we still want the rules within the `@media` block to apply. The media query
200-
handles this by returning an "unknown" value for `fancy-display`, which gets treated as "false" for the purpose
201-
of evaluating the query.
202-
203-
Suppose an author instead wants to condition part of their stylesheet on whether an implementation recognizes
204-
`fancy-display` *at all*. Implementations that recognize `fancy-display`, and implementations that don't, both
205-
must at least parse the above media query. If feature detection were determined purely based on whether the
206-
at-rule parses successfully, it would not be possible to feature-detect support for `fancy-display`. The
207-
exception we carve out allows us to handle this situation: Implementations that recognize `fancy-display` will
208-
parse that feature name on their "known media features" path, and implementations that don't recognize it will
209-
parse it on their "forgiving catch-all" path.
210-
211-
```css
212-
/* This @supports query returns true if the implementation knows what a fancy-display is. */
213-
@supports at-rule(@media (fancy-display)) {
214-
215-
/* This @media query returns true if the user is actually using a fancy-display. */
216-
@media (max-width: 800px and fancy-display) {
217-
/* ... */
218-
}
219-
220-
/* This @media query returns true if the user is detectably not using a fancy-display. */
221-
@media (max-width: 800px and not(fancy-display)) {
222-
/* ... */
223-
}
224-
}
225-
```
226-
227-
### Detect whether a given declaration is supported within an at-rule block
228-
229-
This form allows testing support for descriptors or property declarations within a given at-rule.
230-
Given an at-rule name and a declaration, the support query returns true if the declaration parses within
231-
the at-rule's block, false otherwise.
232-
233-
```css
234-
@supports at-rule(@property; syntax: "<color>") {
235-
/* declare custom properties with color syntax */
236-
}
237-
238-
@supports at-rule(@position-try; box-shadow: 0px 0px) {
239-
/* declare rules that set different box-shadow locations for different position-areas */
240-
}
241-
```
242-
243-
Such tests could also be accomplished with the previous form, but this form allows authors to omit the prelude
244-
and/or required declarations that are not the subject of the test.
245-
For example, the `@font-face` rule requires `font-family` and `src` descriptors.
246-
An author who wants to feature detect support for `font-feature-settings` using the previous form would need
247-
to supply dummy values for `font-family` and `src` in order for the test block to parse successfully.
248-
The query would thus be quite verbose:
249-
250-
```css
251-
/* Testing as a full at-rule using the previous form */
252-
@supports at-rule(@font-face {font-family: test; src: local(test); font-feature-settings: "hwid"} ) {
253-
/* ... */
254-
}
255-
```
256-
257-
With this form, the author can simplify to:
258-
259-
```css
260-
/* Simpler query using this form */
261-
@supports at-rule(@font-face; font-feature-settings: "hwid") {
262-
/* ... */
263-
}
264-
```
265-
266124
## Accessibility, Privacy, and Security Considerations
267125

268126
No accessibility, privacy, or security considerations have been identified for this feature.

0 commit comments

Comments
 (0)