Thu, 11 Oct 2012 23:43:33 -0700
[css3-conditional] Correct Tab's edits for functional notations in @supports to match the discussion on www-style (summarized in <https://lists.w3.org/Archives/Member/w3c-css-wg/2012OctDec/0040.html>
1 <!DOCTYPE html public '-//W3C//DTD HTML 4.01//EN'
2 'http://www.w3.org/TR/html4/strict.dtd'>
3 <html lang="en">
4 <head profile="http://www.w3.org/2006/03/hcard">
5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
6 <title>CSS Conditional Rules Module Level 3</title>
7 <link rel="stylesheet" type="text/css" href="../default.css">
8 <link rel="stylesheet" type="text/css"
9 href="http://www.w3.org/StyleSheets/TR/W3C-[STATUS].css">
10 </head>
12 <div class="head">
13 <!--logo-->
15 <h1>CSS Conditional Rules Module Level 3</h1>
17 <h2 class="no-num no-toc">[LONGSTATUS] [DATE]</h2>
18 <dl>
19 <dt>This version:
20 <dd><a href="[VERSION]">
21 http://www.w3.org/TR/[YEAR]/ED-css3-conditional-[CDATE]/</a>
23 <dt>Latest version:
24 <dd><a href="http://www.w3.org/TR/[SHORTNAME]/">http://www.w3.org/TR/[SHORTNAME]/</a>
26 <dt>Editor's draft:
27 <dd><a href="http://dev.w3.org/csswg/[SHORTNAME]/">http://dev.w3.org/csswg/[SHORTNAME]/</a>
29 <dt>Previous version:
30 <dd><a href="http://www.w3.org/TR/2012/WD-css3-conditional-20120911/">http://www.w3.org/TR/2012/WD-css3-conditional-20120911/</a></dd>
32 <dt>Editors:
33 <dd class=vcard><a class=fn href="http://dbaron.org/">L. David Baron</a>,
34 <a class=org href="http://www.mozilla.org/">Mozilla</a>
36 <dt>Issues list:
37 <dd>Maintained in document (only editor's draft is current)
39 <dt>Feedback:
41 <dd><a
42 href="http://lists.w3.org/Archives/Public/www-style/">www-style@w3.org</a>
43 with subject line “<kbd>[[SHORTNAME]] <var>… message topic
44 …</var></kbd>”
46 <dt>Test suite:
47 <dd><a href="https://test.csswg.org/shepherd/search/spec/css3-conditional/">submitted tests</a>; no built test suite yet
49 </dl>
51 <!--copyright-->
53 <hr title="Separator for header">
54 </div>
56 <h2 class="no-num no-toc" id="abstract">Abstract</h2>
58 <p>CSS is a language for describing the rendering of structured documents
59 (such as HTML and XML) on screen, on paper, in speech, etc. This module
60 contains the features of CSS for conditional processing of parts of
61 style sheets, conditioned on capabilities of the processor or the
62 document the style sheet is being applied to.
63 It includes and extends the functionality of CSS level 2 [[!CSS21]],
64 which builds on CSS level 1 [[CSS1]].
65 The main extensions compared to level 2 are
66 allowing nesting of certain at-rules inside '@media',
67 and the addition of the '@supports'
68 rule for conditional processing.
70 <h2 class="no-num no-toc" id="status">Status of this document</h2>
72 <!--status-->
74 <p>The following features are at risk:
75 <ul>
76 <li>The inclusion of '@font-face' rules and
77 '@keyframes' rules as allowed within all of the @-rules in
78 this specification is at risk, though only because of the relative
79 rates of advancement of specifications. If this specification is able
80 to advance faster than one or both of the specifications defining
81 those rules, then the inclusion of those rules will move from this
82 specification to the specification defining those rules.</li>
84 <li>The addition of support for @-rules inside of conditional grouping
85 rules is at risk; if interoperable implementations are not found, it
86 may be removed to advance the other features in this specification to
87 Proposed Recommendation.</li>
89 <li>The '@supports' rule is at risk; if interoperable
90 implementations are not found, it may be removed to advance the other
91 features in this specification to Proposed Recommendation.</li>
92 </ul>
94 <!--
96 Things to go in level 4:
98 * Create some way to put these new conditional things on an @import.
99 * The @document rule (commented out, down below).
101 -->
103 <h2 class="no-num no-toc" id="contents">Table of contents</h2>
105 <!--toc-->
107 <h2 id="introduction">Introduction</h2>
109 <h3 id="context">Background</h3>
111 <p><em>This section is not normative.</em>
113 <p>[[!CSS21]] defines one type of conditional group rule, the
114 '@media' rule, and allows only rulesets (not other @-rules)
115 inside of it. The '@media' rule provides the ability to
116 have media-specific style sheets, which is also provided by style
117 sheet linking features such as '@import' and
118 <code class="html"><link></code>. The restrictions on the contents of
119 '@media' rules made them less useful; they have forced authors
120 using CSS features involving @-rules in media-specific style sheets to
121 use separate style sheets for each medium.</p>
123 <p>This specification extends the rules for the contents of
124 conditional group rules to allow other @-rules, which enables authors
125 to combine CSS features involving @-rules with media specific style
126 sheets within a single style sheet.</p>
128 <p>This specification also defines an additional type of conditional
129 group rule, '@supports', to
130 address author and user requirements.</p>
132 <p>The '@supports' rule allows CSS to be conditioned on
133 implementation support for CSS properties and values. This rule makes
134 it much easier for authors to use new CSS features and provide good
135 fallback for implementations that do not support those features. This
136 is particularly important for CSS features that provide new layout
137 mechanisms, and for other cases where a set of related styles needs to
138 be conditioned on property support.</p>
140 <h3 id="placement">Module Interactions</h3>
142 <p>This module replaces and extends the '@media' rule
143 feature defined in [[!CSS21]] section <var>7.2.1</var> and
144 incorporates the modifications previously made non-normatively by
145 [[!MEDIAQ]] section <var>1</var>.</p>
147 <p>Its current definition depends on @-rules defined in [[!CSS3-FONTS]]
148 and [[!CSS3-ANIMATIONS]], but that dependency is only on the
149 assumption that those modules will advance ahead of this one. If this
150 module advances faster, then the dependency will be reversed.</p>
152 <h3 id="conventions">Document Conventions</h3>
154 <p>Conformance requirements are expressed with a combination of
155 descriptive assertions and RFC 2119 terminology. The key words “MUST”,
156 “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”,
157 “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this
158 document are to be interpreted as described in RFC 2119.
159 However, for readability, these words do not appear in all uppercase
160 letters in this specification.
162 <p>All of the text of this specification is normative except sections
163 explicitly marked as non-normative, examples, and notes. [[!RFC2119]]</p>
165 <p>Examples in this specification are introduced with the words “for example”
166 or are set apart from the normative text with
167 <code class="html">class="example"</code>, like this:
169 <div class="example">
170 <p>This is an example of an informative example.</p>
171 </div>
173 <p>Informative notes begin with the word “Note” and are set apart from the
174 normative text with <code class="html">class="note"</code>, like this:
176 <p class="note">Note, this is an informative note.</p>
178 <h2 id="processing">Processing of conditional group rules</h2>
180 <p>This specification defines some CSS @-rules, called <dfn>conditional
181 group rules</dfn>, that associate a condition with a group of other
182 CSS rules. These different rules allow testing different types of
183 conditions, but share common behavior for how their contents are used
184 when the condition is true and when the condition is false.</p>
186 <div class="example">
187 <p>For example, this rule:</p>
188 <pre>@media print {
189 #navigation { display: none }
190 }</pre>
191 <p>causes a particular CSS rule (making elements with ID "navigation" be
192 display:none) apply only when the style sheet is used for a print
193 medium.
194 </div>
196 <p>Each conditional group rule has a condition, which at any time
197 evaluates to true or false. When the condition is true, CSS processors
198 <strong>must</strong> apply the rules inside the group rule as though
199 they were at the group rule's location; when the condition is false, CSS
200 processors <strong>must not</strong> apply any of rules inside the group
201 rule. The current state of the condition does not affect the CSS object
202 model, in which the contents of the group rule always remain within the
203 group rule.</p>
205 <p>This means that when multiple conditional group rules are nested,
206 a rule inside of both of them applies only when all of the rules'
207 conditions are true.</p>
209 <div class="example">For example, with this set of nested rules:
210 <pre>@media print { // rule (1)
211 #navigation { display: none }
212 @media (max-width: 12cm) { // rule (2)
213 .note { float: none }
214 }
215 }</pre>
216 the condition of the rule marked (1) is true for print media, and the
217 condition of the rule marked (2) is true when the width of the display
218 area (which for print media is the page box) is less than or equal to
219 12cm. Thus the rule ''#navigation { display: none }'' applies
220 whenever this style sheet is applied to print media, and the rule
221 ''.note { float: none }'' is applied only when the style sheet
222 is applied to print media <em>and</em> the width of the page box is less
223 than or equal to 12 centimeters.</div>
225 <p>When the condition for a conditional group rule changes, CSS
226 processors <strong>must</strong> reflect that the rules now apply or no
227 longer apply, except for properties whose definitions define effects of
228 computed values that persist past the lifetime of that value (such as
229 for some properties in [[CSS3-TRANSITIONS]] and
230 [[!CSS3-ANIMATIONS]]).</p>
232 <h2 id="contents-of">Contents of conditional group rules</h2>
234 <p>The syntax of each conditional group rule consists of some syntax
235 specific to the type of rule followed by a <dfn>group rule body</dfn>,
236 which is a block (pair of braces) containing a sequence of rules.</p>
238 <p>A group rule body is allowed to contain rulesets and any @-rules that
239 are allowed at the top level of a style sheet before and after a
240 ruleset. This means that @-rules that must occur at the beginning of
241 the style sheet (such as '@charset', '@import',
242 and '@namespace' rules) are not allowed inside of conditional group
243 rules. Conditional group rules can be nested.</p>
245 <p>In terms of the grammar, this specification defines the following
246 productions for use in the grammar of conditional group rules:</p>
248 <pre>nested_statement
249 : ruleset | media | page | font_face_rule | keyframes_rule |
250 supports_rule
251 ;
253 group_rule_body
254 : '{' S* nested_statement* '}' S*
255 ;</pre>
256 <p>
257 in which all the productions are defined in that grammar with the
258 exception of <code>font_face_rule</code>
259 defined in [[!CSS3-FONTS]], <code>keyframes_rule</code> defined in
260 [[!CSS3-ANIMATIONS]], and <code>media</code> and <code>supports_rule</code>
261 defined in this specification.</p>
263 <p>In general, future CSS specifications that add new @-rules that are
264 not forbidden to occur after some other types of rules should modify
265 this <code>nested_statement</code> production to keep the grammar
266 accurate.</p>
268 <p>Style sheets <strong>must not</strong> use rules other than the allowed ones inside
269 conditional group rules.</p>
271 <p>CSS processors <strong>must</strong> ignore rules that are not
272 allowed within a group rule, and <strong>must</strong> handle invalid
273 rules inside of group rules as described in <a
274 href="http://www.w3.org/TR/CSS21/syndata.html#parsing-errors">section
275 4.2 (Rules for handling parsing errors)</a>, <a
276 href="http://www.w3.org/TR/CSS21/syndata.html#at-rules">section 4.1.5
277 (At-rules)</a>, and <a
278 href="http://www.w3.org/TR/CSS21/syndata.html#rule-sets">section 4.1.7
279 (Rule sets, declaration blocks, and selectors)</a> of [[!CSS21]].</p>
281 <h2 id="use">Placement of conditional group rules</h2>
283 <p>Conditional group rules are allowed at the top-level of a style
284 sheet, and inside other conditional group rules. CSS processors
285 <strong>must</strong> process such rules as <a
286 href="#processing">described above</a>.</p>
288 <p>Any rules that are not allowed after a ruleset (e.g., ''@charset'',
289 ''@import'', or ''@namespace'' rules) are also not allowed after a
290 conditional group rule. Therefore, style sheets <strong>must
291 not</strong> place such rules after a conditional group rules, and CSS
292 processors <strong>must</strong> ignore such rules.</p>
294 <h2 id="at-media">Media-specific style sheets: the '@media' rule</h2>
296 <p>The <dfn>'@media' rule</dfn> is a conditional group rule whose
297 condition is a media query. It consists of the at-keyword
298 '@media' followed by a (possibly empty) media query list (as
299 defined in [[!MEDIAQ]]), followed by a group rule body. The condition
300 of the rule is the result of the media query.</p>
302 <div class="example">
303 <p>This '@media' rule:</p>
304 <pre>@media print, (max-width: 600px) {
305 #extra_navigation { display: none }
306 }</pre>
307 <p>has the condition ''print, (max-width: 600px)'', which is
308 true for print media and for devices whose width is at most 600px. When
309 either of these is true, the condition of the rule is true, and the rule
310 ''#extra_navigation { display: none }'' is applied.
311 </div>
313 <p>In terms of the grammar, this specification extends the
314 <code>media</code> production in the
315 <a href="http://www.w3.org/TR/CSS21/grammar.html">Grammar of CSS 2.1</a>
316 ([[!CSS21]], Appendix G) into:
317 <pre>media
318 : MEDIA_SYM S* media_query_list group_rule_body
319 ;</pre>
320 <p>where the <code>group_rule_body</code> production is defined in this
321 specification, the <code>media_query_list</code> production is defined
322 in [[!MEDIAQ]], and the others are defined in the <a
323 href="http://www.w3.org/TR/CSS21/grammar.html">Grammar of CSS 2.1</a>
324 ([[!CSS21]], Appendix G).
326 <h2 id="at-supports">Feature queries: the '@supports' rule</h2>
328 <p>The <dfn>'@supports' rule</dfn> is a conditional group
329 rule whose condition tests whether the user agent supports CSS
330 property:value pairs. Authors can use it to write style sheets that use
331 new features when available but degrade gracefully when those features
332 are not supported. CSS has existing mechanisms for graceful
333 degradation, such as ignoring unsupported properties or values, but
334 these are not always sufficient when large groups of styles need to be
335 tied to the support for certain features, as is the case for use of new
336 layout system features.</p>
338 <p>The syntax of the condition in the '@supports' rule is
339 slightly more complicated than for the other conditional group rules
340 (though has some similarities to media queries) since:</p>
341 <ul>
342 <li>negation is needed so that the new-feature styles and the fallback
343 styles can be separated (within the forward-compatible grammar's rules
344 for the syntax of @-rules), and not required to override each other</li>
345 <li>conjunction (and) is needed so that multiple required features can
346 be tested</li>
347 <li>disjunction (or) is needed when there are multiple alternative
348 features for a set of styles, particularly when some of those
349 alternatives are vendor-prefixed properties or values</li>
350 </ul>
352 <p>Therefore, the syntax of the '@supports' rule allows
353 testing for property:value pairs, and arbitrary conjunctions (and),
354 disjunctions (or), and negations (not) of them.</p>
356 <p>This extends the lexical scanner in the
357 <a href="http://www.w3.org/TR/CSS21/grammar.html">Grammar of CSS 2.1</a>
358 ([[!CSS21]], Appendix G) by adding:
359 <pre>
360 @{S}{U}{P}{P}{O}{R}{T}{S} {return SUPPORTS_SYM;}
361 {O}{R} {return OR;}
362 </pre>
363 <p>and the grammar by adding</p>
364 <pre><dfn>supports_rule</dfn>
365 : SUPPORTS_SYM S* supports_condition group_rule_body
366 ;
368 <dfn>supports_condition</dfn>
369 : supports_negation | supports_conjunction | supports_disjunction |
370 supports_condition_in_parens
371 ;
373 <dfn>supports_condition_in_parens</dfn>
374 : ( '(' S* supports_condition ')' S* ) | supports_declaration_condition
375 ;
377 <dfn>supports_negation</dfn>
378 : NOT S* supports_condition_in_parens
379 ;
381 <dfn>supports_conjunction</dfn>
382 : supports_condition_in_parens ( AND S* supports_condition_in_parens )+
383 ;
385 <dfn>supports_disjunction</dfn>
386 : supports_condition_in_parens ( OR S* supports_condition_in_parens )+
387 ;
389 <dfn>supports_declaration_condition</dfn>
390 : '(' S* core_declaration ')' S* | FUNCTION S* [any|unused]* ')'
391 ;</pre>
392 <p>in which <code>core_declaration</code> is the production
393 <code>declaration</code> in the core syntax of CSS defined in <a
394 href="http://www.w3.org/TR/CSS21/syndata.html#tokenization">section
395 4.1.1 (Tokenization)</a> of [[!CSS21]],
396 and the <code>AND</code> and <code>NOT</code> tokens are defined in
397 the Media Queries specification [[!MEDIAQ]].</p>
399 <p>Any ''@supports'' rule that does not parse according to the grammar
400 above is invalid. Style sheets <strong>must not</strong> use such a
401 rule and processors <strong>must</strong> ignore such a rule.</p>
403 <p class="note">Note that this means that declarations that meet the
404 forward-compatible syntax for declarations are permitted (and support
405 for them is then tested by the ''@supports'' rule), but declarations
406 that do not meet the forward-compatible syntax for declarations cause
407 the entire ''@supports'' rule to be ignored.</p>
409 <p>Each of these grammar terms is associated with a boolean result, as
410 follows:</p>
411 <dl>
412 <dt>supports_condition</dt>
413 <dd>
414 The result is the result of the single child term.
415 </dd>
417 <dt>supports_condition_in_parens</dt>
418 <dd>
419 The result is the result of the single <code>supports_condition</code>
420 or <code>supports_declaration_condition</code> child term.
421 </dd>
423 <dt>supports_negation</dt>
424 <dd>
425 The result is the <em>negation</em> of the result of the
426 <code>supports_condition_in_parens</code> child term.
427 </dd>
429 <dt>supports_conjunction</dt>
430 <dd>
431 The result is true if the result of <em>all</em> of the
432 <code>supports_condition_in_parens</code> child terms is true;
433 otherwise it is false.
434 </dd>
436 <dt>supports_disjunction</dt>
437 <dd>
438 The result is true if the result of <em>any</em> of the
439 <code>supports_condition_in_parens</code> child terms is true;
440 otherwise it is false.
441 </dd>
443 <dt>supports_declaration_condition</dt>
444 <dd>
445 The result is false if this corresponds to a functional notation;
446 otherwise, the result is whether the CSS processor <a
447 href="#support-definition">supports</a> the declaration
448 within the parentheses.
449 <span class="note">Note that future levels may define functions that can evaluate to true.</span>
450 </dd>
451 </dl>
453 <p>The condition of the '@supports' rule is the result of the
454 <code>supports_condition</code> term that is a child of the
455 <code>supports_rule</code> term.</p>
457 <div class="example">
458 <p>For example, the following rule</p>
459 <pre>@supports ( display: flexbox ) {
460 body, #navigation, #content { display: flexbox; }
461 #navigation { background: blue; color: white; }
462 #article { background: white; color: black; }
463 }</pre>
464 <p>applies the rules inside the '@supports' rule only when
465 ''display: flexbox'' is supported.</p>
466 </div>
468 <div class="example">
469 <p>The following example shows an additional '@supports' rule that can
470 be used to provide an alternative for when ''display: flexbox'' is not
471 supported:</p>
472 <pre>@supports not ( display: flexbox ) {
473 body { width: 100%; height: 100%; background: white; color: black; }
474 #navigation { width: 25%; }
475 #article { width: 75%; }
476 }</pre>
477 <p>Note that the 'width' declarations may be harmful to the
478 flexbox-based layout, so it is important that they be present only in
479 the non-flexbox styles.</p>
480 </div>
482 <div class="example">
483 <p>The following example checks for support for the 'box-shadow'
484 property, including checking for support for vendor-prefixed versions of
485 it. When the support is present, it specifies both 'box-shadow' (with
486 the prefixed versions) and 'color' in a way what would cause the text to
487 become invisible were 'box-shadow' not supported.</p>
488 <pre>@supports ( box-shadow: 2px 2px 2px black ) or
489 ( -moz-box-shadow: 2px 2px 2px black ) or
490 ( -webkit-box-shadow: 2px 2px 2px black ) or
491 ( -o-box-shadow: 2px 2px 2px black ) {
492 .outline {
493 color: white;
494 -moz-box-shadow: 2px 2px 2px black;
495 -webkit-box-shadow: 2px 2px 2px black;
496 -o-box-shadow: 2px 2px 2px black;
497 box-shadow: 2px 2px 2px black; /* unprefixed last */
498 }
499 }</pre></div>
501 <p>To avoid confusion between ''and'' and ''or'', the syntax requires
502 that both ''and'' and ''or'' be specified explicitly (rather than, say,
503 using commas or spaces for one of them). Likewise, to avoid confusion
504 caused by precedence rules, the syntax does not allow ''and'', ''or'',
505 and ''not'' operators to be mixed without a layer of parentheses.</p>
507 <div class="example">
508 <p>For example, the following rule is not valid:
509 <pre class="illegal">@supports (transition-property: color) or
510 (animation-name: foo) and
511 (transform: rotate(10deg)) {
512 // ...
513 }</pre>
514 <p>Instead, authors must write one of the following:</p>
515 <pre>@supports ((transition-property: color) or
516 (animation-name: foo)) and
517 (transform: rotate(10deg)) {
518 // ...
519 }</pre>
520 <pre>@supports (transition-property: color) or
521 ((animation-name: foo) and
522 (transform: rotate(10deg))) {
523 // ...
524 }</pre>
525 </div>
527 <p>The declaration being tested must always occur within parentheses,
528 when it is the only thing in the expression.<p>
530 <div class="example">
531 <p>For example, the following rule is not valid:
532 <pre class="illegal">@supports display: flexbox {
533 // ...
534 }</pre>
535 <p>Instead, authors must write:</p>
536 <pre>@supports (display: flexbox) {
537 // ...
538 }</pre>
539 </div>
541 <p>The syntax allows extra parentheses when they are not needed. This
542 flexibility is sometimes useful for authors (for example, when
543 commenting out parts of an expression) and may also be useful for
544 authoring tools.</p>
546 <div class="example">
547 <p>For example, authors may write:</p>
548 <pre>@supports ((display: flexbox)) {
549 // ...
550 }</pre>
551 </div>
553 <p>A trailing ''!important'' on a declaration being tested is allowed,
554 though it won't change the validity of the declaration.
556 <div class="example">
557 <p>For example, the following rule is valid:
558 <pre>@supports (display: flexbox !important) {
559 // ...
560 }</pre>
561 </div>
563 <h3 id="support-definition">Definition of support</h3>
565 <p>For forward-compatibility,
566 <a href="http://www.w3.org/TR/CSS21/syndata.html#declaration">section 4.1.8
567 (Declarations and properties)</a> of [[!CSS21]]
568 defines rules for handling invalid properties and values.
569 CSS processors that
570 do not implement or partially implement a specification
571 <strong>must</strong> treat any part of a value that they
572 do not implement, or
573 do not have a usable level of support for,
574 as invalid according to this rule
575 for handling invalid properties and values,
576 and therefore <strong>must</strong> discard the declaration as a parse error.</p>
578 <p>A CSS processor is considered to <dfn id="dfn-support">support</dfn>
579 a declaration (consisting of a property and value) if it accepts that
580 declaration (rather than discarding it as a parse error).
581 If a processor does not implement, with a usable level of support,
582 the value given,
583 then it <strong>must not</strong>
584 accept the declaration or claim support for it.</p>
586 <p>These rules (and the equivalence between them) allow
587 authors to use fallback (either in the [[CSS1]] sense of declarations
588 that are overridden by later declarations or with the new capabilities
589 provided by the ''@supports'' rule in this specification) that works
590 correctly for the features implemented. This applies especially to
591 compound values; implementations must implement all parts of the value
592 in order to consider the declaration supported, either inside a ruleset
593 or in the declaration condition of an ''@supports'' rule.</p>
595 <!--
596 <h2 id="at-document">Document queries: the '@document' rule</h2>
598 <p>The <dfn>'@document' rule</dfn> is a conditional group
599 rule whose condition depends on the
600 <a href="#url-of-doc">URL of the document being styled</a>.
601 This allows style sheets, particularly user style sheets, to have styles
602 that only apply to a set of pages rather than to all pages using the
603 style sheet.</p>
605 <p class="issue">Given that this @-rule is intended primarily for user
606 style sheets, what should this specification say about its use in author
607 style sheets? Should it be forbidden? Should use instead be
608 discouraged? Or should this specification remain neutral on the
609 topic, since there are valid uses in author style sheets?</p>
611 <p id="url-of-doc">The <dfn>URL of the document being styled</dfn> is
612 the URI at which the document is located, excluding any fragment
613 identifiers. (This means, for example, that HTTP redirects have been
614 followed.) If the styles are being applied inside a complete document
615 embedded into the presentation of another (e.g., [[HTML5]]'s <code
616 class="html">iframe</code>, <code class="html">object</code>, or <code
617 class="html">img</code> elements), the relevant URI is that of the
618 frame, not of its container. However, if content from other documents
619 is mixed in via mechanisms that mix content from one document into
620 another (e.g., [[SVG11]]'s <code>use</code> element), then the
621 address of the container document is used.</p>
623 <p class="note">Note: In [[HTML5]], this is the
624 <a href="http://dev.w3.org/html5/spec/dom.html#documents">document's address</a>
625 of a document in a
626 <a href="http://dev.w3.org/html5/spec/browsers.html#browsing-context">browsing context</a>.</p>
628 <div class="issue">What form of normalization is done on URLs and domains
629 before matching? In particular, this specification needs to describe:
630 <ul>
631 <li>what form is used for the <a href="#url-of-doc">URL of the document
632 being styled</a> (and what has been normalized in that form)</li>
633 <li>what normalization (if any) happens to the argument of each of the match
634 functions before the comparison that they describe and</li>
635 <li>whether the
636 comparison algorithm used is string comparison or some other URL
637 comparison algorithm.</li></ul></div>
639 <p>The '@document' rule's condition is written as a
640 comma-separated list of <dfn>URL matching functions</dfn>, and the
641 condition evaluates to true whenever any one of those functions
642 evaluates to true. The following URL matching functions are
643 permitted:</p>
645 <dl>
646 <dt><dfn id="url-exact" title="url()|URL matching functions::exact"><url></dfn></dt>
648 <dd>
649 <p>The 'url()' function is the <dfn>exact url matching
650 function</dfn>. It evaluates to true whenever the <a
651 href="#url-of-doc">URL of the document being styled</a> is exactly
652 the URL given.</p>
654 <p class="Note">The 'url()' function, since it is a core syntax
655 element in CSS, is allowed (subject to different character
656 limitations and thus escaping requirements) to contain an unquoted
657 value (in addition to the string values that are allowed as
658 arguments for all four functions).</p>
660 <div class="example">
661 <p>For example, this rule:</p>
662 <pre>@document url("http://www.w3.org/Style/CSS/") {
663 #summary { background: yellow; color: black}
664 }</pre>
665 <p>styles the <code class="html">summary</code> element on the page
666 <code>http://www.w3.org/Style/CSS/</code>, but not on any other
667 pages.</p>
668 </div>
669 </dd>
671 <dt><dfn id="url-prefix" title="url-prefix()|URL matching functions::prefix">url-prefix(<string>)</dfn></dt>
673 <dd>
674 <p>The 'url-prefix()' function is the <dfn>url prefix
675 matching function</dfn>. It evaluates to true whenever the
676 <a href="#url-of-doc">URL of the document being styled</a>
677 has the argument to the function as an
678 initial substring (which is true when the two strings are equal).
679 When the argument is the empty string, it evaluates to true for all
680 documents.</p>
681 <div class="example">
682 <p>For example, this rule:</p>
683 <pre>@document url-prefix("http://www.w3.org/Style/CSS/") {
684 #summary { background: yellow; color: black}
685 }</pre>
686 <p>styles the <code class="html">summary</code> element on the page
687 <code>http://www.w3.org/Style/CSS/</code> and on the page
688 <code>http://www.w3.org/Style/CSS/Test</code>, but it does not
689 affect the page <code>http://www.w3.org/</code> or the page
690 <code>http://www.example.com/Style/CSS/</code>.</p>
691 </div>
692 </dd>
694 <dt><dfn id="url-domain" title="domain()|URL matching functions::domain">domain(<string>)</dfn></dt>
696 <dd>
697 <p>The 'domain()' function is the <dfn>domain
698 matching function</dfn>. It evaluates to true whenever
699 the <a href="#url-of-doc">URL of the document being styled</a>
700 has a host subcomponent (as defined in [[!URI]])
701 and that host subcomponent is exactly the argument to the
702 'domain()' function or a final substring of the host
703 component is a period (U+002E) immediately followed by the argument
704 to the 'domain()' function.</p>
705 <div class="example">
706 <p>For example, this rule:</p>
707 <pre>@document domain("w3.org") {
708 body { font-size: 16px ! important }
709 }</pre>
710 <p>changes the font size of the body element for pages such as
711 <code>http://www.w3.org/Style/CSS/</code> and
712 <code>http://w3.org/Style/CSS/</code> and
713 <code>http://lists.w3.org/Archives/Public/www-style/</code>
714 but it does not affect the page
715 <code>http://www.example.com/Style/CSS/</code>.</p>
716 </div>
717 </dd>
719 <dt><dfn id="url-regexp" title="regexp()|URL matching functions::regular expression">regexp(<string>)</dfn></dt>
721 <dd>
722 <p>The contents of the <string> argument <strong>must</strong>
723 match the JavaScript <code>Pattern</code> production
724 ([[!ECMA-262-5.1]], section 15.10.1). However,
725 failing to do so is not a CSS syntax error and does not trigger any
726 error handling for CSS syntax errors.</p>
728 <p>The ''regexp()'' function evaluates to true whenever the string
729 argument compiled as a JavaScript regular expression with the
730 <code>global</code>, <code>ignoreCase</code> and
731 <code>multiline</code> flags <em>disabled</em>
732 (see [[!ECMA-262-5.1]], sections 15.10.7.2 through 15.10.7.4)
733 compiles successfully and the resulting regular expression matches
734 the entirety of the
735 <a href="#url-of-doc">URL of the document being styled</a>.</p>
737 <p class="note">Note that regular expression must match the entire
738 URL, not just a part of it.</p>
740 <p class="note">Note that this definition intentionally matches the
741 behavior of the <a
742 href="http://dev.w3.org/html5/spec/common-input-element-attributes.html#attr-input-pattern"><code class="html">pattern</code>
743 attribute</a> on the <code class="html">input</code> element
744 in [[HTML5]].</p>
746 <div class="example">
747 <p>For example, this rule:</p>
748 <pre>@document regexp("http://www.w3.org/TR/\\d{4}/[^/]*-CSS2-\\d{8}/") {
749 body { font-size: 20px ! important }
750 }</pre>
751 <p>changes the font size of the body element for pages such as
752 <code>http://www.w3.org/TR/2011/PR-CSS2-20110412/</code>.</p>
753 <p class="note">Note that the backslashes in the regular
754 expression require CSS escaping as ''\\''.</p>
755 </div>
756 </dd>
758 </dl>
760 <p>Implementations <strong>must</strong> treat any unknown URL matching
761 functions as a syntax error, and thus ignore the '@document' rule.
762 <span class="issue">Should we instead have more complicated error
763 handling rules to make forward-compatibility work differently, or is
764 this rule the best solution for such future expansion anyway?</span></p>
766 <div class="issue">This syntax doesn't offer any ability to do negations,
767 which has been requested in <a
768 href="https://bugzilla.mozilla.org/show_bug.cgi?id=349813">Mozilla bug
769 349813</a>. Use cases that people have wanted negations for
770 include:
771 <ul>
772 <li>User style sheets that want a particular rule in general, but know
773 that that rule does more harm than good on specific sites.</li>
774 <li>Authors who have a rule that they want to apply to most of their
775 pages, but wish to make a few exceptions for.</li>
776 </ul>
777 </div>
779 <p>This extends the lexical scanner in the
780 <a href="http://www.w3.org/TR/CSS21/grammar.html">Grammar of CSS 2.1</a>
781 ([[!CSS21]], Appendix G) by adding:
782 <pre>@{D}{O}{C}{U}{M}{E}{N}{T} {return DOCUMENT_SYM;}</pre>
783 <p>and the grammar by adding</p>
784 <pre>document_rule
785 : DOCUMENT_SYM S+ url_match_fn ( "," S* url_match_fn )* group_rule_body
786 ;
788 url_match_fn
789 : (URI | FUNCTION S* STRING S* ')' ) S*
790 ;</pre>
791 -->
794 <h2 id="apis">APIs</h2>
796 <h3 id='extentions-to-cssrule-interface'>
797 Extensions to the <code>CSSRule</code> interface</h3>
799 <p>The <code>CSSRule</code> interface is extended as follows:
801 <pre class='idl'>partial interface CSSRule {
802 const unsigned short SUPPORTS_RULE = 12;
803 <!--
804 const unsigned short DOCUMENT_RULE = 13;
805 -->
806 }</pre>
809 <h3 id='the-cssgroupingrule-interface'>
810 The <code>CSSGroupingRule</code> interface</h3>
812 <p>The <dfn><code>CSSGroupingRule</code></dfn> interface represents an at-rule that contains other rules nested inside itself.
814 <pre class='idl'>interface CSSGroupingRule : CSSRule {
815 readonly attribute CSSRuleList cssRules;
816 unsigned long insertRule (DOMString rule, unsigned long index);
817 void deleteRule (unsigned long index);
818 }</pre>
820 <dl class='idl-attributes'>
821 <dt><code>cssRules</code> of type <code>CSSRuleList</code>, readonly
822 <dd>The <code>cssRules</code> attribute must return a <code>CSSRuleList</code>
823 object for the list of CSS rules nested inside the grouping rule.
824 </dl>
826 <dl class='idl-methods'>
827 <dt><code>insertRule(DOMString rule, unsigned long index)</code>, returns
828 <code>unsigned long</code>
829 <dd>The <code>insertRule</code> operation must insert a CSS rule <var>rule</var>
830 into the CSS rule list returned by <code>cssRules</code> at <var>index</var>.
832 <dt><code>deleteRule (unsigned long index)</code>, return <code>void</code>
833 <dd>The <code>deleteRule</code> operation must remove a CSS rule from the
834 CSS rule list returned by <code>cssRules</code> at <var>index</var>.
835 </dl>
838 <h3 id="the-cssconditionrule-interface">
839 The <code>CSSConditionRule</code> interface</h3>
841 <p>The <dfn><code>CSSConditionRule</code></dfn> interface represents all the "conditional" at-rules,
842 which consist of a condition and a statement block.
844 <pre class='idl'>interface CSSConditionRule : CSSGroupingRule {
845 attribute DOMString conditionText;
846 }</pre>
848 <dl class='idl-attributes'>
850 <dt><code>conditionText</code> of type <code>DOMString</code>
851 <dd>
852 <p>The <code>conditionText</code> attribute represents
853 the condition of the rule.
854 Since what this condition does
855 varies between the derived interfaces of <code>CSSConditionRule</code>,
856 those derived interfaces
857 may specify different behavior for this attribute
858 (see, for example, <code>CSSMediaRule</code> below).
859 In the absence of such rule-specific behavior,
860 the following rules apply:</p>
862 <p>The <code>conditionText</code> attribute, on getting, must return
863 the result of serializing the associated condition.
865 <p>On setting the <code>conditionText</code> attribute these steps
866 must be run:
868 <ol>
869 <li>Trim the given value of white space.
870 <li>If the given value matches the grammar of the
871 appropriate condition production for the given rule,
872 replace the associated CSS condition with the given value.
873 <li>Otherwise, do nothing.
874 </ol>
875 </dl>
878 <h3 id="the-cssmediarule-interface">
879 The <code>CSSMediaRule</code> interface</h3>
881 <p>The <dfn><code>CSSMediaRule</code></dfn> interface represents a ''@media'' rule:
883 <pre class='idl'>interface CSSMediaRule : CSSConditionRule {
884 readonly attribute MediaList media;
885 }</pre>
887 <dl class='idl-attributes'>
888 <dt><code>media</code> of type <code>MediaList</code>, readonly
889 <dd>The <code>media</code> attribute must return a <code>MediaList</code> object
890 for the list of media queries specified with the ''@media'' rule.
892 <dt><code>conditionText</code> of type <code>DOMString</code>
893 <dd>The <code>conditionText</code> attribute (defined on the <code>CSSConditionRule</code> parent rule),
894 on getting, must return the value of <code>media.mediaText</code> on the rule.
896 <p>Setting the <code>conditionText</code> attribute
897 must set the <code>media.mediaText</code> attribute on the rule.
898 </dl>
901 <h3 id="the-csssupportsrule-interface">
902 The <code>CSSSupportsRule</code> interface</h3>
904 <p>The <dfn><code>CSSSupportsRule</code></dfn> interface represents a ''@supports'' rule.</p>
906 <pre class='idl'>interface CSSSupportsRule : CSSConditionRule {
907 }</pre>
909 <!--
910 <h3 id="the-cssdocumentrule-interface">
911 The <code>CSSDocumentRule</code> interface</h3>
913 <p>The <dfn><code>CSSDocumentRule</code></dfn> interface represents a ''@document'' rule.</p>
915 <pre class='idl'>interface CSSDocumentRule : CSSConditionRule {
916 }</pre>
917 -->
920 <h3 id='the-css-interface'>
921 The <code>CSS</code> interface, and the <code title=''>supports()</code> function</h3>
923 <p>The <dfn id='CSS-interface'><code>CSS</code></dfn> interface holds useful CSS-related functions that do not belong elsewhere.
925 <pre class='idl'>interface CSS {
926 boolean supports(DOMString property, DOMString value);
927 boolean supports(DOMString declaration);
928 }</pre>
930 <dl class='idl-methods'>
931 <dt><code>supports(DOMString property, DOMString value)</code>,
932 returns <code>boolean</code>
933 <dt><code>supports(DOMString conditionText)</code>,
934 returns <code>boolean</code>
935 <dd>
936 When the <code title=''>supports()</code> method is invoked with two arguments <var>property</var> and <var>value</var>,
937 it must return <code>true</code> if <var>property</var> is a literal match for the name of a CSS property that the UA supports,
938 and <var>value</var> would be successfully parsed as a supported value for that property.
939 Otherwise, it must return <code>false</code>.
941 <p>
942 When invoked with a single <var>conditionText</var> argument,
943 it must return <code>true</code> if <var>conditionText</var>,
944 when parsed and evaluated as a <code>supports_condition</code>,
945 would return true.
946 Otherwise, it must return <code>false</code>.
947 </dl>
950 <h2 class=no-num id="grammar">Grammar</h2>
952 <p>In order to allow these new @-rules in CSS style sheets, this
953 specification modifies the <code>stylesheet</code> production in the <a
954 href="http://www.w3.org/TR/CSS21/grammar.html">Appendix G</a> grammar of
955 [[!CSS21]] by replacing the <code>media</code> production defined in
956 [[!CSS21]] with the <code>media</code> production defined in this one,
957 and additionally inserting <code>| supports_rule</code>
958 alongside <code>ruleset | media | page</code>.</p>
961 <h2 id="conformance">Conformance</h2>
963 <h3 id="base-modules">Base Modules</h3>
965 <p>This specification defines conformance in terms of base modules,
966 which are modules that this specification builds on top of. The base
967 modules of this module are:</p>
969 <ul>
970 <li>[[!CSS21]]</li>
971 </ul>
973 <p>All of the conformance requirements of all base modules are
974 incorporated as conformance requirements of this module, except where
975 overridden by this module.</p>
977 <p>Additionally, all conformance requirements related to validity of
978 syntax in this module and all of its base modules are to be interpreted
979 as though all syntax in all of those modules is valid.</p>
981 <div class="example"><p>For example, this means that grammar presented
982 in modules other than [[!CSS21]] must obey the requirements that
983 [[!CSS21]] defines for the parsing of properties, and that requirements
984 for handling invalid syntax in [[!CSS21]] do not treat syntax added by
985 other modules as invalid.</p></div>
987 <p>Additionally, the set of valid syntax can be increased by the
988 conformance of a style sheet or processor to additional modules; use of
989 such syntax does not make a style sheet nonconformant and failure to
990 treat such syntax as invalid does not make a processor
991 nonconformant.</p>
993 <h3 id="conformance-classes">Conformance Classes</h3>
995 <p>Conformance to the CSS Conditional Rules Module is defined for three
996 conformance classes:
997 <dl>
998 <dt><dfn title="conformance::style sheet" id="conform-style-sheet">style sheet</dfn>
999 <dd>A <a href="http://www.w3.org/TR/CSS21/conform.html#style-sheet">CSS
1000 style sheet</a>.</dd>
1001 <dt><dfn title="conformance::processor" id="conform-processor">processor</dfn></dt>
1002 <dd>A tool that reads CSS style sheets: it may be a renderer or
1003 <a
1004 href="http://www.w3.org/TR/CSS21/conform.html#user-agent">user-agent</a>
1005 that interprets the semantics of a style sheet and renders
1006 documents that use style sheets, or it may be a validator that
1007 checks style sheets.</dd>
1008 <dt><dfn title="conformance::authoring tool" id="conform-authoring-tool">authoring tool</dfn></dt>
1009 <dd>A tool that writes a style sheet.</dd>
1010 </dl>
1012 <p>A style sheet is conformant to the CSS Conditional Rules Module
1013 if it meets all of the conformance requirements in the module that are
1014 described as requirements of style sheets.</p>
1016 <p>A processor is conformant to the CSS Conditional Rules Module if it
1017 meets all applicable conformance requirements in the module that are
1018 described as requirements of processors. In general, all requirements
1019 are applicable to renderers. Requirements concerning a part of CSS
1020 not performed by a processor are not applicable, e.g., requirements
1021 related to rendering are not applicable to a validator. The inability
1022 of a processor to correctly render a document due to limitations of
1023 the device does not make it non-conformant. (For example, a renderer
1024 is not required to render color on a monochrome monitor.)</p>
1026 <p>An authoring tool is conformant to the CSS Conditional Rules Module
1027 if it writes style sheets that conform to the module and (if it reads
1028 CSS) it is a conformant processor.</p>
1030 <h3 id="partial">
1031 Partial Implementations</h3>
1033 <p>So that authors can exploit the forward-compatible parsing rules to
1034 assign fallback values, CSS renderers <strong>must</strong>
1035 treat as invalid (and <a href="http://www.w3.org/TR/CSS21/conform.html#ignore">ignore
1036 as appropriate</a>) any at-rules, properties, property values, keywords,
1037 and other syntactic constructs for which they have no usable level of
1038 support. In particular, user agents <strong>must not</strong> selectively
1039 ignore unsupported component values and honor supported values in a single
1040 multi-value property declaration: if any value is considered invalid
1041 (as unsupported values must be), CSS requires that the entire declaration
1042 be ignored.</p>
1044 <h3 id="experimental">Experimental Implementations</h3>
1046 <p>To avoid clashes with future CSS features, the CSS specifications
1047 reserve a <a href="http://www.w3.org/TR/CSS21/syndata.html#vendor-keywords">prefixed
1048 syntax</a> for proprietary property and value extensions to CSS. The CSS
1049 Working Group recommends that experimental implementations of features in
1050 CSS Working Drafts also use vendor-prefixed property or value names. This
1051 avoids any incompatibilities with future changes in the draft. Once a
1052 specification reaches the Candidate Recommendation stage, implementors
1053 should implement the non-prefixed syntax for any feature they consider to
1054 be correctly implemented according to spec.</p>
1056 <h3 id="cr-exit-criteria">CR Exit Criteria</h3>
1058 <p>For this specification to be advanced to Proposed Recommendation,
1059 there must be at least two independent, interoperable implementations
1060 of each feature. Each feature may be implemented by a different set of
1061 products, there is no requirement that all features be implemented by
1062 a single product. For the purposes of this criterion, we define the
1063 following terms:
1065 <dl>
1066 <dt>independent <dd>each implementation must be developed by a
1067 different party and cannot share, reuse, or derive from code
1068 used by another qualifying implementation. Sections of code that
1069 have no bearing on the implementation of this specification are
1070 exempt from this requirement.
1072 <dt>interoperable <dd>passing the respective test case(s) in the
1073 official CSS test suite, or, if the implementation is not a Web
1074 browser, an equivalent test. Every relevant test in the test
1075 suite should have an equivalent test created if such a user
1076 agent (UA) is to be used to claim interoperability. In addition
1077 if such a UA is to be used to claim interoperability, then there
1078 must one or more additional UAs which can also pass those
1079 equivalent tests in the same way for the purpose of
1080 interoperability. The equivalent tests must be made publicly
1081 available for the purposes of peer review.
1083 <dt>implementation <dd>a user agent which:
1085 <ol class=inline>
1086 <li>implements the specification.
1088 <li>is available to the general public. The implementation may
1089 be a shipping product or other publicly available version
1090 (i.e., beta version, preview release, or “nightly build”).
1091 Non-shipping product releases must have implemented the
1092 feature(s) for a period of at least one month in order to
1093 demonstrate stability.
1095 <li>is not experimental (i.e., a version specifically designed
1096 to pass the test suite and is not intended for normal usage
1097 going forward).
1098 </ol>
1099 </dl>
1101 <p>The specification will remain Candidate Recommendation for at least
1102 six months.
1104 <h2 id="changes">
1105 Changes</h2>
1107 <p>The following (non-editorial) changes were made to this specification since the
1108 <a href="http://www.w3.org/TR/2012/WD-css3-conditional-20120911/">11 September 2012 Working Draft</a>:
1110 <ul>
1111 <li>Allow functional notation in ''@supports'' queries to be valid (to allow for future extensions),
1112 but treat such notations as always being false.
1113 <li>Corrected the grammar as follows:
1114 <pre>
1115 - : SUPPORTS_SYM S+ supports_condition group_rule_body
1116 + : SUPPORTS_SYM S* supports_condition group_rule_body
1117 </pre>
1118 <pre>
1119 - : (URI | FUNCTION) S*
1120 + : (URI | FUNCTION S* STRING S* ')' ) S*
1121 </pre>
1122 <li>Switched "and", "or", and "not" keywords to use appropriate productions rather than literals.
1123 </ul>
1125 <h2 class=no-num id="acknowledgments">Acknowledgments</h2>
1127 <p>
1128 Thanks to the ideas and feedback from
1129 Tab Atkins,
1130 <span lang="tr">Tantek Çelik</span>,
1131 Alex Danilo,
1132 Elika Etemad,
1133 Pascal Germroth,
1134 <span lang="de">Björn Höhrmann</span>,
1135 Paul Irish,
1136 Vitor Menezes,
1137 Alex Mogilevsky,
1138 Chris Moschini,
1139 Simon Sapin,
1140 Ben Ward,
1141 Zack Weinberg,
1142 Estelle Weyl,
1143 Boris Zbarsky,
1144 and all the rest of the <a href="http://lists.w3.org/Archives/Public/www-style/">www-style</a> community.
1146 </p>
1148 <h2 class=no-num id="references">References</h2>
1151 <h3 class="no-num" id="normative-references">Normative references</h3>
1152 <!--normative-->
1154 <h3 class="no-num" id="other-references">Other references</h3>
1155 <!--informative-->
1157 <h2 class="no-num" id="index">Index</h2>
1158 <!--index-->
1160 </body>
1161 </html>
1162 <!-- Keep this comment at the end of the file
1163 Local variables:
1164 mode: sgml
1165 sgml-declaration:"~/SGML/HTML4.decl"
1166 sgml-default-doctype-name:"html"
1167 sgml-minimize-attributes:t
1168 sgml-nofill-elements:("pre" "style" "br")
1169 sgml-live-element-indicator:t
1170 sgml-omittag:nil
1171 sgml-shorttag:nil
1172 sgml-namecase-general:t
1173 sgml-general-insert-case:lower
1174 sgml-always-quote-attributes:t
1175 sgml-indent-step:nil
1176 sgml-indent-data:t
1177 sgml-parent-document:nil
1178 sgml-exposed-tags:nil
1179 sgml-local-catalogs:nil
1180 sgml-local-ecat-files:nil
1181 End:
1182 -->