Selector de CSS para o primeiro elemento com classe

eu tenho um monte de elementos com um nome de classe red, mas não consigo selecionar o primeiro elemento com o class="red" usando a seguinte regra CSS:

.red:first-child {
    border: 5px solid red;
}
<p class="red"></p>
<div class="red"></div>

o que se passa neste selector e como é que o corrijo?

Graças aos comentários, descobri que o elemento tem de ser o primeiro filho do pai a ser seleccionado, o que não é o caso que tenho. Eu tenho a seguinte estrutura, e esta regra falha como mencionado nas observações:

.home .red:first-child {
    border: 1px solid red;
}
<div class="home">
    <span>blah</span>
    <p class="red">first</p>
    <p class="red">second</p>
    <p class="red">third</p>
    <p class="red">fourth</p>
</div>
Como posso atingir a primeira criança com classe?

Author: TylerH, 2010-04-27

18 answers

Este é um dos exemplos mais conhecidos de autores que não compreendem como :first-child funciona. introduzido em CSS2 , A pseudo-classe :first-child representa o primeiro filho do seu pai. É isso. Há um equívoco muito comum de que ele pega qualquer elemento criança é o primeiro a corresponder às condições especificadas pelo resto do selector composto. Devido à forma como os selectores funcionam (ver aqui para uma explicação), isso simplesmente não é verdadeiro.

O Nível 3 dos selectores introduz uma pseudo-classe :first-of-type , que representa o primeiro elemento entre irmãos do seu tipo de elemento. Esta resposta explica, com ilustrações, a diferença entre :first-child e :first-of-type. No entanto, como em :first-child, ele não olha para quaisquer outras condições ou atributos. Em HTML, o tipo de elemento é representado pelo nome da tag. Na pergunta, esse tipo é p.

Infelizmente, não existe uma pseudo-classe semelhante para corresponder ao primeiro elemento-filho de uma determinada classe. Um trabalho em torno de que Lea Verou e eu inventei para isso (embora totalmente independente) é primeiro aplicar seus estilos desejados a todos os seus elementos com essa classe:
/* 
 * Select all .red children of .home, including the first one,
 * and give them a border.
 */
.home > .red {
    border: 1px solid red;
}

... em seguida, "desfazer" os estilos para os elementos com a classe que vir após o primeiro, usando geral irmão combinator ~ em um interesse regra:

/* 
 * Select all but the first .red child of .home,
 * and remove the border from the previous rule.
 */
.home > .red ~ .red {
    border: none;
}
Agora só o primeiro elemento com class="red" terá uma fronteira. Aqui está uma ilustração de como as regras são aplicadas:
<div class="home">
  <span>blah</span>         <!-- [1] -->
  <p class="red">first</p>  <!-- [2] -->
  <p class="red">second</p> <!-- [3] -->
  <p class="red">third</p>  <!-- [3] -->
  <p class="red">fourth</p> <!-- [3] -->
</div>
  1. Não são aplicadas regras; não é feita nenhuma fronteira.
    Este elemento não tem a classe red, por isso é ignorado.

  2. Apenas a primeira regra é aplicada; uma fronteira vermelha é renderizada.
    Este elemento tem a classe red, mas não é precedido por nenhum elemento com a classe red em seu pai. Assim, a segunda regra não é aplicada, apenas o primeiro, e o elemento mantém a sua fronteira.

  3. Ambas as regras são aplicadas; nenhuma fronteira é renderizada.
    Este elemento tem a classe red. É também precedido por pelo menos um outro elemento com a classe red. Assim, ambas as regras são aplicadas, e a segunda declaração border sobrepõe-se à primeira, "desfazendo-a", por assim dizer.

Como bónus, apesar de ter sido introduzido nos selectores 3, o combinador de irmãos é muito bonito. bem apoiado pela IE7 e mais recente, ao contrário de :first-of-type e {[26] } que só são suportados pela IE9 adiante. Se você precisa de um bom suporte de navegador, você está com sorte.

De fato, o fato de que o combinador de irmãos é o único componente importante nesta técnica, e ele tem um suporte de navegador tão incrível, torna esta técnica muito versátil - você pode adaptá-la para filtrar elementos por outras coisas, além de selectores de classe:

  • Pode usar isto para contornar :first-of-type em IE7 e IE8, simplesmente fornecendo um selector de tipo em vez de um selector de classe (mais uma vez, mais sobre a sua utilização incorrecta aqui numa secção posterior):

    article > p {
        /* Apply styles to article > p:first-of-type, which may or may not be :first-child */
    }
    
    article > p ~ p {
        /* Undo the above styles for every subsequent article > p */
    }
    
  • Você pode filtrar por selectores de atributos ou quaisquer outros selectores simples em vez de classes.

  • Você também pode combinar esta técnica primordial com pseudo-elementos mesmo que pseudo-elementos tecnicamente não são seletores simples.

