w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.47k stars 658 forks source link

[selectors4] Name the “functional pseudo-class like :matches() with 0 specificity” #2143

Closed fantasai closed 5 years ago

fantasai commented 6 years ago

In Issue #1170 we decided to add a functional pseudo-class that is exactly like :matches() but has zero specificity. However, we didn't decide on a name.

Suggestions in that thread included :is(), :when(), :filter(), and :nospecificity(). It was noted that having :filter() as a selector and filter s a property might be confusing, and that :nospecificity() is a pain to type. Additional suggestions, comments, and clarifications welcome.

ewilligers commented 6 years ago

:where is like :when but without time connotations.

"A WHERE clause in SQL specifies that a ... statement should only affect rows that meet specified criteria." (Wikipedia)

ewilligers commented 6 years ago

I have added recent proposals to Lea's table.

Zhang-Junzhi commented 6 years ago

I suggest fallback, meaning an alternative solution when no else solution is available or general, which is the antonym of specific, which is then the adjective form of specificity.

Zhang-Junzhi commented 6 years ago

Or sub, which itself can mean a lower level or position, plus it can be an abbreviation of substitute(as in a substitute player in basketball game). Or weak, which means being susceptible to substitute

css-meeting-bot commented 6 years ago

The Working Group just discussed Bikeshed the 0 specificity alternative to :matches().

