Usando o seletor do último filho


106

Meu objetivo é aplicar o CSS no último li, mas não faz isso.

#refundReasonMenu #nav li:last-child {
    border-bottom: 1px solid #b5b5b5;
}
<div id="refundReasonMenu">
    	<ul id="nav">
    		<li><a id="abc" href="#">abcde</a></li>
    		<li><a id="def" href="#">xyz</a></li>
    	</ul>
    </div>

Como posso selecionar apenas o último filho?

Respostas:


171

A :last-childpseudoclasse ainda não pode ser usada de forma confiável em todos os navegadores. Em particular, as versões do Internet Explorer <9 e Safari <3,2 definitivamente não apoiá-lo , embora o Internet Explorer 7 e Safari 3.2 fazer apoio:first-child , curiosamente.

Sua melhor aposta é adicionar explicitamente uma last-childclasse (ou similar) a esse item e aplicar em seu li.last-childlugar.


46
O IE8 também não oferece suporte :last-child. E não é que curioso. :first-childé uma pseudoclasse CSS2, :last-childuma pseudoclasse CSS3.
mercator de

92
O último filho funciona em todos os navegadores modernos, o que significa, é claro, não funciona em nenhuma versão do IE.
Rob


6
@mercator É curioso que: first-child foi implementado em CSS2, mas: last-child foi deixado para CSS3 ... parece bastante óbvio adicioná-los ao mesmo tempo.
Cobby

21
IE7 se recusa a reconhecer outros filhos bastardos
Dewayne

76

Outra solução que pode funcionar para você é reverter o relacionamento. Portanto, você definiria a borda para todos os itens da lista. Em seguida, você usaria o primeiro filho para eliminar a borda do primeiro item. O primeiro filho é estaticamente compatível com todos os navegadores (o que significa que não pode ser adicionado dinamicamente por meio de outro código, mas o primeiro filho é um seletor CSS2, enquanto o último filho foi adicionado na especificação CSS3)

Nota: Isso só funciona da maneira desejada se você tiver apenas 2 itens na lista como o seu exemplo. Qualquer terceiro item em diante terá bordas aplicadas a eles.


2
+1 para o pensamento pronto para uso :-) Acabei de converter meus elementos do último filho em primeiro filho e alterei de border-right para border-left para separadores de menu. Agora o IE8 gosta do meu css.
Scott B,

43

Se você acha que pode usar Javascript, então, desde o suporte jQuery last-child, você pode usar o método css do jQuery e, a boa coisa, ele suportará quase todos os navegadores

Código de exemplo:

$(function(){
   $("#nav li:last-child").css("border-bottom","1px solid #b5b5b5")
})

Você pode encontrar mais informações sobre aqui: http://api.jquery.com/css/#css2


8
Fale sobre sujo.
md1337

95
É melhor fazer algo assim, $("#nav li:last-child").addClass('last-child')para manter seu estilo nas folhas de estilo.
Jason,

Isso é mais limpo do que a primeira solução, pois é tratado automaticamente. Mas também concordo com Jason.
Josh M.

1
Na verdade, o IE7 não carrega uma classe que tenha div:last-childe div.last-child. Parece que ele considera a :last-childsintaxe inválida e qualquer classe com esse pseudo-seletor não será aplicada.
Josh M.

@Josh M .: Esse é um comportamento correto e esperado. Muito lamentável, devo dizer. Você teria que duplicar a regra.
BoltClock

19

Se o número de itens da lista for fixo, você pode usar o seletor adjacente, por exemplo, se você tiver apenas três <li>elementos, você pode selecionar o último <li>com:

#nav li+li+li {
    border-bottom: 1px solid #b5b5b5;
}

3
Seu seletor está errado. li + #nav liseleciona lidentro #navque vem depois li. Seu seletor deve simplesmente ser #nav li + li + li.
BoltClock

1
Isso é bacana. Funciona bem no IE8, mas não no IE7.
Mateng

13

Se você costuma desejar seletores CSS3, poderá usar a biblioteca selectivizr em seu site:

http://selectivizr.com/

É um script JS que adiciona suporte para quase todos os seletores CSS3 para navegadores que de outra forma não os suportariam.

Jogue-o em sua <head>tag com uma condicional do IE:

<!--[if (gte IE 6)&(lte IE 8)]>
  <script src="/js/selectivizr-min.js" type="text/javascript"></script>
<![endif]-->


0

Como alternativa ao uso de uma classe, você pode usar uma lista detalhada, definindo os elementos filho dt para ter um estilo e os elementos filhos dd para ter outro. Seu exemplo seria:

#refundReasonMenu #nav li:dd
{
  border-bottom: 1px solid #b5b5b5;
}

html:

<div id="refundReasonMenu">
  <dl id="nav">
        <dt><a id="abc" href="#">abcde</a></dt>
        <dd><a id="def" href="#">xyz</a></dd>
  </dl>
</div>

Nenhum método é melhor do que o outro e é apenas uma questão de preferência pessoal.


0

Outra maneira de fazer isso é usar o seletor do último filho no jQuery e, em seguida, usar o método .css (). Porém, esteja cansado porque algumas pessoas ainda estão na idade da pedra usando navegadores com JavaScript desabilitado.


0

Por que não aplicar a borda na parte inferior do UL?

#refundReasonMenu #nav ul
{
    border-bottom: 1px solid #b5b5b5;
}

1
Se você tiver padding-bottomno <ul>elemento ou margin-bottomno último <li>elemento, ele não terá o posicionamento desejado logo abaixo do último <li>elemento. Caso contrário, esta é uma boa solução.
Wex

0

Se você estiver flutuando os elementos, você pode inverter a ordem

ou seja, em float: right;vez defloat: left;

E então use este método para selecionar o primeiro filho de uma classe.

/* 1: Apply style to ALL instances */
#header .some-class {
  padding-right: 0;
}
/* 2: Remove style from ALL instances except FIRST instance */
#header .some-class~.some-class {
  padding-right: 20px;
}

Na verdade, isso está aplicando a classe à ÚLTIMA instância apenas porque agora está na ordem reversa.

Aqui está um exemplo prático para você:

<!doctype html>
<head><title>CSS Test</title>
<style type="text/css">
.some-class { margin: 0; padding: 0 20px; list-style-type: square; }
.lfloat { float: left; display: block; }
.rfloat { float: right; display: block; }
/* apply style to last instance only */
#header .some-class {
  border: 1px solid red;
  padding-right: 0;
}
#header .some-class~.some-class {
  border: 0;
  padding-right: 20px;
}
</style>
</head>
<body>
<div id="header">
  <img src="some_image" title="Logo" class="lfloat no-border"/>
  <ul class="some-class rfloat">
    <li>List 1-1</li>
    <li>List 1-2</li>
    <li>List 1-3</li>
  </ul>
  <ul class="some-class rfloat">
    <li>List 2-1</li>
    <li>List 2-2</li>
    <li>List 2-3</li>
  </ul>
  <ul class="some-class rfloat">
    <li>List 3-1</li>
    <li>List 3-2</li>
    <li>List 3-3</li>
  </ul>
  <img src="some_other_img" title="Icon" class="rfloat no-border"/>
</div>
</body>
</html>

-2

É difícil dizer sem ver o resto do seu CSS, mas tente adicionar !importantantes da cor da borda, para torná-lo assim:

#refundReasonMenu #nav li:last-child
{
  border-bottom: 1px solid #b5b5b5 !important;
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.