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