Seletor CSS3: primeiro do tipo com o nome da classe?

230

É possível usar o seletor CSS3 :first-of-typepara selecionar o primeiro elemento com um determinado nome de classe? Não tive sucesso com o meu teste, então estou pensando que não é?

O código ( http://jsfiddle.net/YWY4L/ ):

p:first-of-type {color:blue}
p.myclass1:first-of-type {color:red}
.myclass2:first-of-type {color:green}
<div>
  <div>This text should appear as normal</div>
  <p>This text should be blue.</p>
  <p class="myclass1">This text should appear red.</p>
  <p class="myclass2">This text should appear green.</p>
</div>

Adam Youngers
fonte

Respostas:

336

Não, não é possível usar apenas um seletor. O :first-of-typepseudo-classe seleciona o primeiro elemento do seu tipo ( div, p, etc.). Usar um seletor de classe (ou um seletor de tipo) com essa pseudo-classe significa selecionar um elemento se ele tiver a classe fornecida (ou for do tipo especificado) e for o primeiro de seu tipo entre seus irmãos.

Infelizmente, o CSS não fornece uma :first-of-class seletor que escolhe apenas a primeira ocorrência de uma classe. Como solução alternativa, você pode usar algo como isto:

.myclass1 { color: red; }
.myclass1 ~ .myclass1 { color: /* default, or inherited from parent div */; }

Explicações e ilustrações para a solução alternativa são fornecidas aqui e aqui .

BoltClock
fonte
7
No @justNik, isso funciona para vários elementos. O .myclass1seletor selecionaria todos os elementos de .myclass1. O seletor .myclass1 ~ .myclass1usa o combinador geral de irmãos para selecionar todos os elementos da classe .myclass1que é o irmão seguinte de um elemento com uma classe de .myclass1. Isso é explicado em detalhes surpreendentes aqui .
WebWanderer
ótima solução alternativa! funcionou bem para a implementação de scroll-spy usando o observador de interseção, onde algumas seções podem estar visíveis na página, mas queremos desenhar em negrito apenas a primeira ativa.
zavr 30/01
45

O rascunho do CSS Selectors Level 4 propõe adicionar uma of <other-selector>gramática ao :nth-childseletor . Isso permitiria que você a escolher o n º criança combinando um determinado outro seletor:

:nth-child(1 of p.myclass) 

Os rascunhos anteriores usavam uma nova pseudo-classe; :nth-match()portanto, você pode ver essa sintaxe em algumas discussões sobre o recurso:

:nth-match(1 of p.myclass)

Isso já foi implementado no WebKit e, portanto, está disponível no Safari, mas parece ser o único navegador que o suporta . Há tickets arquivados para implementá-lo Blink (Chrome) , Gecko (Firefox) e uma solicitação para implementá-lo no Edge , mas nenhum progresso aparente em nenhum deles.

Brian Campbell
fonte
102
Apenas 10 anos, e eu posso usar isso. Embora o projeto que eu usaria isso precise ser feito amanhã.
Lajos Meszaros
1
: nth-match () foi descartado em favor de novos recursos para nth-child (), que ainda não são bem suportados: caniuse.com/#feat=css-nth-child-of
nabrown
@ nabrown78 Obrigado pelo aviso, atualizei a resposta para ser atualizado.
Brian Campbell
19

Isso não possível utilizar o seletor CSS3 : first-of-tipo para selecionar o primeiro elemento com um determinado nome da classe.

No entanto, se o elemento de destino tiver um irmão elemento anterior, você poderá combinar a pseudo classe CSS de negação e os seletores de irmãos adjacentes para corresponder a um elemento que não possui imediatamente um elemento anterior com o mesmo nome de classe:

:not(.myclass1) + .myclass1

Exemplo completo de código de trabalho:

p:first-of-type {color:blue}
p:not(.myclass1) + .myclass1 { color: red }
p:not(.myclass2) + .myclass2 { color: green }
<div>
  <div>This text should appear as normal</div>
  <p>This text should be blue.</p>
  <p class="myclass1">This text should appear red.</p>
  <p class="myclass2">This text should appear green.</p>
</div>

lodz
fonte
9

Encontrei uma solução para sua referência. de alguns divs de grupo, selecione do grupo de duas divs da mesma classe o primeiro

p[class*="myclass"]:not(:last-of-type) {color:red}
p[class*="myclass"]:last-of-type {color:green}

BTW, não sei por que :last-of-typefunciona, mas :first-of-typenão funciona.

Minhas experiências com jsfiddle ... https://jsfiddle.net/aspanoz/m1sg4496/

Konstantin
fonte
Isso não funciona conforme necessário, como já pode ser visto no violino. A única coisa que isso faz, não é selecionar a última div se ela não tiver a classe.
Marten Koetsier
6

Este é um tópico antigo, mas estou respondendo porque ainda aparece no alto da lista de resultados de pesquisa. Agora que o futuro chegou, você pode usar o pseudo-seletor: enésimo filho.

p:nth-child(1) { color: blue; }
p.myclass1:nth-child(1) { color: red; }
p.myclass2:nth-child(1) { color: green; }

O pseudo-seletor: enésimo filho é poderoso - os parênteses aceitam fórmulas e números.

Mais aqui: https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child

TDavison
fonte
6
Sim, eu não acho que funciona, pelo menos não no Chrome ... jsfiddle.net/YWY4L/91
Adam Youngers
2
O que você quer dizer com "agora que o futuro chegou"? Isso só funciona no Safari no momento da redação.
Alejandro García Iglesias
4

Como solução alternativa, você pode agrupar suas classes em um elemento pai como este:

<div>
    <div>This text should appear as normal</div>
    <p>This text should be blue.</p>
    <div>
        <!-- first-child / first-of-type starts from here -->
        <p class="myclass1">This text should appear red.</p>
        <p class="myclass2">This text should appear green.</p>
    </div>
</div>
Gediminas Bivainis
fonte
1

Não sei como explicar isso, mas me deparei com algo semelhante hoje. Não é possível definir .user:first-of-type{}enquanto .user:last-of-type{}funcionou bem. Isso foi corrigido depois que eu os envolvi em uma div sem nenhuma classe ou estilo:

https://codepen.io/adrianTNT/pen/WgEpbE

<style>
.user{
  display:block;
  background-color:#FFCC00;
}

.user:first-of-type{
  background-color:#FF0000;
}
</style>

<p>Not working while this P additional tag exists</p>

<p class="user">A</p>
<p class="user">B</p>
<p class="user">C</p>

<p>Working while inside a div:</p>

<div>
<p class="user">A</p>
<p class="user">B</p>
<p class="user">C</p>
</div>
adrianTNT
fonte
0

Você pode fazer isso selecionando todos os elementos da classe que são irmãos da mesma classe e invertendo-os, o que selecionará praticamente todos os elementos da página; portanto, você deverá selecionar novamente pela classe.

por exemplo:

<style>
    :not(.bar ~ .bar).bar {
        color: red;
    }
<div>
    <div class="foo"></div>
    <div class="bar"></div> <!-- Only this will be selected -->
    <div class="foo"></div>
    <div class="bar"></div>
    <div class="foo"></div>
    <div class="bar"></div>
</div>
Jonathan.
fonte
-5

Simplesmente :firstfunciona para mim, por que isso ainda não foi mencionado?

Eduard Ge
fonte
3
:firsté uma pseudo-classe relacionada à impressão.
user247702