The full IRC log of that discussion <florian> Topic: Bikeshed the 0 specificity alternative to :matches()
<leaverou> Table: https://github.com/w3c/csswg-drafts/issues/2143#issuecomment-360586470
<dbaron> github: https://github.com/w3c/csswg-drafts/issues/2143#issuecomment-360586470
<florian> ericwilligers: [projets the issue]
<florian> fantasai: if we have :not and :is, they should have the same specificity
<florian> ericwilligers: matches has changed specificity recently
<florian> fantasai: that's out of scope here
<florian> ericwilligers: :when was time based, so I proposed :where, haven't heard back
<florian> astearns: does anyone have problem with :where ?
<florian> leaverou: has does that avoid the problems that :is has?
<florian> fantasai: because :is and :not need to be opposite
<florian> leaverou: how about having :is-not be the opposite of :is
<florian> all: Noooo
<florian> frremy: :where works for me
<florian> ericwilligers: has to combine well with :not()
<florian> leaverou: why can't we change :matches? it has shipped, but nobody uses it yet
<florian> astearns: we've discussed doing it several time, and failed to reach consensus
<florian> fantasai: lea propose to just change the specificity of :matches, and add a new one for the other specificity
<florian> frremy: why use the :match name at all, it's a bad name
<florian> leaverou: we're stuck with it anyway
<florian> fantasai: I want a short list so that we can think about it
<florian> leaverou: would you object to :is if it did what matches currently does, and :match() is the 0 specificity one?
<florian> fantasai: no, I would not
<florian> leaverou: what if we just have one, with an argument for specificity
<florian> fantasai: too confusing
<florian> shane: :where makes sense for people who have used SQL, but for others it is confusing, and seems to involve position
<dbaron> Whiteboard:
<florian> leaverou: I find SQL readable, but that's because it's a full sentence, which isn't the case in css
<florian> fantasai: I like 2 and 4
<Rossen> Here are the options
<dbaron> 1. :is()
<dbaron> 2. :matches() + replace existing :matches() with :is()
<Rossen> 1. :is()
<Rossen> 3. :if()
<Rossen> 4. :also()
<Rossen> 5. :where()
<florian> frremy: :and means nothing to me, all selectors already imply that
<Rossen> 6. :selects()
<florian> fantasai: yes, but :also doesn't have that implication
<florian> leaverou: in favor of :also
<florian> Rossen: [makes funny inaudible jokes]
<florian> dbaron: we have an html element called select
<florian> Rossen: let's start removing
<florian> Rossen: kill select
<florian> ericwilligers: I think we can also kill :if
<florian> Rossen: :if would need an :else
<florian> frremy: why?
<Rossen> 7. :also() + replace existing :matches() with :is()
<florian> leaverou: I'd like 7
<florian> frremy: this was called that way because the DOM API is called that
<florian> fantasai: actually, it's very old and it's the other way around
<florian> ericwilligers: it has been in webkit for a long time
<florian> astearns: how much web content uses :matches?
<florian> iank_: not a lot, looking at usecounter
<florian> ericwilligers: usecounter may be wrong
<dbaron> "the other way around" was in reference to original name being :any or :matches.
<florian> Rossen: is either 2 or 7 an option? they involve changing :matches. webkit people, can we do that?
<florian> myles: we could
<florian> myles: we would be moderately interested in updating, but it's low priority
<florian> dino: why ?
<florian> fantasai: because a best named proposal otherwise is :is, but it is bad if it's specificity doesn't match :not
<florian> fantasai: so we could change :matches to be the 0 specificity one, freeing the room for :is to do what :matches does now
<florian> leaverou: maybe we can resolve on that in parts
<florian> fantasai: removing option 1
<dbaron> I implemented :-moz-any() in Gecko in 2010 in https://bugzilla.mozilla.org/show_bug.cgi?id=544834
<florian> fantasai: the web compat impact of 2 and 7 are different
<florian> ericwilligers: does anyone want 2?
<florian> fantasai: removing 2
<florian> [lots of people]: I don't like also.
<florian> [lots of people]: [lots of jokes]
<florian> leaverou: what's wrong with :also ?
<Rossen> :soso()
<florian> dbaron: :also comes after something, but it doesn't come after anything particular
<florian> Rossen: agreed (with a pun)
<florian> ericwilligers: :where implies position OR situation
<florian> fantasai: does :where not have the same problem as :also?
<florian> fantasai: :matches does not have that problem
<florian> frremy: I prefer :where and :if, and :if makes a lot of sense when you read it
<dbaron> The thing I was talking about was called a "simple selector" in CSS 2, a "sequence of simple selectors" in selectors-3, and a "compound selector" in selectors-4.
<florian> astearns: :if clashes with JS?
<florian> [lots of people]: it doesn't
<florian> ...: :if calls for :else
<florian> ...: it doesn't
<florian> philipwalton: ??????
<florian> heycam: one option was to have a specificity parameter in :matches
<florian> astearns: we have agreed that renaming :matches is not necessary to solve this
<dbaron> s/??????/was the reason for doing this that the specificity was bad, or to give control over specificity? [answer: latter] It seems like a pseudo-class isn't the right tool for that, but I guess that's the right tool for the job./
<florian> astearns: we rejected some of the options, we should make a smaller list of plausible
<florian> fantasai: we should make a strawpoll, and then call for objections on the most popular
<florian> fantasai: :if gets 7 votes
<florian> fantasai: :also gets 1.5votes
<florian> fantasai: :where gets 7 votes
<florian> astearns: objections to :if ?
<florian> astearns: objections to :where ?
<florian> leaverou, fantasai, iank_: strong reservations
<tantek> let's strawpoll if vs where!
<florian> astearns: I am not declaring consensus
<florian> astearns: we will ask outsiders about :if vs :where
SelenIT commented 6 years ago

one option was to have a specificity parameter in :matches

Was the option of having one pseudo-class with optional specificity parameter (regardless its exact name), instead of two almost identical in anything except specificity pseudo-classes, rejected completely? Since the specificity rules of :matches() have already been redefined, so compatibility with existing implementations is not required anymore, maybe this option could have a second chance?

nico3333fr commented 6 years ago

:is() is my favorite too.

Why not :get() or a combination => :is-matching()? 🎉

SelenIT commented 6 years ago

At first, I liked :where(), but suddenly I imagined how I would interpret it if I didn’t know anything about SQL, and for that moment it seemed something like :has(): a specific element where, i.e. in which, there is another specific element (or elements). Is it just me?

salvan13 commented 6 years ago

What about :zero-matches() or :weak-matches() ? I think it should have matches in the name, since it does the same thing :/

