Skip to content

Commit daeb7c3

Browse files
committed
[css-conditional-4] Add if/else per WG resolution, fix #112
1 parent 4cec4db commit daeb7c3

File tree

1 file changed

+176
-1
lines changed

1 file changed

+176
-1
lines changed

css-conditional-4/Overview.bs

+176-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ TR: https://www.w3.org/TR/css-conditional-4/
1111
Previous Version: https://www.w3.org/TR/2020/WD-css-conditional-4-20200303/
1212
Test Suite: http://test.csswg.org/suites/css-conditional-4_dev/nightly-unstable/
1313
Editor: L. David Baron, Mozilla https://www.mozilla.org/, https://dbaron.org/, w3cid 15393
14+
Editor: Elika J. Etemad / fantasai, Invited Expert, http://fantasai.inkedblade.net/contact, w3cid 35400
15+
Editor: Chris Lilley, W3C, https://svgees.us/, w3cid 1438
1416
Abstract: This module contains the features of CSS for conditional processing of parts of
1517
style sheets, conditioned on capabilities of the processor or the
1618
document the style sheet is being applied to. It includes and extends the
@@ -21,12 +23,45 @@ Abstract: This module contains the features of CSS for conditional processing of
2123
Default Highlight: css
2224
</pre>
2325

26+
<pre class="link-defaults">
27+
spec: css-conditional-3
28+
type: dfn; text: conditional group rule
29+
</pre>
30+
2431
<h2 id="introduction">Introduction</h2>
2532

2633
This is currently an early draft of the things that are <em>new</em> in level 4.
2734
The features in level 3 are still defined in [[css3-conditional]]
2835
and have not yet been copied here.
2936

37+
It adds extensions to the ''@supports'' rule
38+
to allow testing for supported selectors
39+
and supported font technologies.
40+
41+
It also adds generalized conditional rules
42+
and chained conditional rules.
43+
44+
It also adds an ''@if'' rule,
45+
which generalizes the concept of a conditional rule.
46+
Anything you can express in an existing conditional rule
47+
can be expressed in ''@if'',
48+
it just has to be wrapped in an appropriate function
49+
to declare what kind of condition it is.
50+
This allow authors to easily combine multiple types of queries,
51+
such as media queries and supports queries,
52+
in a single boolean expression.
53+
Without this,
54+
authors must rely on nesting separate conditional rules,
55+
which is harder to read and write,
56+
presupposes the conditions are to be conjoined with the "and" boolean relation
57+
(with no easy way to indicate anything else),
58+
and restricts their utility in the proposed <a>conditional rule chains</a>.
59+
60+
It also adds ''@else'' rules,
61+
which immediately follow conditional rules
62+
and automatically qualify their conditions as you'd expect,
63+
such that at <em>most one rule</em> in an <a>conditional rule chain</a> is chosen as active.
64+
3065
Issue: In the future, copy the contents of [[css3-conditional]] into this document.
3166

3267
<h2 id="at-supports-ext">Extensions to the ''@supports'' rule</h2>
@@ -69,6 +104,142 @@ when the text and layout processing engine ingesting
69104
this CSS text is capable of utilising the specified font-technology
70105
in layout and rendering.
71106

