¿Puedo escribir un selector CSS que seleccione elementos que NO tengan una determinada clase o atributo?

647

Me gustaría escribir una regla de selector de CSS que seleccione todos los elementos que no tienen una clase determinada. Por ejemplo, dado el siguiente HTML:

<html class="printable">
    <body class="printable">
        <h1 class="printable">Example</h1>
        <nav>
            <!-- Some menu links... -->
        </nav>
        <a href="javascript:void(0)" onclick="javascript:self.print()">Print me!</a>
        <p class="printable">
            This page is super interresting and you should print it!
        </p>
    </body>
</html>

Me gustaría escribir un selector que seleccione todos los elementos que no tienen la clase "imprimible" que, en este caso, son la navegación y un elemento.

es posible?

NOTA: en el HTML real donde me gustaría usar esto, habrá muchos más elementos que no tienen la clase "imprimible" que la que tengo (me doy cuenta de que es al revés en el ejemplo anterior).

David Nordvall
fuente

Respuestas:

901

Por lo general, agrega un selector de clase a la :not()pseudoclase de la siguiente manera:

:not(.printable) {
    /* Styles */
}

:not([attribute]) {
    /* Styles */
}

Pero si necesita una mejor compatibilidad con el navegador (IE8 y versiones anteriores no son compatibles :not()), probablemente sea mejor crear reglas de estilo para los elementos que tienen la clase "imprimible". Si incluso eso no es factible a pesar de lo que dices sobre tu marcado real, es posible que tengas que trabajar alrededor de esa limitación.

Tenga en cuenta que, dependiendo de las propiedades que establezca en esta regla, algunos de ellos pueden ser heredados por descendientes que lo son .printable , o afectarlos de una manera u otra. Por ejemplo, aunque displayno se hereda, la configuración display: noneen a :not(.printable)evitará que se muestre a él y a todos sus descendientes, ya que elimina completamente el elemento y su subárbol del diseño. A menudo puede evitar esto usando en su visibility: hiddenlugar lo que permitirá que se muestren descendientes visibles, pero los elementos ocultos seguirán afectando el diseño como lo hicieron originalmente. En resumen, solo ten cuidado.