Zhang-Junzhi commented 6 years ago

:weak-matches sounds quite straightforward to me. I like it.

Zhang-Junzhi commented 6 years ago

I suggested fallback and weak in a previous comment.

If we were to add the keyword match in the pseudo-class. :match-fallbacks, fallback-matches are also preferred by me.

CyberAP commented 6 years ago

I have a strong feeling this repeats mistakes from CSS2, when pseudo-classes and pseudo-elements were the same thing syntactically (remember :after and ::after?). Now with introduction of functional selectors they have exactly the same syntactic form for as pseudo-classes. But when we get one more functional selector (like a negative :is) and then another one and another one it becomes hard to distinguish ones that affect specificity and ones that do not.

tzi commented 6 years ago

@CyberAP Do you suggest we need another operator type / punctuation to describe the zero specificity pseudo-class?

CyberAP commented 6 years ago

@tzi, it could be anything. I think it has to be easily distinguishable from regular selectors that change specificity and be backwards compatible (not break any old css). But there has to be enough intent to do this as well because it's a big change. It all depends on whether there'll be any more functional selectors or not. There's no reason to introduce a new form of selector just for a single selector.

phistuck commented 6 years ago

What about simply parentheses? .grandfather (.parent-1, .parent-2) .child

Tyler-H commented 6 years ago

Between :is and :matches, my straw poll vote goes to :is.

burtonrodman commented 6 years ago

How about :trivial()

bradkemper commented 6 years ago

:whenceforth(.foo)

bradkemper commented 6 years ago

Or :inasmuch-as(.foo)

LeaVerou commented 6 years ago

Hi all,

I know that when it comes to names, we all have opinions. However, the group has been discussing this for months (possibly over a year) at this point. We've recently discussed it again in the F2F, and narrowed it down to :if() and :where(). I think it's highly unlikely that we will go back and reconsider other names at this point. Therefore, it would be far more productive to argue which one of these is a better choice.

Personally, I see myself using this A LOT so I think brevity is important. Roman Komarov seems to think the same. So, I would vote for :if(). Also, I think :if() stands much better when it's by itself than :where(). However, the community so far seems to favor :where(): https://twitter.com/LeaVerou/status/1014767203508338688

Based on their comments, I do worry a little that this is because they hope to see if used for something else, or because many of them are programmers and are used to if from there (whereas if has a much stronger association with natural language, if your brain has not been tainted by programming languages).

bradkemper commented 6 years ago

My last two suggestions weren’t serious.

But I liked :is() more than :if(). Sorry, but :if() just feels wrong to me. I think for Web authors, knowing a little (or more) JavaScript is more common than not. And you don’t need to know a lot of it to see if(foo) { } as script instead of CSS. :if() makes me expect there should also be an :else(). Or maybe a :then()

The older proposal of @if and @else for media queries seemed more natural to me.

Tyler-H commented 6 years ago

For what it's worth, languages I'm familiar with don't require an else or then statement for an if, but a lot of people assume one is required because many use cases do call for one. While English and basic science class does drill into our heads that "if" statements need to be followed by "then" statements, a lot of programming syntax is counter-intuitive when compared with lexical rules. I don't see an :if without a :then being any more of a problem than being recalcitrant to changing :matches while it is still in draft.

tzi commented 6 years ago

I have some mixed feelings here. In one hand, it is one of the feature that we want for like 10 years. In the other hand, I didn't read a comment from a developer that say "I don't car of the name, just ship it, we need it". Perhaps, it's because it's weird to have another operator to do almost the same thing that :matches?

A long time ago, for every CSS developers width was actually the content-width. And we switch, slowy, and now we see width as the box-width. I see this as a great success, because it's a change of the core of CSS, that didn't introduce too much complexity, we didn't introduce a new regularly used property. We handle it like a setting, something you decide at the start of your project. Most developer adopted it, but not everybody use it, it's a choice. We could have introduce a new property like box-width but it would have changed our daily syntax, allow mixed code, and the history of CSS would have been something hard to forget when we code.