107+
<h2 id="if-rule">Generalized Conditional Rules: the ''@if'' rule</h2>
108+
109+
The <dfn>@if</dfn> at-rule is a <a>conditional group rule</a>
110+
that generalizes the individual <a>conditional group rules</a>
111+
such as ''@media'' and ''@supports''.
112+
It is defined as:
113+
114+
<pre class=prod>
115+
@if <<boolean-condition>> {
116+
<<stylesheet>>
117+
}
118+
</pre>
119+
120+
Where <<boolean-condition>> is a boolean algebra a la [[mediaqueries-4#mq-syntax]],
121+
but with ''media()'' and ''supports()'' functions as leaves.
122+
123+
Issue: Define "boolean algebra, with X as leaves" in a generic way in Conditional,
124+
so all the conditional rules can reference it directly,
125+
rather than having to redefine boolean algebra on their own.
126+
127+
The ''media()'' and ''supports()'' functions are defined as:
128+
129+
<pre class=prod>
130+
<dfn>media()</dfn> = media( [ <<mf-plain>> | <<mf-boolean>> | <<mf-range>> ] )
131+
<dfn>supports()</dfn> = supports( <<declaration>> )
132+
</pre>
133+
134+
A ''media()'' or ''supports()'' function is associated the boolean result
135+
that its contained condition is associated with.
136+
137+
<h2 id="else-rule">Chained Conditionals: the ''@else'' rule</h2>
138+
139+
Usually, <a>conditional group rules</a> are independent;
140+
each one has a separate condition
141+
evaluated without direct reference to any other rule,
142+
and decides whether or not to apply its contained rules
143+
based solely on its condition.
144+
145+
This is fine for simple conditions,
146+
but makes it difficult to write a collection of conditionals that are meant to be mutually exclusive;
147+
authors have to very carefully craft their conditions to not activate when the other rules are meant to,
148+
and make sure the collection of conditionals don't accidentally <em>all</em> exclude some situation
149+
which is then left unstyled.
150+
151+
The <dfn>@else</dfn> rule is a <a>conditional group rule</a>
152+
used to form <a>conditional rule chains</a>,
153+
which allow multiple conditional rules to be provided
154+
and guarantee that at most one of them will evaluate their condition as true.
155+
It is defined as:
156+
157+
<pre class=prod>
158+
@else <<boolean-condition>>? {
159+
<<stylesheet>>
160+
}
161+
</pre>
162+
163+
''@else'' is interpreted identically to ''@if''.
164+
If its <<boolean-condition>> is omitted,
165+
it's treated as having a condition that's always true.
166+
167+
A <dfn export>conditional rule chain</dfn> is a series of consecutive <a>conditional group rules</a>,
168+
starting with a <a>conditional group rule</a> other than ''@else'',
169+
followed by zero or more ''@else'' rules.
170+
There cannot be anything between the successive <a>conditional group rules</a>
171+
other than whitespace and/or comments;
172+
any other token "breaks" the chain.
173+
174+
Issue: Should we require that only the last ''@else'' in a chain can have an omitted condition?
175+
It's not uncommon for me, when debugging code,
176+
to short-circuit an if-else chain by setting one of them to "true";
177+
I presume that would be similarly useful in CSS?
178+
It's still pretty easy to see you've done something wrong if you omit the condition accidentally.
179+
180+
Within a <a>conditional rule chain</a>,
181+
the conditions of each <a>conditional group rule</a> are evaluated in order.
182+
If one of them is true,
183+
the conditions of all <em>following</em> <a>conditional group rules</a> in the chain must evaluate to false,
184+
regardless of what they contain.
185+
186+
An ''@else'' rule that is not part of a <a>conditional rule chain</a> is invalid and must be ignored.
187+
188+
<div class=example>
189+
For example, here's a (somewhat silly) conditional chain:
190+
191+
<pre class="lang-css">
192+
@if media(width >= 400px) and media(pointer: fine) and supports(display: flex) {
193+
/* A */
194+
} @else supports(caret-color: pink) and supports(background: double-rainbow()) {
195+
/* B */
196+
} @else {
197+
/* C */
198+
}
199+
</pre>
200+
201+
Exactly one of the preceding rules will be chosen,
202+
even though the second rule
203+
doesn't exclude large widths, fine points, or flexbox support,
204+
and the last rule
205+
doesn't specify anything at all.
206+
207+
To achieve the same result without <a>conditional rule chains</a>,
208+
you'd need to write:
209+
210+
<pre class="lang-css">
211+
@media (width >= 400px) and (pointer: fine) {
212+
@supports (display: flex) {
213+
/* A */
214+
}
215+
@supports not (display: flex) {
216+
@supports (caret-color: pink) and (background: double-rainbow()) {
217+
/* B */
218+
}
219+
@supports not ((caret-color: pink) and (background: double-rainbow())) {
220+
/* C */
221+
}
222+
}
223+
}
224+
@media not ((width >= 400px) and (pointer: fine)) {
225+
@supports (caret-color: pink) and (background: double-rainbow()) {
226+
/* B */
227+
}
228+
@supports not ((caret-color: pink) and (background: double-rainbow())) {
229+
/* C */
230+
}
231+
}
232+
</pre>
233+
234+
This is simultaneously impossible to read,
235+
requires significant duplication of both conditions and contents,
236+
and is <em>very</em> difficult to write correctly
237+
<!-- (I wrote it wrong <em>twice</em> while producing this example). -->
238+
If the conditions got any more complicated
239+
(which is not unusual in real-world content),
240+
the example would get <em>significantly</em> worse.
241+
</div>
242+
72243
<h2 class=no-num id="priv">Privacy Considerations</h2>
73244

74245
No Privacy issues have been raised against this document
@@ -79,6 +250,8 @@ No Security issues have been raised against this document
79250

80251
<h2 class=no-num id="acknowledgments">Acknowledgments</h2>
81252

253+
The @if and @else rules are based on a proposal by Tab Atkins.
254+
82255
<h2 id='changes' class='no-num'>
83256
Changes</h2>
84257

@@ -87,6 +260,8 @@ No Security issues have been raised against this document
87260
</h3>
88261

89262
<ul>
90-
<li>Extended supports feature to express font capabilities</li>
263+
<li>Added @if and @else per CSSWG resolution</li>
264+
<li>Extended @supports feature to express font capabilities</li>
265+
<li>Added two co-editors per CSSWG resolution</li>
91266
<li>Added Privacy and Security sections</li>
92267
</ul>

0 commit comments

Comments
 (0)