Note que para isso para funcionar, você precisará saber com antecedência o que os estilos padrão serão para os seus outros elementos irmãos para que você possa anular a primeira regra. Além disso, uma vez que isto envolve regras imperiais em CSS, você não pode alcançar a mesma coisa com um único selector para usar com os selectores API de selénio 'S localizadores de CSS.

Vale a pena mencionar que os selectores 4 introduz uma extensão à notação :nth-child() (originalmente uma pseudo-classe inteiramente nova chamado :nth-match()), que lhe permitirá usar algo como :nth-child(1 of .red) em vez de um hipotético .red:first-of-class. Sendo uma proposta relativamente recente, ainda não existem implementações interoperáveis suficientes para ser utilizável em locais de produção. Esperemos que isto mude em breve. Entretanto, a solução que sugeri deve funcionar para a maioria dos casos.

Tenha em mente que esta resposta assume que a questão está à procura de cada elemento do primeiro filho que tenha uma determinada classe. Não há nenhum pseudo-Classe nem sequer uma solução CSS genérica para a n - ésima correspondência de um selector complexo ao longo de todo o documento - se uma solução existe depende fortemente da estrutura do documento. jQuery fornece :eq(), :first, :last e mais para este propósito, mas note novamente que eles funcionam muito diferente de :nth-child() et al . Usando a API dos selectores, tanto pode usar document.querySelector() para obter a primeira correspondência:

var first = document.querySelector('.home > .red');

Ou utilizar document.querySelectorAll() com um indexador para escolher qualquer produto específico match:

var redElements = document.querySelectorAll('.home > .red');
var first = redElements[0];
var second = redElements[1];
// etc

Embora a solução .red:nth-of-type(1) na resposta original aceite por Philip Daubmeier obras (que foi originalmente escrita porMartyn mas apagada desde então), não se comporta da maneira que se espera que aconteça.

Por exemplo, se apenas quisesse seleccionar o p na sua marcação original:

<p class="red"></p>
<div class="red"></div>

... então você não pode usar .red:first-of-type (equivalente a .red:nth-of-type(1)), porque cada elemento é o primeiro (e único) um de seu tipo (p e div respectivamente), por isso ambos serão correspondidos pelo selector.

Quando o primeiro elemento de uma determinada classe é também o primeiro do seu tipo, A pseudo-classe irá funcionar, mas isto só acontece por coincidência. Este comportamento é demonstrado na resposta de Filipe. No momento em que você ficar em um elemento do mesmo tipo antes deste elemento, o selector vai falhar. Tomando a marcação actualizada:
<div class="home">
  <span>blah</span>
  <p class="red">first</p>
  <p class="red">second</p>
  <p class="red">third</p>
  <p class="red">fourth</p>
</div>
A aplicação de uma regra com .red:first-of-type funcionará, mas uma vez que adicionar outro p sem a classe:
<div class="home">
  <span>blah</span>
  <p>dummy</p>
  <p class="red">first</p>
  <p class="red">second</p>
  <p class="red">third</p>
  <p class="red">fourth</p>
</div>

... o selector irá falhar imediatamente, porque o primeiro elemento .red é agora o segundo p elemento.

 1181
Author: BoltClock, 2017-06-29 10:56:18

O selector :first-child destina-se, como diz o nome, a seleccionar o primeiro filho de uma marca-mãe. As crianças têm de estar embutidas na mesma etiqueta Parental. O seu exemplo EXACTO irá funcionar (basta experimentá-lo Aqui):

<body>
    <p class="red">first</p>
    <div class="red">second</div>
</body>
Talvez tenhas aninhado as tuas etiquetas em etiquetas de pais diferentes? As suas marcas da classe red são realmente as primeiras marcas sob o pai?

Repare também que isto não se aplica apenas à primeira marca deste tipo em todo o documento, mas sempre que um novo pai está enrolado à volta, tipo:

<div>
    <p class="red">first</p>
    <div class="red">second</div>
