ChatGPT解决这个技术问题 Extra ChatGPT

Can the :not() pseudo-class have multiple arguments?

I'm trying to select input elements of all types except radio and checkbox.

Many people have shown that you can put multiple arguments in :not, but using type doesn't seem to work anyway I try it.

form input:not([type="radio"], [type="checkbox"]) {
  /* css here */
}

Any ideas?

"Many people have shown that you can put multiple arguments in :not" Either those people were quoting a certain article that is popularly referenced but gravely misleading, or they were talking about jQuery, not CSS. Note that the given selector is in fact valid in jQuery, but not in CSS. I wrote a Q&A detailing the differences: stackoverflow.com/questions/10711730/… (the answer also mentions that article on the side)
Congratulations! You have successfully written valid CSS4.0 in your example above 2 years before the official edition came out.
@Jack Giffin: What "official edition" are you referring to? This question only pre-dates the FPWD of selectors-4 by 5 months, and the spec is still nowhere near completion: w3.org/TR/2011/WD-selectors4-20110929/#negation And it pre-dates the first implementation by 4 and a half years: stackoverflow.com/questions/35993727/…
According to MDN, the :not() selector with multiple arguments, is currently supported in FF84 and Safari9: developer.mozilla.org/en-US/docs/Web/CSS/:not#specifications

T
TylerH

Why :not just use two :not:

input:not([type="radio"]):not([type="checkbox"])

Yes, it is intentional


This has a high specificity.
For those who don't get the humor: he said "Why not..." with the : character.
As a side note, if you do something like input:not('.c1'), input:not('c2') you end up with an "and" situation where both classes would have to be on the input for it to match.
@BoltClock Delayed, but, hence the desire for the :not([attr],[attr]) CSV format as well :-P
@Cloudkiller no that would select any input element -> "input without the class c1 OR input without the class c2"
D
Daniel Tonon

If you're using SASS in your project, I've built this mixin to make it work the way we all want it to:

@mixin not($ignorList...) {
    //if only a single value given
    @if (length($ignorList) == 1){
        //it is probably a list variable so set ignore list to the variable
        $ignorList: nth($ignorList,1);
    }
    //set up an empty $notOutput variable
    $notOutput: '';
    //for each item in the list
    @each $not in $ignorList {
        //generate a :not([ignored_item]) segment for each item in the ignore list and put them back to back
        $notOutput: $notOutput + ':not(#{$not})';
    }
    //output the full :not() rule including all ignored items
    &#{$notOutput} {
        @content;
    }
}

it can be used in 2 ways:

Option 1: list the ignored items inline

input {
  /*non-ignored styling goes here*/
  @include not('[type="radio"]','[type="checkbox"]'){
    /*ignored styling goes here*/
  }
}

Option 2: list the ignored items in a variable first

$ignoredItems:
  '[type="radio"]',
  '[type="checkbox"]'
;

input {
  /*non-ignored styling goes here*/
  @include not($ignoredItems){
    /*ignored styling goes here*/
  }
}

Outputted CSS for either option

input {
    /*non-ignored styling goes here*/
}

input:not([type="radio"]):not([type="checkbox"]) {
    /*ignored styling goes here*/
}

isn't that kinda like asking a lumberjack to go to the hardware store instead to get his wood?
What? so you would rather write .selector:not(.one):not(.two):not(.three):not(.four) { ... } than .selector { @include not('.one','.two','.three','.four') { ... } } ?
In terms of efficiency: yes. Way less ' characters and imo more efficient code.
:not() = 6 characters per item; '', = 3 characters per item. @include should be assigned to a hot key so I'm going to count that as one character (in terms of typing it). Technically I don't think you even need to use the single quote marks in the list if you hate them that much. They do help prevent editors from freaking out though. Based on that, I still think my way is the more typing efficient way of writing it out.
@DaanHeskes also that writing out all the :not() cases doesn't allow you to use a variable to list them.
v
vsync

Starting from CSS Selectors 4 using multiple arguments in the :not selector becomes possible (see here).

In CSS3, the :not selector only allows 1 selector as an argument. In level 4 selectors, it can take a selector list as an argument.

Example:

/* In this example, all p elements will be red, except for 
   the first child and the ones with the class special. */

p:not(:first-child, .special) {
  color: red;
}

Unfortunately, browser support is somewhat new.


Keep in mind its CSS Selectors Level 4, not CSS 4, there is no such thing as CSS 4 and probably it will never exist.
Now it works on all major browsers. This should be the accepted answer as of 2021.
@dreamLo arguably as of June 2022 when IE was officially binned.
e
eatCasserole

I was having some trouble with this, and the "X:not():not()" method wasn't working for me.

I ended up resorting to this strategy:

INPUT {
    /* styles */
}
INPUT[type="radio"], INPUT[type="checkbox"] {
    /* styles that reset previous styles */
}

It's not nearly as fun, but it worked for me when :not() was being pugnacious. It's not ideal, but it's solid.


D
Daniel Tonon

If you install the "cssnext" Post CSS plugin, then you can safely start using the syntax that you want to use right now.

Using cssnext will turn this:

input:not([type="radio"], [type="checkbox"]) {
  /* css here */
}

Into this:

input:not([type="radio"]):not([type="checkbox"]) {
  /* css here */
}

https://cssnext.github.io/features/#not-pseudo-class


Would like to follow the link and buy the "plugin" advertised here, but (un)fortunately the target site seems to be unavailable anymore.
Thanks for letting me know the link was broken. CSS Next have changed their URL since I posted my answer. I've fixed the links now. You didn't have to be so sassy about it though. It's a free open-source Post-CSS plugin. Would you be this sassy if I posted a link to something like Lodash or Bootstrap?