I saw an idea of @philipwalton (https://github.com/w3c/csswg-drafts/issues/1170#issuecomment-329878248) to add an attribute on the link tag. I think it could be a great solution.

My proposal is to add a specificity attribute, and a value to switch the specificity of :matches(), :not(), and :has() to zero. For example:

<link specificity="no-pseudo-container" rel="stylesheet" hef="path/to/reset.css">

Pros:

Cons:

What do you think about it, not this exact solution, but this kind of solution?

cork commented 6 years ago

I have to say i have problem with both :if and :where cause in a bigger selector it feels like it moves the focus #select-this :if/:when(.this-is-true)

And I don't feel the same focus move from :matches, or :is. Sorry

FremyCompany commented 6 years ago

I feel like we should probably add real-world examples and see how they fare with the most common proposals:

Use case 1: specificity tweaks

textarea, input:if([type=text], [type=number], [type=email]) {
   /* default text box styling, with tag specificity */
   /* overridden by a css class, unlike what would happen without the no-specificity attribute check */
}

a:if([href^="http"]) {
    /* external link default style */
    /* does not override any 'a:hover' style defined before */
}

:any-link:if(:not(:hover):not(:active):not(:focus)) {
   /* by default, links have no own color */
   color: inherit; outline: none;
}
:any-link:focus {
    /* this rule overrides the previous one */
    outline: 1px dotted currentColor;
}
:any-link:hover {
    /* this rule overrides the previous ones */
    color: red; outline: none;
}

vs

textarea, input:where([type=text], [type=number], [type=email]) {
   /* default text box styling, with tag specificity */
   /* overridden by a css class, unlike what would happen without the no-specificity attribute check */
}

a:where([href^="http"]) {
    /* external link default style */
    /* does not override any 'a:hover' style defined before */
}

:any-link:where(:not(:hover):not(:active):not(:focus)) {
   /* by default, links have no own color */
   color: inherit; outline: none;
}
:any-link:focus {
    /* this rule overrides the previous one */
    outline: 1px dotted currentColor;
}
:any-link:hover {
    /* this rule overrides the previous ones */
    color: red; outline: none;
}

Use case 2: opting out of specificity entirely

:if(.class1) { … }
:if(.class1.class1--optionA) { … }
:if(.class2) { … } /* overrides .class1.class1-optionA style */
:if(.class2.class2--optionA) { … }
:if(.class2.class2--optionB) { … }

vs

:where(.class1) { … }
:where(.class1.class1--optionA) { … }
:where(.class2) { … } /* overrides .class1.class1-optionA style */
:where(.class2.class2--optionA) { … }
:where(.class2.class2--optionB) { … }
FremyCompany commented 6 years ago

Typing it out, I think :if is the best solution by far. I only had a very slight preference for :if during the meeting, and voted for both proposals, but after seeing this, I'm strongly in favor of :if now.

tzi commented 6 years ago

And what about a :0() selector? It's actually mean that it does something special. The zero is not explicit, but it is at least logical.

a:0([href^="http"]) {
    /* external link default style, does not override any 'a:hover' styles */
}
:0(.block) {
    /* opting out of specificity entirely */
}

Cheers, Thomas.

nico3333fr commented 6 years ago

Love the :0 idea, a nice smiley => :0 => OMG, specificity to 0 ???? :D

Loirooriol commented 6 years ago

For me the problem with :if is not that it needs an :else. Instead it's that intuitively I would think it would remove part of the selector if a condition is false, i.e. foo bar:if(#cond) baz would behave like foo bar#cond baz, foo baz. Of course this doesn't really make sense, but it's what the selector seems to mean to me at first glance.

I don't really like :where either.

:0 is not intuitive, it would be difficult to find its meaning using a search engine, and would require syntax changes because identifiers cannot begin with a digit.

iamvdo commented 6 years ago

:0() is one of the best idea so far. As identifiers cannot begin with a digit, what about :zero() or :void() or even :null() (even if I don't like this one)?

inoas commented 6 years ago

@LeaVerou :if has a strong procedural meaning whereas :where has not and I share your fear that :if may or may not become useful for other purposes in future.

@CyberAP

... from a functional side of things. What this selector ... tries to do is to set a default value that can be easily overridden, so :defaults() comes to mind. However, there is a :default pseudo-class and that may of course confuse people.

What about :init() or :initial() then. It behaves similiar to resetting a bunch of values to property: initial.

a:initial(.toggled) {
    /* external link default style, does not override any 'a:hover' styles */
}

Edit: :cond(...) > :where(...) > :initial(...) > :when(...) > :specificity(0, ...) > :for() > :if(...)

Edit: Fixed example @tzi

CyberAP commented 6 years ago

Hmm, what about :foreach? It basically takes an array of arguments and for each item performs some operation, without affecting anything, similar to the forEach array method in JS.

So if with JS we would write:

['.a', '.b', '.c'].forEach(item => doSomething(item + ' el'));

In CSS it would become:

:foreach(.a,.b,.c) el {
  // doSomething
}
tomhodgins commented 6 years ago

I'm still fond of :is() because of the brevity and clarity, but if that's been decided against would a name like :selector() be a good replacement? Something like :selector() indicates to me that it would match a CSS selector, and when styled like a pseudo-class (:()) it can modify any part of a selector as well. Here are some examples so you can see what it might look like and how it reads in code:

a:selector(.active) { }

:selector(header, footer, nav) a { }

It's not explicit that it's ignoring specificity, but it seems less permanent, or less strong than if I had written the same selector directly. What do you think?

SelenIT commented 6 years ago

What about :and()? It's short, it seems intuitive (a conjunction of two conditions, the target element should match both main and additional part), but in the same time it separates the selector into the non-parenthesized and parenthesized parts, implying that the latter is "special" (so its specificity might be not counted as usually).

Though it might look a bit odd in the beginning of the selector, the general rule that absence of the elemental selector means * should help to understand the intent to express the selector that has the specificity of the universal selector (i.e. zero) and still selects only specific elements...

CyberAP commented 6 years ago

@SelenIT :and() can be confused with a comma combinator a, b.

Loirooriol commented 6 years ago

What about :any? It's short, intuitive, and it's already implemented (but with a prefix and specificity 0,1,0 instead of 0,0,0).

There are also some old documentations mentioning :any, so people may get confused about :any, :matches and :something. Renaming :something to :any reduces the cognitive load, it's one option less to remember. Sure, if some documentation mentioned the specificity of :any then it will become invalid, but usually the focus was in the functionality instead of the specificity.

SelenIT commented 6 years ago

@CyberAP, the comma clearly means "or", not "and" :)

@Loirooriol, wouldn't it increase the cognitive load instead if for some period of transition there would co-exist two completely different experimental implementations of :any/:-*-any — the old deprecated one with the specificity of the single pseudo-class and the new one with no specificity at all?

But I agree that it's confusing to have several things that effectively do nearly the same job, but a bit differently. That's why, ideally, I would prefer the single pseudo-class with some (optional) modifier for turning off/adjusting the specificity to the current solution with 2 very similar pseudo-classes (plus the old deprecated-but-yet-supported one).

bkardell commented 6 years ago

I've been hesitant to comment because I've not had anything particularly thoughtful to add beyond varying degrees of conflicting thoughts on each one. However, over the past week or so I have informally talked to a (small) number of people with various degrees of skill who either independently arrived at :zero(...) or :nil(...) when posed the description without options, or, having known options agreed that this is among the better ones in this thread.

I just want to note that is isn't in the table above and I am in that camp, I think that either of those makes more sense to me than many of the others and I think the big strike against it in terms of the table is that it would prevent from later extending it to be arbitrary specificity. I'm not entirely convinced that is actually a big strike though.

jonathantneal commented 6 years ago

TL;DR: I like :any().


Forking @LeaVerou’s list from earlier to express sentiments on keywords I was drawn to:

Name Pros Cons
:any() short, meaningful prefixed version had differing specificity characteristics
:as() short, frequently used suggests transformation of preceeding selector
:if() short suggests logical opposite of non-existent :else()
:is() short, meaningful, backronym for "Ignore Specificity". suggests logical opposite of existing :not without matching specificity characteristics
:nil() short infrequently used in language, explicitly not extendable
:nospecificity() meaningful long, explicitly not extendable
:when() meaningful suggests a change of context (when some time is.., when some element query is...)
:zero() meaningful explicitly not extendable

The table is sorted alphabetically by name nil is an infrequent word according to https://www.wordfrequency.info/free.asp?s=y

Example Usages:

Forking @FremyCompany’s usages with minor changes to further share my impressions:

/* :any() → actually looks okay especially because any is also used in any-link */

:any(textarea, input:matches([type=text], [type=number], [type=email], :not([type])) {
  /* weightless text box styling */
}

:any(:any-link:not(:hover):not(:active):not(:focus)) {
  /* weightless link styling */
}
/* :as() → looks visually similar to :has and tripped me up when following it with :any-link */

:as(textarea, input:matches([type=text], [type=number], [type=email], :not([type])) {
  /* weightless text box styling */
}

:as(:any-link:not(:hover):not(:active):not(:focus)) {
  color: inherit;
}
/* :if() → so is :else like :not but with zero-specificity? */

:if(textarea, input:matches([type=text], [type=number], [type=email], :not([type])) {
  /* weightless text box styling */
}

:if(:any-link:not(:hover):not(:active):not(:focus)) {
  /* weightless link styling */
}
/* :nil() → i get it, but looks like programmer-speak not found elsewhere in css */

:nil(textarea, input:matches([type=text], [type=number], [type=email], :not([type])) {
  /* weightless text box styling */
}

:nil(:any-link:not(:hover):not(:active):not(:focus)) {
  /* weightless link styling */
}
/* :nospecificity() → hello, spell check, my old friend */

:nospecificity(textarea, input:matches([type=text], [type=number], [type=email], :not([type])) {
  /* weightless text box styling */
}

:nospecificity(:any-link:not(:hover):not(:active):not(:focus)) {
  /* weightless link styling */
}
/* :when() → it feels like this should not take css selectors */

:when(textarea, input:matches([type=text], [type=number], [type=email], :not([type])) {
  /* weightless text box styling */
}

:when(:any-link:not(:hover):not(:active):not(:focus)) {
  /* weightless link styling */
}
/* :zero() → it feels like :zero is supposed to represent a state */

:zero(textarea, input:matches([type=text], [type=number], [type=email], :not([type])) {
  /* weightless text box styling */
}

:zero(:any-link:not(:hover):not(:active):not(:focus)) {
  /* weightless link styling */
}

My overall impression is that :any seems the most clear and consistent.

phistuck commented 6 years ago

Is :matches(0, selector, selector...)) not an option?

tzi commented 6 years ago

@jonathantneal I don't see the cons about a pseudo-class that is "explicitly not extended-able". Can you give some context?

:nil() and :zero() seems to be the only ones where it will be clear "why we used this pseudo-selector". So they've got my vote.

jonathantneal commented 6 years ago

Hey @tzi, I was under the impression that folks wanted the ability to possibly extend the functionality of this selector in the future. I considered “explicitly not extendable” to be taken similarly as one of Lea’s cons — “can't be extended to specify specificity”. Sorry if I missed that this concern is no longer relevant.

@ionas, I’m not opposed to extending matches, either, especially if it’s readable and doesn’t require look-ahead. Thanks for looking at it anyway. 😄

Tyler-H commented 6 years ago

Most of the comments from the last three weeks seem to not respect the fact that the WG has narrowed their choices down to :if and :where.

jonathantneal commented 6 years ago

Until we see implementation, @Tyler-H, I would actively encourage you to challenge any consensus you think could be better. Make your differing evaluation clear. Keep a positive tone. That’s showing respect for the web and the people who make it.

get it wrong & it's on the web & pissing off devs forever — Bruce Lawson https://twitter.com/brucel/status/1022394427225063425

Tyler-H commented 6 years ago

@jonathantneal The thing is this topic has been taken to the bike shed already, and Lea requested to focus discussion on the two WG front-runners. Ignoring the request without providing critiques of the front-runners is not respect, it's... ignoring the request. Only two or three comments have provided concerns/critiques with the front-runners, while others (like yours) just take other suggestions and run with them.

As far as "pissing off devs forever" frankly the concerns of people who have visceral reactions to naming things should have their concerns notched far below those with actual logic-based reasons.

jonathantneal commented 6 years ago

I’m legitimately (and not sarcastically) sorry to you if my critique was not profound enough, but please do re-read my post, looking specifically for :if().

All of that aside, if you wish to continue bikeshedding how we ought to bikeshed, I would kindly ask that we move that discussion to Twitter, where civilized discourse may abound. 😄

bkardell commented 6 years ago

:nil() and :zero() seems to be the only ones where it will be clear "why we used this pseudo-selector". So they've got my vote.

@tzi - and :nospecificity

@Tyler-H FWIW, while I definitely share the sentiment that perpetual bikeshed isn't a good thing, it seems to me that part of why the WG has made no real decision is that none of the options seemed particularly great (at least this has been my feeling - kind of noncommittal/least worst). Since then, I feel like some options that seem at least as good have been added. From other conversations I am led to think that perhaps some other WG members feel this. I think that updating the table and asking whether it is more valuable for the pseudo to be clear or extendable to including a numeric specificity seems valid and potentially helpful. Perhaps the WG can resolve one way or another on that much at least and we can eliminate several items?

sarimarton commented 6 years ago

I've read the whole thread, and I'm aware of that now it's supposedly only an :if vs. :when question. But I'd like to get back a little bit (if only to show why :if and :when are mistaken tracks).

It's notable how far we've got from :is. :is is by far the most intuitive choice, everybody gets that in their mind in the first (or second) place, and there's a reason for that (no, not the funny acronym, which in my view has zero relevance). A selector, by nature, is a predicate, which says something about the matching element. Linguistically, nouns, adjectives and verbs and negation play well as predicates. Not surprisingly, if we look around among the current pseudo-classes, we find exactly these word classes. Any other word class, which the alternatives belong to, including :if, :when, :nospecificity, :zero etc., essentially breaks this logic and so hits a little bit in the gut. Obviously they can been read as parts of a sentence, but the reading logic is custom in that case. :if is not really a first-order predicate in itself.

Now came the problem with the imperfect contrast with :not. I'm not sure how this can be more important, than the above. :is is an exception in the system which has no specificity calculation, and having the most generic name plays well with this fact. Technically this imperfect contrast is not a problem at all. It's actually beneficial, because it makes :is(:not( meaningful, and it reads well.

On the other hand, in the future, other strategies might appear for specificity management. To me, for example, using the zero-specificity selector (whatever name it has, and however short it is) extensively, particularly with wrapping the whole selector to keep it on zero, is not a good long-term solution. It's just code repetition. We might have a higher order scope for specificity, maybe something like this:

<link rel="stylesheet" type="text/css" href="framework.css" specificity=1>
<link rel="stylesheet" type="text/css" href="mycustom.css" specificity=x>

which might act as the highest order in the calculation placeholders: x,0,0,0. I know it's out of scope (and maybe it is proposed already?), but my point is that specificity strategies can easily evolve above the selector level, so we shouldn't get lost in the supposed significance of the :is vs. :not question. IMO, :is would nicely fill a gap in the API (linguistically) and the zero-specificity function is just a good motive to get it not just as an alias (to :matches). Imperfect contrast with :not is not a problem at all. And we can leave :matches as it is now.

Sorry for being too long.

fantasai commented 5 years ago

I mentioned this during the meeting and I'll repeat, I think it's important for this selector to be short and also for it to be clear about how it's different from :matches()/:not(). Subtly different names that imply subtly different behavior without actually implying the difference through their names are very confusing.

I'm rather less concerned about extending to an arbitrary specificity level, it's reasonably likely that we never do that. Numbers for ordering are not the best, see e.g. BASIC and its goto statements, or tabindex if you want a more recent example. Ideally any solutions to specificity wrangling would incorporate some concept of higher level structures rather than numbers on the number line.

:zero() and :nil() aren't great in many ways, but at least they fulfill the two criteria I mentioned: they're short, and they imply something about what makes them different from :matches()/:not(). Or :is()/:not() if we lived in an ideal world and could rename :matches(). :)

css-meeting-bot commented 5 years ago

The CSS Working Group just discussed [selectors4] Name the “functional pseudo-class like :matches() with 0 specificity”.

The full IRC log of that discussion <mstange> Topic: [selectors4] Name the “functional pseudo-class like :matches() with 0 specificity”
<mstange> fantasai: Lea is not here, do we want to talk about it?
<mstange> fantasai: Anybody have anything to add to this discussion? There's no clear "this is definitely what we should do" resolution.
<TabAtkins> New suggestion: smoosh()
<Rossen> github: https://github.com/w3c/csswg-drafts/issues/2143
<fantasai> https://github.com/w3c/csswg-drafts/issues/2143#issuecomment-408128027
<TabAtkins> Sorry, :smoosh()
<zcorpan> -webkit-appearance: smoosh
<mstange> fantasai: This takes a list of selectors of which any can match. Unlike the :matches selector it basically zeroes out the specificity: anything you put inside has a specificity of zero.
<mstange> fantasai: This gives you more control about which parts of the selector affect the specificity and which down.
<mstange> fantasai: The only question is what to name it.
<mstange> fantasai: Some of the suggestions didn't get any traction.
<mstange> fantasai: We don't have any suggestion that is clearly better than the other ones.
<mstange> fantasai: My concern with a lot of these is that it is not very clear for :if or :where why this is different from :matches.
<mstange> ... It's different because of the zero specificity, so the name should have something to do with that.
<mstange> franremy: Last time we had narrowed it down to three.
<mstange> fantasai: New ones were added after last time.
<mstange> franremy: We almost agreed on one of them last time, don't remember which one.
<mstange> franremy: Would prefer to not expand the length of the list of candidates.
<mstange> dbaron: To make progress, we need to say "Nobody leaves the room until we decide."
<ericwilligers> Last time: if vs where
<fantasai> https://lists.w3.org/Archives/Public/www-style/2018Jul/0027.html
<mstange> fantasai: Our resolution last time was to narrow the short list to :if and :where, and we added :nil and :zero.
<mstange> ... So we could choose between those.
<mstange> Rossen: if, where, nil, zero, quash
<mstange> Rossen: In that order, with if being 1 and quash being 5, go ahead and put in your preferred 3.
<mstange> ... In the order of preference
<fantasai> 1 = if, 2 = where, 3 = nil, 4 = zero, 5 = quash
<franremy> 1 2 ... 4 3 5
<iank_> 2, 5, 3
<fantasai> 5, 3, 4, 1, 2
<cbiesinger> 2, 1
<florian> 1, 2
<TabAtkins> 3, 2, 1
<heycam> 2, 1
<futhark> 2 3 5
<dbaron> 4 3 2 5 1
<fantasai> https://github.com/w3c/csswg-drafts/issues/1170
<ericwilligers> 2, 1, 4
<Rossen> 2, 1
<eae> 3 2 1
<melanierichards> 2
<AmeliaBR> 2 4
<tantek> 4 3 5 :ns (no specificity)
<rachelandrew> 2, 1 , 3
<emilio> 3, 1
<Oriol> 1, 2, 4, but I would prefer any
<emilio> fantasai: lol
<bz> nsISelector
<bz> That's NS
<mstange> Rossen: A lot of votes for number 2 as the first choice
<AmeliaBR> Why was `:is` dropped from the options?
<mstange> ... Resolve on :where?
<mstange> ... If anyone has a strong reason to change this, speak up now.
<mstange> Resolved: Name the selector :where