</div>
<div>
    <p class="red">third</p>
    <div class="red">fourth</div>
</div>

first e third será vermelho então.

Actualizar:

Não sei porque martyn apagou a resposta, mas ele tinha a solução, o selector:
<html>
<head>
<style type="text/css">
.red:nth-of-type(1)
{
    border:5px solid red;
} 
</style>
</head>

<body>
    <div class="home">
        <span>blah</span>
        <p class="red">first</p>
        <p class="red">second</p>
        <p class="red">third</p>
        <p class="red">fourth</p>
    </div>
</body>
</html>

Créditos a Martyn . Mais informações, por exemplo aqui. Esteja ciente de que este é um seletor de CSS 3, portanto nem todos os navegadores o reconhecerão (por exemplo, IE8 ou mais antigo).

 305
Author: Philip Daubmeier, 2017-05-23 12:34:54

A resposta correcta é:

.red:first-child, :not(.red) + .red { border:5px solid red }

Parte I: se o elemento for o primeiro para o seu pai e tiver a classe "vermelho", ele terá fronteira.
Part II: If".o elemento vermelho" não é o primeiro para o seu pai, mas segue imediatamente um elemento sem classe ".vermelho", também merecerá a honra da referida fronteira.

Violino ou não aconteceu.

A resposta de Philip Daubmeier, embora aceite, não está correcta - ver violino em anexo.
A resposta de BoltClock resultaria, mas ... define e substitui desnecessariamente os estilos
(especialmente uma questão em que de outra forma herdaria uma fronteira diferente - você não quer declarar outra fronteira:nenhuma)

Editar: No caso de você ter " Vermelho "seguindo Não-vermelho várias vezes, cada" primeiro " vermelho vai obter a fronteira. Para evitar isso, seria preciso usar a resposta de BoltClock. Ver violino

 59
Author: SamGoody, 2016-11-15 13:26:22

Pode usar first-of-type ou nth-of-type(1)

.red {
  color: green;  
}

/* .red:nth-of-type(1) */
.red:first-of-type {
  color: red;  
}
<div class="home">
  <span>blah</span>
  <p class="red">first</p>
  <p class="red">second</p>
  <p class="red">third</p>
  <p class="red">fourth</p>
</div>
 13
Author: Moes, 2017-01-13 00:57:44

Para corresponder ao seu selector, o elemento deve ter um nome de classe de red e deve ser o primeiro filho do seu pai.

<div>
    <span class="red"> <!-- MATCH -->
</div>

<div>
    <span>Blah</span>
    <p class="red"> <!-- NO MATCH -->
</div>

<div>
    <span>Blah</span>
    <div><p class="red"></div> <!-- MATCH -->
</div>
 8
Author: Chetan Sastry, 2011-12-16 18:50:41
Como as outras respostas cobrem o que está errado com ele, vou tentar a outra metade, como consertá-lo. Infelizmente, eu não sei se você tem uma solução CSS apenas aqui, pelo menos não que eu possa pensar em . Mas há outras opções....
  1. Atribuir uma classe first ao elemento quando o gerar, assim:

    <p class="red first"></p>
    <div class="red"></div>
    

    CSS:

    .first.red {
      border:5px solid red;
    }
    

    Este CSS só corresponde a elementos com ambos first e aulas.

  2. Alternativamente, faça o mesmo em JavaScript, por exemplo aqui está o que jQuery você usaria para fazer isso, usando o mesmo CSS que Acima:

    $(".red:first").addClass("first");
    
 7
Author: Nick Craver, 2012-06-25 23:07:00

De acordo com o seu problema actualizado

<div class="home">
  <span>blah</span>
  <p class="red">first</p>
  <p class="red">second</p>
  <p class="red">third</p>
  <p class="red">fourth</p>
</div>

Que tal

.home span + .red{
      border:1px solid red;
    }

Isto irá seleccionar class home, depois o elemento span e finalmente tudo .elementos vermelhos que são colocados imediatamente após os elementos de calibração.

Referência: http://www.w3schools.com/cssref/css_selectors.asp

 5
Author: StinkyCat, 2014-01-21 11:49:39
Pode mudar o seu código para algo assim para que funcione.
<div class="home">
  <span>blah</span>
  <p class="red">first</p>
  <p class="red">second</p>
  <p class="red">third</p>
  <p class="red">fourth</p>
</div>

Isto faz o trabalho por ti

.home span + .red{
      border:3px solid green;
    }

