Posso escrever um seletor CSS selecionando elementos que NÃO possuem uma determinada classe ou atributo?

645

Eu gostaria de escrever uma regra de seletor de CSS que selecione todos os elementos que não têm uma determinada classe. Por exemplo, dado o seguinte 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>

Eu gostaria de escrever um seletor que selecione todos os elementos que não possuem a classe "imprimível" que, nesse caso, são os elementos nav e a .

Isso é possível?

NOTA: no HTML em que eu gostaria de usar isso, haverá muito mais elementos que não possuem a classe "printable" do que a que eu tenho (percebo que é o contrário no exemplo acima).

David Nordvall
fonte

Respostas:

899

Normalmente, você adiciona um seletor de classe à :not()pseudo-classe da seguinte forma:

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

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

Mas se você precisar de um suporte melhor navegador (IE8 e mais velhos não suportam :not()), você é provavelmente melhor fora de criar regras de estilo para os elementos que fazem com que a classe "impressão". Se mesmo isso não for possível, apesar do que você diz sobre sua marcação real, talvez seja necessário contorná-la.

Tenha em mente que, dependendo das propriedades que você está definindo nesta regra, alguns deles tanto pode ser herdado pelos descendentes que são .printable , ou não afetá-los de uma forma ou de outra. Por exemplo, embora displaynão seja herdado, a configuração display: nonede a :not(.printable)impedirá que ele e todos os seus descendentes sejam exibidos, pois remove completamente o elemento e sua subárvore do layout. Em geral, é possível contornar isso usando o visibility: hiddenque permitirá que os descendentes visíveis sejam exibidos, mas os elementos ocultos ainda afetarão o layout como originalmente. Em suma, apenas tenha cuidado.

BoltClock
fonte
4
Como uma pequena quantidade de informações, o suporte ao navegador para aspectos agnósticos de mídia do CSS geralmente é o mesmo entre os tipos de mídia - se um navegador não suportar :not()na tela, ele também não será impresso.
BoltClock
19
Note-se que :not()só tem um seletor simples que significa que ele não pode conter seletores aninhados como :not(div .printable)- ver W3C Selector sintaxe
Steve Eynon
1
Eu apenas tentei para .active a: not (.active a) não funcionou para mim. Mas, a: not (.active) fez!
precisa saber é o seguinte
Quando você diz que não funcionou para você, provavelmente significa que não funcionou para você , certo? Isso não significa que não funcione, provavelmente é um caso de especificidade - as propriedades em sua :not(.active)regra podem ter sido substituídas por propriedades em regra (s) com prioridade mais alta.
amn
1
@Kilves: Você tem certeza disso? A especificidade de :not()é a de seu argumento, o que significa que :not(div)é igualmente específico para div, :not(.cls)para .clse :not(#id)para #id.
BoltClock
179
:not([class])

Na verdade, isso selecionará qualquer coisa que não tenha uma classe css ( class="css-selector") aplicada a ele.

Eu fiz uma demonstração do 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>

Isso é suportado? Sim: Caniuse.com (acessado em 02 jan 2020) :

  • Suporte: 98.74%
  • Suporte parcial: 0,1%
  • Total: 98,84%

Edição engraçada, eu estava pesquisando no Google pelo contrário: não. Negação de CSS?

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

A :notpseudo classe de negação

A pseudo-classe CSS de negação :not(X), é uma notação funcional que utiliza um simples seletor X como argumento. Corresponde a um elemento que não é representado pelo argumento. X não deve conter outro seletor de negação.

Você pode usar :notpara excluir qualquer subconjunto de elementos correspondentes, ordenados como faria com seletores CSS normais.


Exemplo simples: excluindo por classe

div:not(.class)

Selecionaria todos os divelementos sem a classe.class

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


Exemplo complexo: excluindo por tipo / hierarquia

:not(div) > div

Selecionaria todos os divelementos que não são filhos de outrodiv

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


Exemplo complexo: encadeando pseudo-seletores

Com a exceção notável de não poder encadear / aninhar :notseletores e pseudo elementos, você pode usar em conjunto com outros pseudo seletores.

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


Suporte ao navegador , etc.

:noté um seletor de nível CSS3 , a principal exceção em termos de suporte é que é o IE9 +

A especificação também faz um ponto interessante:

o :not()pseudo permite que seletores inúteis sejam gravados. Por exemplo :not(*|*), que não representa nenhum elemento, ou foo:not(bar)que é equivalente a, foomas com uma especificidade mais alta.

SW4
fonte
3
Essa foi uma resposta bem documentada e bem explicada à ceia! #thumbsup
Jonathan Bredo Christensen #
Ok, seu exemplo :not(div) > divfuncionaria apenas com pais diretos. E os outros avós?
FindOut_Quran
Informação impressionante! Apenas o que eu precisava! Obrigado!
29719 Jamie
9

Gostaria de contribuir para que as respostas acima de: not () possam ser muito eficazes em formas angulares, em vez de criar efeitos ou ajustar a visualização / DOM,

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

Garante que, ao carregar sua página, os campos de entrada mostrem apenas os inválidos (bordas vermelhas ou planos de fundo, etc.) se eles tiverem dados adicionados (ou seja, não estiverem mais limpos), mas forem inválidos.

BaneStar007
fonte
7

Exemplo

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

// Opacidade 0,6 tudo "seção-", mas não "nome da seção"

Hakan
fonte
2

Você pode usar o :not(.class)seletor como mencionado anteriormente.

Se você se preocupa com a compatibilidade do Internet Explorer, recomendo que você use http://selectivizr.com/ .

Mas lembre-se de executá-lo no apache, caso contrário você não verá o efeito.

MelkorNemesis
fonte
3
Como assim, executá-lo no apache? Selectivizr é um lib front-end, não tem nada a ver com o software de servidor
Kloar
Ele executa uma solicitação ajax - que não funciona sem um servidor http.
MelkorNemesis
2

Usando a :not()pseudo classe:

Para selecionar tudo, exceto um determinado elemento (ou elementos). Podemos usar a :not() pseudo classe CSS . A :not()pseudo classe requer um CSSseletor como argumento. O seletor aplicará os estilos a todos os elementos, exceto os elementos especificados como argumento.

Exemplos:

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

Já podemos ver o poder dessa pseudo classe, ela nos permite ajustar convenientemente nossos seletores, excluindo certos elementos. Além disso, essa pseudo classe aumenta a especificidade do seletor . Por exemplo:

/* 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
fonte
0

Se você deseja que um menu de classe específico tenha um CSS específico, se estiver faltando o logon da classe :

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

Como outros disseram, você simplesmente coloca: not (.class). Para seletores CSS, eu recomendo visitar este link, foi muito útil ao longo da minha jornada: https://code.tutsplus.com/tutorials/the-30-css-selectors-you-must-memorize--net-16048

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

A pseudo classe de negação é particularmente útil. Digamos que eu queira selecionar todas as divs, exceto a que possui um ID de container. O snippet acima irá lidar com essa tarefa perfeitamente.

Ou, se eu quisesse selecionar todos os elementos (não recomendados), exceto as tags de parágrafo, poderíamos fazer:

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