Existe um seletor de CSS por prefixo de classe?

175

Quero aplicar uma regra CSS a qualquer elemento cuja classe corresponda ao prefixo especificado.

Por exemplo, eu quero uma regra que se aplique a div que tem classe que começa com status-(A e C, mas não B no seguinte trecho):

<div id='A' class='foo-class status-important bar-class'></div>
<div id='B' class='foo-class bar-class'></div>
<div id='C' class='foo-class status-low-priority bar-class'></div>

Algum tipo de combinação de:
div[class|=status]ediv[class~=status-]

É factível no CSS 2.1? É factível sob qualquer especificação CSS?

Nota: Eu sei que posso usar o jQuery para emular isso.

THX-1138
fonte

Respostas:

373

Não é possível com CSS2.1, mas é possível com seletores de correspondência de substring de atributo CSS3 (que são suportados no IE7 +):

div[class^="status-"], div[class*=" status-"]

Observe o caractere de espaço no segundo seletor de atributo. Isso seleciona divelementos cujo classatributo atende a uma destas condições:

  • [class^="status-"] - começa com "status-"

  • [class*=" status-"]- contém a subcadeia "status-" ocorrendo diretamente após um caractere de espaço. Os nomes de classe são separados por espaço em branco de acordo com a especificação HTML , daí o caractere de espaço significativo. Isso verifica qualquer outra classe após a primeira se várias classes forem especificadas e adiciona um bônus de verificar a primeira classe, caso o valor do atributo seja preenchido com espaço (o que pode acontecer com alguns aplicativos que geram classatributos dinamicamente).

Naturalmente, isso também funciona no jQuery, como demonstrado aqui .

O motivo pelo qual você precisa combinar dois seletores de atributos, conforme descrito acima, deve-se ao fato de um seletor de atributos [class*="status-"]corresponder ao seguinte elemento, o que pode ser indesejável:

<div id='D' class='foo-class foo-status-bar bar-class'></div>

Se você puder garantir que esse cenário nunca aconteça, poderá usar esse seletor por uma questão de simplicidade. No entanto, a combinação acima é muito mais robusta.

Se você tem controle sobre a fonte HTML ou o aplicativo que gera a marcação, pode ser mais simples transformar o status-prefixo em sua própria statusclasse, como sugere o Gumbo .

BoltClock
fonte
1
Se, por qualquer motivo estranho, você tiver uma classe chamada status-e não quiser corresponder a isso, o seletor se tornará ainda mais complicado: div[class^="status-"]:not(.status-), div[class*=" status-"]:not(.status-)Além disso, você perde o suporte ao IE7 / IE8. Felizmente, se sua marcação for sensata, você não precisará excluir essa classe.
BoltClock
O que está errado com isso: [class*=" anim-overlay-"] a:hover:after{...}. Minhas classes CSS são anim-overlay-1, anim-overlay-2.....anim-overlay-8
MB Parvez Rony
2
@WebDevRon: Você esqueceu a parte ^ =. Se seu atributo de classe é garantido para começar com anim-overlay-, provavelmente você não precisa da parte * =.
BoltClock
Obrigado. Outra coisa, posso usar isso .anim-overlay-*{...}?
MB Parvez Rony
2
@ Daniel Compton: Obrigado pela edição. Em última análise, tomei consciência de como palavras assim podem ser condescendentes com alguém para quem algo pode não ser tão óbvio. Sei que algumas pessoas realmente não apreciam esse tipo de mudança, por isso estou respondendo principalmente para que você saiba que sim.
BoltClock
14

Os seletores de atributos CSS permitem verificar os atributos de uma sequência. (neste caso - um nome de classe)

https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors

(parece que está realmente no status de 'recomendação' para 2.1 e 3)


Aqui está um resumo de como eu acho que funciona:

  • [ ]: é o contêiner para seletores complexos, se você quiser ...
  • class: 'class' é o atributo que você está vendo neste caso.
  • * : modifier (se houver): neste caso - "curinga" indica que você está procurando QUALQUER correspondência.
  • test- : o valor (supondo que exista um) do atributo - que contém a sequência "test-" (que pode ser qualquer coisa)

Então, por exemplo:

[class*='test-'] {
  color: red;
}

Você pode ser mais específico se tiver um bom motivo, com o elemento também

ul[class*='test-'] > li { ... }

Tentei encontrar casos extremos, mas não vejo necessidade de usar uma combinação de ^e *- à medida que * obtém tudo ...

exemplo: http://codepen.io/sheriffderek/pen/MaaBwp

http://caniuse.com/#feat=css-sel2

Tudo acima do IE6 obedecerá com alegria. :)

Observe que:

[class] { ... }

Selecionará qualquer coisa com uma classe ...

sheriffderek
fonte
[class*='test-']irá corresponder a elementos como <div class='foo-test-bar'>. Esse é o caso único que exige a combinação de ^ e *, conforme descrito na minha resposta. E o IE6 não suporta seletores de atributos.
BoltClock
@BoltClock - obrigado por esclarecer! - Eu não apoio <EI9 - e nunca escreveria nenhuma classe que se interceptasse - então, para mim, isso funciona. :)
sheriffderek
6

Isso não é possível com seletores CSS. Mas você pode usar duas classes em vez de uma, por exemplo, status e important em vez de status-important .

quiabo
fonte
14
Boa idéia sobre separá-lo em sua própria classe, mas é possível com seletores CSS. Veja minha resposta.
BoltClock
2

Você não pode fazer isso não. Há um seletor de atributo que corresponde exatamente ou parcial até um sinal de -, mas não funcionaria aqui porque você possui vários atributos. Se o nome da classe que você está procurando sempre for o primeiro, faça o seguinte:

<html>
<head>
<title>Test Page</title>
<style type="text/css">
div[class|=status] { background-color:red; }
</style>
</head>
<body>
<div id='A' class='status-important bar-class'>A</div>
<div id='B' class='bar-class'>B</div>
<div id='C' class='status-low-priority bar-class'>C</div>

</body>
</html>

Observe que isso é apenas para apontar qual seletor de atributos CSS é o mais próximo, não é recomendável supor que os nomes das classes sempre estarão na frente, pois o javascript pode manipular o atributo.

SBUJOLD
fonte
2
sim, pensei nisso. Pode se tornar um problema quando o jQuery entra em cena, pois pode inserir uma classe na frente.
THX-1138
Sim, eu vou editar minha postagem para deixar claro que claramente não é uma maneira recomendada de fazer isso. Se você tiver controle sobre os nomes das classes, a sugestão do Gumbo definitivamente seria o caminho a seguir (além de seletores de atributos em navegadores IE mais antigos não são suportados).
SBUJOLD 26/07