Title: CSS Conditional Rules Module Level 3 Group: csswg Shortname: css-conditional Level: 3 Status: ED Prepare for TR: no Date: 2022-01-13 Work Status: Testing Implementation Report: https://test.csswg.org/harness/results/css-conditional-3_dev/grouped/ Implementation Report: https://wpt.fyi/results/css/css-conditional?label=master&label=experimental&aligned WPT Path Prefix: css/css-conditional/ ED: https://drafts.csswg.org/css-conditional-3/ TR: https://www.w3.org/TR/css-conditional-3/ Previous Version: https://www.w3.org/TR/2022/CR-css-conditional-3-20220113/ Previous Version: https://www.w3.org/TR/2021/CRD-css-conditional-3-20211223/ Previous Version: https://www.w3.org/TR/2020/CR-css-conditional-3-20201208/ Previous Version: https://www.w3.org/TR/2013/CR-css3-conditional-20130404/ Test Suite: http://test.csswg.org/suites/css-conditional-3_dev/nightly-unstable/ Editor: L. David Baron, Mozilla https://www.mozilla.org/, https://dbaron.org/, w3cid 15393 Editor: Elika J. Etemad / fantasai, Invited Expert, http://fantasai.inkedblade.net/contact, w3cid 35400 Editor: Chris Lilley, W3C, https://svgees.us/, w3cid 1438 Abstract: This module contains the features of CSS for conditional processing of parts of style sheets, conditioned on capabilities of the processor or the document the style sheet is being applied to. It includes and extends the functionality of CSS level 2 [[!CSS21]], which builds on CSS level 1 [[CSS1]]. The main extensions compared to level 2 are allowing nesting of certain at-rules inside ''@media'', and the addition of the ''@supports'' rule for conditional processing. At Risk: The inclusion of @font-face rules and @keyframes rules as allowed within all of the @-rules in this specification is at risk, though only because of the relative rates of advancement of specifications. If this specification is able to advance faster than one or both of the specifications defining those rules, then the inclusion of those rules will move from this specification to the specification defining those rules. At Risk: The addition of support for @-rules inside of conditional grouping rules is at risk; if interoperable implementations are not found, it may be removed to advance the other features in this specification to Proposed Recommendation. Default Highlight: css
spec:css-color-4; type:property; text:color spec:html; type:element; text:link spec:css-namespaces-3; type:dfn; text:namespace prefix spec:css-namespaces-3; type:dfn; text:CSS qualified name
@media print { /* hide navigation controls when printing */ #navigation { display: none } }causes a particular CSS rule (making elements with ID “navigation” be display:none) apply only when the style sheet is used for a print medium.
@media print { /* rule (1) */ /* hide navigation controls when printing */ #navigation { display: none } @media (max-width: 12cm) { /* rule (2) */ /* keep notes in flow when printing to narrow pages */ .note { float: none } } }the condition of the rule marked (1) is true for print media, and the condition of the rule marked (2) is true when the width of the display area (which for print media is the page box) is less than or equal to 12cm. Thus the rule ''#navigation { display: none }'' applies whenever this style sheet is applied to print media, and the rule ''.note { float: none }'' is applied only when the style sheet is applied to print media and the width of the page box is less than or equal to 12 centimeters.
@namespace x url(http://www.w3.org/1999/xlink); @supports (content: attr(x|href)) { // do something }
@supports (content: attr(n|tooltip)) { // do something }The user agent will consult the namespace map to see whether a namespace url exists corresponding to the "n" prefix.
@media <It consists of the at-keyword ''@media'' followed by a (possibly empty) media query list (as defined in [[!MEDIAQUERIES-4]]), followed by a block containing arbitrary rules. The condition of the rule is the result of the media query.> { < > }
@media screen and (min-width: 35em), print and (min-width: 40em) { #section_navigation { float: left; width: 10em; } }has the condition ''screen and (min-width: 35em), print and (min-width: 40em)'', which is true for screen displays whose viewport is at least 35 times the initial font size and for print displays whose viewport is at least 40 times the initial font size. When either of these is true, the condition of the rule is true, and the rule ''#section_navigation { float: left; width: 10em; }'' is applied.
@supports <with <> { < > }
<supports-condition> = not <The above grammar is purposely very loose for forwards-compatibility reasons, since the <> | < > [ and < > ]* | < > [ or < > ]* <supports-in-parens> = ( < > ) | < > | < > <supports-feature> = < > <supports-decl> = ( < > )
@supports ( display: flex ) { body, #navigation, #content { display: flex; } #navigation { background: blue; color: white; } #article { background: white; color: black; } }applies the rules inside the ''@supports'' rule only when ''display: flex'' is supported.
@supports not ( display: flex ) { body { width: 100%; height: 100%; background: white; color: black; } #navigation { width: 25%; } #article { width: 75%; } }Note that the 'width' declarations may be harmful to the flex-based layout, so it is important that they be present only in the non-flex styles.
.noticebox { border: 1px solid black; padding: 1px; } @supports ( box-shadow: 0 0 2px black inset ) or ( -moz-box-shadow: 0 0 2px black inset ) or ( -webkit-box-shadow: 0 0 2px black inset ) or ( -o-box-shadow: 0 0 2px black inset ) { .noticebox { -moz-box-shadow: 0 0 2px black inset; -webkit-box-shadow: 0 0 2px black inset; -o-box-shadow: 0 0 2px black inset; box-shadow: 0 0 2px black inset; /* unprefixed last */ /* override the rule above the @supports rule */ border: none; padding: 2px; } }
@supports (transition-property: color) or (animation-name: foo) and (transform: rotate(10deg)) { /* ... */ }Instead, authors must write one of the following:
@supports ((transition-property: color) or (animation-name: foo)) and (transform: rotate(10deg)) { /* ... */ }
@supports (transition-property: color) or ((animation-name: foo) and (transform: rotate(10deg))) { /* ... */ }
@supports display: flex { /* ... */ }Instead, authors must write:
@supports (display: flex) { /* ... */ }
@supports ((display: flex)) { /* ... */ }
@supports (display: flex !important) { /* ... */ }
CSSRule
interfaceCSSRule
interface is extended as follows:
partial interface CSSRule { const unsigned short SUPPORTS_RULE = 12; };
CSSConditionRule
interface[Exposed=Window] interface CSSConditionRule : CSSGroupingRule { readonly attribute CSSOMString conditionText; };
conditionText
of type CSSOMString
conditionText
attribute represents
the condition of the rule.
Since what this condition does
varies between the derived interfaces of CSSConditionRule
,
those derived interfaces
may specify different behavior for this attribute
(see, for example, CSSMediaRule
below).
In the absence of such rule-specific behavior,
the following rules apply:
The conditionText
attribute, on getting, must return
the result of serializing the associated condition.
CSSMediaRule
interface[Exposed=Window] interface CSSMediaRule : CSSConditionRule { [SameObject, PutForwards=mediaText] readonly attribute MediaList media; };
media
of type {{MediaList}}, readonly
media
attribute must return a {{MediaList}} object
for the list of media queries specified with the ''@media'' at-rule.
conditionText
of type CSSOMString
(CSSMediaRule-specific definition for attribute on CSSConditionRule)
conditionText
attribute (defined on the CSSConditionRule
parent rule),
on getting, must return the value of media.mediaText
on the rule.
conditionText
attribute
must set the media.mediaText
attribute on the rule.
CSSSupportsRule
interface[Exposed=Window] interface CSSSupportsRule : CSSConditionRule { };
conditionText
of type CSSOMString
(CSSSupportsRule-specific definition for attribute on CSSConditionRule)
conditionText
attribute (defined on the CSSConditionRule
parent rule),
on getting, must return the condition that was specified,
without any logical simplifications,
so that the returned condition will evaluate to the same result
as the specified condition
in any conformant implementation of this specification
(including implementations that implement future extensions
allowed by the <CSS
namespace, and the supports()
functionpartial namespace CSS { boolean supports(CSSOMString property, CSSOMString value); boolean supports(CSSOMString conditionText); };
supports(CSSOMString property, CSSOMString value)
, returns boolean
true
.
2. Otherwise, if |property| is a [=custom property name string=],
return true
.
3. Otherwise, return false
.
Note: No CSS escape or whitespace processing is performed on the property name,
so CSS.supports(" width", "5px")
will return false
,
as " width" isn't the name of any property due to the leading space.
Note: ''!important'' flags are not part of property grammars,
and will cause |value| to parse as invalid,
just as they would in the value argument to ''element.style.setProperty()''.
supports(CSSOMString conditionText)
, returns boolean
true
.
2. Otherwise,
If |conditionText|,
wrapped in parentheses
and then [=CSS/parsed=] and evaluated as a <true
.
3. Otherwise, return false
.
All namespaces in the conditionText argument
are considered invalid,
just as they are in document.querySelector("a|b")
.
Conditional group rules are allowed wherever style rules are allowed (at the top-level of a style sheet,
and insideas well as within other conditional group rules). CSS processors must process such rules as described above. Any at-rules that are not allowed after a style rule (e.g., @charset , @import , or @namespace rules) are also not allowed after a conditional group rule. Therefore, style sheets must not place such rules after a conditional group rule, and CSS processors must ignore such rules., and are therefore invalid when so placed.
supports()
method
to imply parentheses for simple declarations,
for consistency with the @import rule’s supports() function.