Aqui está uma referência CSS de SnoopCode sobre isso.

 3
Author: Prabhakar, 2015-10-14 10:15:28

Estou a usar abaixo do CSS para ter uma imagem de fundo para a lista ul li

#footer .module:nth-of-type(1)>.menu>li:nth-of-type(1){
  background-position: center;
  background-image: url(http://monagentvoyagessuperprix.j3.voyagesendirect.com/images/stories/images_monagentvoyagessuperprix/layout/icon-home.png);
  background-repeat: no-repeat;
}
<footer id="footer">
  <div class="module">
    <ul class="menu ">
      <li class="level1 item308 active current"></li>
      <li> </li>
    </ul> 
  </div>
  <div class="module">
    <ul class="menu "><li></li>
      <li></li> 
    </ul>
  </div>
  <div class="module">
    <ul class="menu ">
      <li></li>
      <li></li>
    </ul>
  </div>
</footer>
 3
Author: li bing zhao, 2018-06-18 15:10:14

Você poderia usar o nth-of-type(1) mas certifique-se de que o site não precisa suportar o IE7 etc, Se este for o caso use o jQuery para adicionar classe de corpo, em seguida, encontrar o elemento via classe de corpo IE7, em seguida, o nome do elemento, em seguida, adicionar no nth-child styling para ele.

 2
Author: Jamie Paterson, 2013-06-03 12:59:17

Tenta isto.:

    .class_name > *:first-child {
        border: 1px solid red;
    }
 2
Author: Loy, 2016-08-04 22:06:52
Tenho este no meu projecto.

div > .b ~ .b:not(:first-child) {
	background: none;
}
div > .b {
    background: red;
}
<div>
      <p class="a">The first paragraph.</p>
      <p class="a">The second paragraph.</p>
      <p class="b">The third paragraph.</p>
      <p class="b">The fourth paragraph.</p>
  </div>
 2
Author: Yener Örer, 2018-01-31 07:02:47

As respostas acima são demasiado complexas.

.class:first-of-type { }

Isto irá seleccionar o primeiro tipo de classe. Fonte MDN

 2
Author: Gabriel Fair, 2018-06-28 13:53:43

Por alguma razão nenhuma das respostas acima parecia estar a abordar o caso de o primeiro Real e apenas o primeiro filho do Pai.

#element_id > .class_name:first-child

Todas as respostas acima falharão se você quiser aplicar o estilo apenas para a criança de primeira classe dentro deste código.

<aside id="element_id">
  Content
  <div class="class_name">First content that need to be styled</div>
  <div class="class_name">
    Second content that don't need to be styled
    <div>
      <div>
        <div class="class_name">deep content - no style</div>
        <div class="class_name">deep content - no style</div>
        <div>
          <div class="class_name">deep content - no style</div>
        </div>
      </div>
    </div>
  </div>
</aside>
 1
Author: Yavor Ivanov, 2018-06-18 15:08:56

Tente este simples e eficaz

 .home > span + .red{
      border:1px solid red;
    }
 0
Author: Friend, 2016-07-26 08:19:19

Tente esta solução:

 .home p:first-of-type {
  border:5px solid red;
  width:100%;
  display:block;
}
<div class="home">
  <span>blah</span>
  <p class="red">first</p>
  <p class="red">second</p>
  <p class="red">third</p>
  <p class="red">fourth</p>
</div>

Ligação do CodePen

 0
Author: Santosh Khalse, 2018-06-18 15:08:35

Só era preciso primeiro e apenas um parágrafo faz vermelho. Como?

<!DOCTYPE html><html><head><style>

article p:nth-child(1){background: red}
article p:first-child{background: red}

</style></head><body>

<p style="color:blue">Needed only first and only one paragraph had red. How?</p>

<article>
<p>The first paragraph.</p>
<div><p>The second paragraph.</p></div>
<p>The third paragraph.</p>
<div><p>The fourth paragraph.</p></div>
</article>

</body></html>
 0
Author: Alexander V. Ulyanov, 2018-07-15 17:48:05

Eu acredito que usar o selector relativo + para seleccionar os elementos colocados imediatamente a seguir, funciona aqui o melhor (como poucos sugeriram antes).

Também é possível para este caso usar este selector

.home p:first-of-type

Mas este é o selector de elementos e não a classe um.

Aqui tem uma bela lista de selectores CSS: https://kolosek.com/css-selectors/

 -1
Author: Nesha Zoric, 2018-04-11 06:47:01