BoltClock
fuente
44
Como una pequeña pepita de información, la compatibilidad del navegador para los aspectos independientes de los medios de CSS a menudo es la misma en todos los tipos de medios: si un navegador no es compatible :not()en la pantalla, tampoco lo será en la impresión.
BoltClock
19
Tenga en cuenta que :not()solo toma un selector simple, lo que significa que no puede contener selectores anidados como :not(div .printable)- vea la sintaxis del Selector W3C
Steve Eynon
1
Acabo de probarlo para .active a: not (.active a) no funcionó para mí. Pero, a: no (.active) lo hizo!
user2367418
Cuando dice que no funcionó para usted, probablemente quiere decir que no funcionó para usted , ¿verdad? No significa que no funcione, probablemente sea un caso de especificidad: las propiedades en su :not(.active)regla pueden haber sido anuladas simplemente por propiedades en la (s) regla (s) con mayor prioridad.
amn
1
@Kilves: ¿Estás seguro de eso? La especificidad de :not()es la de su argumento, lo que significa que :not(div)es igualmente específico para div, :not(.cls)para .clsy :not(#id)para #id.
BoltClock
180
:not([class])

En realidad, esto seleccionará cualquier cosa que no tenga una clase css ( class="css-selector") aplicada.

Hice una demo jsfiddle

    h2 {color:#fff}
    :not([class]) {color:red;background-color:blue}
    .fake-class {color:green}
    <h2 class="fake-class">fake-class will be green</h2>
    <h2 class="">empty class SHOULD be white</h2>
    <h2>no class should be red</h2>
    <h2 class="fake-clas2s">fake-class2 SHOULD be white</h2>
    <h2 class="">empty class2 SHOULD be white</h2>
    <h2>no class2 SHOULD be red</h2>

¿Esto es compatible? Sí: Caniuse.com (consultado el 2 de enero de 2020) :

  • Soporte: 98.74%
  • Soporte parcial: 0.1%
  • Total: 98.84%

Edición divertida, estaba buscando en Google lo contrario de: no. Negación CSS?

selector[class]  /* the oposite of :not[]*/
Milche Patern
fuente
109

La :notpseudo clase de negación

La negación de la pseudo-clase CSS :not(X), es una notación funcional que toma un simple selector X como argumento. Coincide con un elemento que no está representado por el argumento. X no debe contener otro selector de negación.

Puede usar :notpara excluir cualquier subconjunto de elementos coincidentes, ordenados como lo haría con los selectores CSS normales.


Ejemplo simple: excluyendo por clase

div:not(.class)

Seleccionaría todos los divelementos sin la clase.class

div:not(.class) {
  color: red;
}
<div>Make me red!</div>
<div class="class">...but not me...</div>


Ejemplo complejo: excluyendo por tipo / jerarquía

:not(div) > div

Seleccionaría todos los divelementos que no son hijos de otrodiv

div {
  color: black
}
:not(div) > div {
  color: red;
}
<div>Make me red!</div>
<div>
  <div>...but not me...</div>
</div>


Ejemplo complejo: encadenar pseudo-selectores

Con la notable excepción de no poder encadenar / anidar :notselectores y pseudoelementos, puede usarlo junto con otros pseudo-selectores.

div {
  color: black
}
:not(:nth-child(2)){
  color: red;
}
<div>
  <div>Make me red!</div>
  <div>...but not me...</div>
</div>


Soporte de navegador , etc.

:notes un selector de nivel CSS3 , la principal excepción en términos de soporte es que es IE9 +

La especificación también hace un punto interesante:

el :not()pseudo permite escribir selectores inútiles. Por ejemplo :not(*|*), que no representa ningún elemento, o foo:not(bar)que es equivalente foopero con una especificidad más alta.

SW4
fuente
3
¡Esa fue una cena bien documentada y bien respondida! #thumbsup
Jonathan Bredo Christensen
Ok, tu ejemplo :not(div) > divfuncionaría solo con padres directos. ¿Qué hay de otros abuelos?
FindOut_Quran
Información impresionante! ¡Justo lo que necesitaba! ¡Gracias!
Jamie
9

Solo quiero contribuir a que las respuestas anteriores de: not () pueden ser muy efectivas en formas angulares, en lugar de crear efectos o ajustar la vista / DOM,

input.ng-invalid:not(.ng-pristine) { ... your css here i.e. border-color: red; ...}

Asegura que al cargar su página, los campos de entrada solo mostrarán los no válidos (bordes rojos o fondos, etc.) si tienen datos agregados (es decir, ya no son prístinos) pero no son válidos.

BaneStar007
fuente
7

Ejemplo

  [class*='section-']:not(.section-name) {
    @include opacity(0.6);
    // Write your css code here
  }

// Opacity 0.6 all "section-" pero no "section-name"

Hakan
fuente
2

Puede usar el :not(.class)selector como se mencionó anteriormente.

Si le interesa la compatibilidad con Internet Explorer, le recomiendo que use http://selectivizr.com/ .

Pero recuerde ejecutarlo bajo apache, de lo contrario no verá el efecto.

MelkorNemesis
fuente
3
¿Qué quieres decir con ejecutarlo bajo Apache? Selectivizr es una biblioteca front-end, no tiene nada que ver con el software del servidor
Kloar
Realiza una solicitud ajax, eso no funciona sin un servidor http.
MelkorNemesis
2

Usando la :not()pseudo clase:

Para seleccionar todo menos un determinado elemento (o elementos). Podemos usar el:not() pseudo clase CSS . La :not()pseudo clase requiere unCSS selector como argumento. El selector aplicará los estilos a todos los elementos, excepto a los elementos que se especifican como argumento.

Ejemplos:

/* This query selects All div elements except for   */
div:not(.foo) {
  background-color: red;
}


/* Selects all hovered nav elements inside section element except
   for the nav elements which have the ID foo*/
section nav:hover:not(#foo) {
  background-color: red;
}


/* selects all li elements inside an ul which are not odd */
ul li:not(:nth-child(odd)) { 
  color: red;
}
<div>test</div>
<div class="foo">test</div>

<br>

<section>
  <nav id="foo">test</nav>
  <nav>Hover me!!!</nav>
</section>
<nav></nav>

<br>

<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
</ul>

Ya podemos ver el poder de esta pseudo clase, nos permite ajustar convenientemente nuestros selectores al excluir ciertos elementos. Además, esta pseudo clase aumenta la especificidad del selector . Por ejemplo:

/* This selector has a higher specificity than the #foo below */
#foo:not(#bar) {
  color: red;
}

/* This selector is lower in the cascade but is overruled by the style above */
#foo {
  color: green;
}
<div id="foo">"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
  in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</div>

Willem van der Veen
fuente
0

Si desea que un menú de clase específico tenga un CSS específico si falta clase iniciada sesión :

body:not(.logged-in) .menu  {
    display: none
}
Mihai
fuente
-1

Como otros dijeron, simplemente pones: no (.class). Para los selectores de CSS, recomiendo visitar este enlace, ha sido muy útil durante mi viaje: https://code.tutsplus.com/tutorials/the-30-css-selectors-you-must-memorize--net-16048

div:not(.success) {
  color: red;
}

La pseudo clase de negación es particularmente útil. Digamos que quiero seleccionar todos los divs, excepto el que tiene una identificación de contenedor. El fragmento anterior manejará esa tarea perfectamente.

O, si quisiera seleccionar cada elemento (no recomendado) excepto las etiquetas de párrafo, podríamos hacer:

*:not(p) {
  color: green;
}
HBhering
fuente