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?

Solution 1

Why :not just use two :not:

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

Yes, it is intentional

Solution 2

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*/
}

Solution 3

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.

Solution 4

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.

Solution 5

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