Skip to content

Commit 4fd47d8

Browse files
committed
[css-values-5] Define <boolean [test]> multiplier w3c#10457
1 parent 8932d2e commit 4fd47d8

File tree

2 files changed

+110
-97
lines changed

2 files changed

+110
-97
lines changed

css-values-4/Overview.bs

Lines changed: 1 addition & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ Component Value Types</h3>
147147
does not include the top-level <a lt=# grammar>comma-separated list multiplier</a>.
148148
(E.g. if a property named <code>pairing</code> is defined as <code>[ <<custom-ident>> <<integer>>? ]#</code>,
149149
then <code>&lt;\'pairing'></code> is equivalent to <code>[ <<custom-ident>> <<integer>>? ]</code>,
150-
not <code>[ <<custom-ident>> <<integer>>? ]#</code>.)\
150+
not <code>[ <<custom-ident>> <<integer>>? ]#</code>.)
151151

152152
<details class=note>
153153
<summary>Why remove the multiplier?</summary>
@@ -5371,102 +5371,6 @@ Appendix A: Recommended Minimum Ranges and Precision of Computed Values</h2>
53715371
</span>
53725372
-->
53735373

5374-
5375-
<!-- Big Text: bools -->
5376-
5377-
<h2 id="bools">
5378-
Boolean Expressions</h2>
5379-
5380-
In several contexts, CSS allows certain boolean tests
5381-
(things that can evaluate to true or false),
5382-
and allows them to be combined with the logical operators
5383-
AND, OR, and NOT to form more complicated boolean tests.
5384-
(For example, ''@media'' or ''@supports'' rules.)
5385-
5386-
All of these locations share a common grammatical structure,
5387-
with the only difference being what "base" boolean tests
5388-
are allowed,
5389-
and whether they use simple 2-value (true/false) boolean algebra,
5390-
or 3-value (true/false/unknown) Kleene logic.
5391-
5392-
For example, in ''@media'' only <<media-condition>>s are allowed,
5393-
with Kleene logic;
5394-
in ''@supports'' only <<supports-condition>>s are allowed,
5395-
with boolean logic.
5396-
5397-
As the overall structure of these grammars is identical
5398-
across the various usages of it,
5399-
and also complex enough to be non-trivial to reproduce
5400-
(and easy to accidentally do wrong),
5401-
this specification defines <<boolean>>,
5402-
a generic grammar for all such boolean tests.
5403-
5404-
<pre class=prod>
5405-
<dfn>&lt;boolean></dfn> = <<bool-not>> | <<bool-in-parens>> [ <<bool-and>>* | <<bool-or>>* ]
5406-
<dfn>&lt;boolean-without-or></dfn> = <<bool-not>> | <<bool-in-parens>> <<bool-and>>*
5407-
<dfn>&lt;bool-not></dfn> = not <<bool-in-parens>>
5408-
<dfn>&lt;bool-and></dfn> = and <<bool-in-parens>>
5409-
<dfn>&lt;bool-or></dfn> = or <<bool-in-parens>>
5410-
<dfn>&lt;bool-in-parens></dfn> = ( <<boolean>> ) | <<bool-test>> | <<general-enclosed>>
5411-
5412-
<dfn>&lt;general-enclosed></dfn> = [ <<function-token>> <<any-value>>? ) ] | [ ( <<any-value>>? ) ]
5413-
</pre>
5414-
5415-
Each specification using <<boolean>>
5416-
must define what things are valid as <dfn>&lt;bool-test></dfn> values
5417-
in that context,
5418-
and whether it uses 2-value or 3-value logic.
5419-
As well, <<bool-test>> values
5420-
<em>should</em> either be wrapped in parentheses
5421-
or be functions;
5422-
if a specification needs to express some conditions in a different way,
5423-
please contact the CSSWG for review.
5424-
5425-
: If using 2-value logic
5426-
::
5427-
* Every <<bool-test>> must be defined to evaluate to either true or false.
5428-
* <<general-enclosed>> evaluates to false.
5429-
* <<bool-in-parens>> evaluates to the value of its contained <<boolean>>, <<bool-test>>, or <<general-enclosed>>
5430-
* <<bool-not>> evaluates to true if its contained <<bool-in-parens>> is false,
5431-
and false otherwise.
5432-
* A <<boolean>> with only a <<bool-not>> or <<bool-in-parens>> evaluates to that.
5433-
* A <<boolean>> with multiple <<bool-in-parens>> connected with ''and''
5434-
evaluates to true if all of its <<bool-in-parens>> are true,
5435-
and false otherwise.
5436-
* A <<boolean>> with multiple <<bool-in-parens>> connected with ''or''
5437-
evaluates to true if any of its <<bool-in-parens>> are true,
5438-
and false otherwise.
5439-
5440-
: If using 3-value logic
5441-
::
5442-
* Every <<bool-test>> must be defined to evaluate to either true, false, or unknown.
5443-
* <<general-enclosed>> evaluates to unknown.
5444-
* <<bool-in-parens>> evaluates to the value of its contained <<boolean>>, <<bool-test>>, or <<general-enclosed>>
5445-
* <<bool-not>> evaluates to true if its contained <<bool-in-parens>> is false,
5446-
false if it's true,
5447-
and unknown if it's unknown.
5448-
* A <<boolean>> with only a <<bool-not>> or <<bool-in-parens>> evaluates to that.
5449-
* A <<boolean>> with multiple <<bool-in-parens>> connected with ''and''
5450-
evaluates to true if all of its <<bool-in-parens>> are true,
5451-
false if any of them are false,
5452-
and unknown otherwise
5453-
(at least one unknown, but no false).
5454-
* A <<boolean>> with multiple <<bool-in-parens>> connected with ''or''
5455-
evaluates to true if any of its <<bool-in-parens>> are true,
5456-
false if all of them are false,
5457-
and unknown otherwise
5458-
(at least one unknown, but no true).
5459-
* If a "top-level" <<boolean>> is unknown,
5460-
and the containing context uses 2-value logic
5461-
(or doesn't specify otherwise),
5462-
it instead evaluates to false.
5463-
5464-
Note: That is, unknown doesn't "escape" a 3-value expression,
5465-
similar to how NaN doesn't "escape" a [=top-level calculation=]).
5466-
5467-
5468-
5469-
54705374
<!-- Big Text: lists
54715375

54725376
█▌ ████ ███▌ █████▌ ███▌

css-values-5/Overview.bs

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,17 @@ Value Definition Syntax</h2>
7777

7878
See [[css-values-4#value-defs]].
7979

80+
Additionally,
81+
82+
<ol>
83+
<li value=5>Boolean combinations of a conditional notation.
84+
These are written using the <<boolean [ &lt;test&gt; ]>> notation,
85+
and represent recursive expressions of boolean logic
86+
using keywords and parentheses,
87+
applied to the type specified in brackets,
88+
e.g. <<boolean [ ( &lt;media-feature&gt; ) ]>> to express [=media queries=].
89+
</ol>
90+
8091
<h3 id=component-functions>
8192
Functional Notation Definitions</h3>
8293

@@ -201,6 +212,62 @@ Commas in Function Arguments</h4>
201212
Other contexts <em>may</em> define that they use [=non-strict comma-containing productions=],
202213
but it <em>should</em> be avoided unless necessary.
203214

215+
<h3 id=boolean>
216+
Boolean Expression Multiplier <<boolean>></h3>
217+
218+
Several contexts
219+
(such as ''@media'', ''@supports'', ''if()'', ...)
220+
specify conditions,
221+
and allow combining those conditions with boolean logic (and/or/not/grouping).
222+
Because they use the same non-trivial recursive syntax structure,
223+
the special <dfn><<boolean>></dfn> production represents this pattern generically.
224+
225+
The <<boolean>> notation wraps another value type in the square brackets within it,
226+
e.g. &lt;boolean [ &lt;test&gt; ]&gt;,
227+
and represents that value alone as well as
228+
boolean combinations of those values
229+
using the ''not'', ''and'', and ''or'' keywords
230+
and grouping parenthesis.
231+
It is formally equivalent to:
232+
233+
<xmp class=prod>
234+
<boolean [ <test> ]> = not <boolean-group> | <boolean-group>
235+
[ [ and <boolean-group> ]*
236+
| [ or <boolean-group> ]* ]
237+
238+
<boolean-group> = <test> | ( <boolean> ) | <general-enclosed>
239+
</xmp>
240+
241+
The <<boolean>> production represents a true, false, or unknown value,
242+
with top-level unknown values
243+
(those not directly nested inside the grammar of another <<boolean>>)
244+
resolving to false unless otherwise specified.
245+
Its value is resolved using 3-value Kleene logic;
246+
see [[#boolean-logic]] for details.
247+
248+
<div class=example>
249+
For example, the ''@container'' rule allows a wide variety of tests:
250+
including size queries, style queries, and scroll-state queries.
251+
All of these are arbitrarily combinable with boolean logic.
252+
Using <<boolean>>, the grammar for an ''@container'' query is:
253+
254+
<xmp class=prod>
255+
<container-query> = <boolean [ <cq-test> ]>
256+
<cq-test> = (<size-query>) | style( <style-query> ) | scroll-state( <scroll-state-query> )
257+
<size-query> = <boolean [ ( <size-feature> ) ]> | <size-feature>
258+
<style-query> = <boolean [ ( <style-feature> ) ]> | <style-feature>
259+
<scroll-state-query> = <boolean [ ( <scroll-state-feature> ) ]> | <scroll-state-feature>
260+
</xmp>
261+
</div>
262+
263+
The <<general-enclosed>> branch of the logic allows for future compatibility--
264+
unless otherwise specified new expressions in an older UA
265+
will be parsed and considered “unknown”,
266+
rather than invalidating the production.
267+
For consistency with that allowance,
268+
the <css>&lt;test></css> term in a <<boolean>>
269+
should be defined to match <<general-enclosed>>.
270+
204271
<h3 id=css-syntax>
205272
Specifying CSS Syntax in CSS: the <<syntax>> type</h3>
206273

@@ -3070,6 +3137,48 @@ Safely Handling Overly-Long Substitution</h3>
30703137
and the fact that it can be done without any of the pieces
30713138
<em>seeming</em> to be too large on first inspection.
30723139

3140+
<h2 id="boolean-logic">
3141+
Appendix B: Boolean Logic</h2>
3142+
3143+
In order to accommodate future extensions of CSS,
3144+
<<boolean>> productions generally interpret their <<general-enclosed>> grammar branch as unknown,
3145+
and their boolean logic is resolved using 3-value Kleene logic.
3146+
In some cases (such as ''@supports''),
3147+
<<general-enclosed>> is instead defined as false;
3148+
in which case the logic devolves to standard boolean algebra.
3149+
3150+
3-value boolean logic is applied recursively
3151+
to a boolean condition |test| as follows:
3152+
3153+
* A leaf-level |test| resolves to
3154+
true, false, or unknown,
3155+
as defined by the relevant specification.
3156+
3157+
* ''not |test|'' evaluates to
3158+
true if its contained |test| is false,
3159+
false if it's true,
3160+
and unknown if it's unknown.
3161+
3162+
* Multiple |test|s connected with ''and'' evaluate to
3163+
true if <em>all</em> of those |test|s are true,
3164+
false if <em>any</em> of them are false,
3165+
and unknown otherwise (i.e. if at least one unknown, but no false).
3166+
3167+
* Multiple |test|s connected with ''or'' evaluate to
3168+
true if <em>any</em> of those |test|s are true,
3169+
false if <em>all</em> of them are false,
3170+
and unknown otherwise (i.e. at least one unknown, but no true).
3171+
3172+
If a “top-level” <<boolean>> is unknown,
3173+
and the containing context doesn't otherwise define
3174+
how to handle unknown conditions,
3175+
it evaluates to false.
3176+
3177+
Note: That is, unknown doesn't “escape” a 3-value boolean expression
3178+
unless explicitly handled,
3179+
similar to how <code>NaN</code> doesn't “escape” a [=top-level calculation=]).
3180+
3181+
30733182
<!-- Big Text: etc
30743183

30753184
█████▌ █████▌ ███▌

0 commit comments

Comments
 (0)