[csswg-drafts] [Selectors] Numeric or Typed Attribute Value and Pseudo Attribute Selectors

Crissov has just created a new issue for 
https://github.com/w3c/csswg-drafts:

== [Selectors] Numeric or Typed Attribute Value and Pseudo Attribute 
Selectors ==
The [CSS WG Wiki](http://wiki.csswg.org/spec/selectors4) already 
mentions numeric comparisons of attribute values for [Selectors Level 
4](https://drafts.csswg.org/selectors-4/#attribute-selectors) (or 5). 
@LeaVerou brought it back up in [November 
2015](https://lists.w3.org/Archives/Public/www-style/2015Nov/0009.html)
 and cites a post by @alastc from [January 
2007](https://lists.w3.org/Archives/Public/www-style/2007Jan/0080.html).
 I’ve provided an overview of more or less intuitive operands in 
[April 
2011](https://lists.w3.org/Archives/Public/www-style/2011Apr/0817.html)
 which I will partially repeat below, so it gets properly tracked.

## Existing attribute selectors

As of 2016, attribute values are matched as (parts of) **character 
strings** only.

* `=` exact match

    We also have the [`i` modifier 
suffix](https://drafts.csswg.org/selectors-4/#attribute-case) for 
explicit case-insensitive comparisons. I would have liked it better if
 that would have been the default (despite host language conventions) 
and `==` would have been used for case-sensitive values; or if a colon
 indicated a case-insensitive “pseudo” value `=:`. Please, let’s *not*
 add more single-letter grep-like suffixes.

* `^=` starts with

* `$=` ends with

* `*=` contains

* `~=` in (space-separated) list

* `|=` exact or starts with followed by dash anything

    The pseudo-class `:lang()` already is more complex than what this 
similar attribute value operand  allows for.

## Proposed operands for attribute value selectors

Instead of complex `:not()` phrases, it would be handy to have 
**negated comparisons**, e.g.:
 
* `!=` or `=!` and `!==` or `==!` or `=!=`
* `!~=` or `~!=` or `~=!`
* `!|=` or `|!=` or `|=!`
*`!^=` or `^!=`  or `^=!`
* `!$=` or `$!=` or `$=!`
* `!*=` or `*!=` or `*=!`

As mentioned in the intro, others have already noted that it would be 
useful to have **numeric equality comparison** where ‘0’ = ‘0.0’ = 
‘.0’ = ‘00’ = `0x0` = ‘0e1’ = ‘’. Since we probably need to 
distinguish this from string comparisons explicitly, let’s just add 
another character:

* `#=` or
* `==` or
* `%=` if also  ‘0.5’ = ‘50%’

Numeric attribute selectors should be able to do simple **greater and 
lesser than comparisons**, of course. They’re not as useful for string
 comparisons, so we could spare the added character from above:

* `<`  = `!>=` or `=!>` but neither `>!=` nor `>=!`
* `>`  = `!<=` or `<!=` but neither `=!<` nor `<=!`
* ‘≤’: `<=` or `=<` = `!>`
* ‘≥’: `>=` or `=>` = `!<`

I don’t think we’d need `calc()`-like dynamic arithmetic expressions 
on either side of the operand, because authors should be able to 
adjust the static selector value accordingly, although some might want
 to specify rounding or precision. With step-based values, follows and
 precedes may be useful:

* ‘≺’: `<<` or `<=<` or `-=`
* ‘≻’: `>>` or `>=>` or `+=`

As has been correctly observed, not all such comparisons are between 
simple scalars. *Dates and times* can be converted to single numbers 
(e.g. in spreadsheet applications, Unix timestamps or Julian Day 
Numbers), but are usually expressed as tuples for human readability 
even in code (but at least usually within the same calendar system). 
Another case are strongly typed values with *units*, e.g. ‘25.4mm’ = 
‘1in’ = ‘72pt’ in CSS, and yet another are values with *multiple 
components* or channels like colors, e.g. ‘#FF0000’ = ‘red’.

Preferably, these should *just work* when using a single equals sign 
`=` and literal comparison would be invoked by doubling it `==` (or 
tripling `===` if `#=` wasn’t accepted), but I’m fine with the 
inverse, too. If another, different character was needed to mark a 
comparison as possibly involving unit or base conversion (i.e. opt-in 
and don’t treat `2016-07-28` as 1981 or `28/7/16` as 0.25), I’ve 
previously suggested the underscore, but I think pseudo-attributes 
would actually be more useful:

* `_=` etc.

A **boolean** or **binary logic attribute selector** could handle 
(case-insensitive) values like ‘yes’ = ‘true’ = ‘1’ = ‘on’ = 
_attribute-name_ and ‘no’ = ‘false’ = ‘0’ = ‘off’ = null, possibly 
depending on the host language:

* `?=`

## Pseudo-attribute selectors

I’ve previously mentioned an **assertion attribute selector** using 
`:=` that could be used to test whether a value would be legal, but I 
can’t come up with a use case for it. Sub-values are more realistic, 
e.g. `[color:red>50%]` or `[href:protocol=http]` and these could be 
generalized to pseudo-attribute selectors, e.g. `[:value]`, 
`[:datetime]`, `[:url]` or `[:class=foo]` == `.foo` and `[:name=foo]` 
or `[:ID=foo]` == `#foo`.

Please view or discuss this issue at 
https://github.com/w3c/csswg-drafts/issues/354 using your GitHub 
account

Received on Thursday, 28 July 2016 16:34:08 UTC