Usando el selector de último hijo


106

Mi objetivo es aplicar CSS en el último li, pero no hace eso.

#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>

¿Cómo puedo seleccionar solo al último hijo?

Respuestas:


171

La :last-childpseudoclase aún no se puede usar de manera confiable en todos los navegadores. En particular, las versiones de Internet Explorer <9 y Safari <3.2 definitivamente no lo soportan , aunque Internet Explorer 7 y Safari 3.2 hacen de soporte :first-child, con curiosidad.

Su mejor last-childopción es agregar explícitamente una clase (o similar) a ese elemento y aplicar en su li.last-childlugar.


46
IE8 tampoco es compatible :last-child. Y no es que la curiosidad. :first-childes una pseudoclase CSS2, :last-childuna pseudoclase CSS3.
— mercator

92
last-child funciona en todos los navegadores modernos, lo que significa, por supuesto, que no funciona en ninguna versión de IE.
— Rob


6
@mercator Es curioso que: first-child se implementó en CSS2 pero: last-child se dejó hasta CSS3 ... parece bastante obvio agregarlos al mismo tiempo.
— Cobby

21
IE7 se niega a reconocer a otros niños bastardos
— Dewayne

76

Otra solución que podría funcionar para usted es invertir la relación. Por lo tanto, establecería el borde para todos los elementos de la lista. Luego, usaría first-child para eliminar el borde del primer elemento. El primer hijo es compatible estáticamente en todos los navegadores (lo que significa que no se puede agregar dinámicamente a través de otro código, pero el primer hijo es un selector de CSS2, mientras que el último hijo se agregó en la especificación CSS3)

Nota: Esto solo funciona de la manera que pretendía si solo tiene 2 elementos en la lista como su ejemplo. Se aplicarán bordes a cualquier tercer elemento en adelante.


2
+1 para pensar fuera de la caja :-) Acabo de convertir mis elementos del último hijo en el primer hijo y los cambié por el borde derecho a borde izquierdo para los separadores de menú. Ahora a IE8 le gusta mi css.
— Scott B

43

Si cree que puede usar Javascript, entonces, dado que es compatible con jQuery last-child, puede usar el método css de jQuery y lo bueno es que será compatible con casi todos los navegadores.

Código de ejemplo:

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

Puede encontrar más información aquí: http://api.jquery.com/css/#css2


8
Habla de sucio.
— md1337

95
Es mejor hacer algo así $("#nav li:last-child").addClass('last-child')para que puedas mantener tu estilo en tus hojas de estilo.
— jason

Es más limpia que la primera solución ya que se maneja automáticamente. Pero también estoy de acuerdo con Jason.
— Josh M.

1
En realidad, IE7 no carga una clase que tenga ambos div:last-childy div.last-child. Parece que considera que la :last-childsintaxis no es válida y no se aplicará ninguna clase con ese pseudo-selector.
— Josh M.

@Josh M .: Ese es el comportamiento correcto y esperado. Muy desafortunado, debería decir. Tendrías que duplicar la regla.
— BoltClock

19

Si el número de elementos de la lista es fijo, puede usar el selector adyacente, por ejemplo, si solo tiene tres <li>elementos, puede seleccionar el último <li>con:

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

3
Tu selector está mal. li + #nav liselecciona el liinterior #navque viene después li. Su selector debería ser simplemente #nav li + li + li.
— BoltClock

1
Eso es genial. Funciona bien en IE8, pero no en IE7.
— Mateng

13

Si se encuentra buscando con frecuencia selectores CSS3, siempre puede usar la biblioteca selectivizr en su sitio:

http://selectivizr.com/

Es un script JS que agrega soporte para casi todos los selectores CSS3 a navegadores que de otra manera no los admitirían.

Tíralo a tu <head>etiqueta con un condicional de IE:

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


0

Como alternativa al uso de una clase, puede usar una lista detallada, configurando los elementos dt secundarios para que tengan un estilo y los elementos dd secundarios para que tengan otro. Tu ejemplo se convertiría en:

#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>

Ninguno de los métodos es mejor que el otro y depende de las preferencias personales.


0

Otra forma de hacerlo es usar el selector de último hijo en jQuery y luego usar el método .css (). Sin embargo, esté cansado porque algunas personas todavía están en la edad de piedra usando navegadores con JavaScript desactivado.


0

¿Por qué no aplicar el borde en la parte inferior de la UL?

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

1
Si tiene padding-bottomen el <ul>elemento o margin-bottomen el último <li>elemento, este no tendrá la ubicación deseada de justo debajo del último <li>elemento. De lo contrario, esta es una buena solución.
— Wex

0

Si está flotando los elementos, puede invertir el orden

es decir, en float: right;lugar defloat: left;

Y luego use este método para seleccionar el primer hijo de una clase.

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

En realidad, esto está aplicando la clase a la ÚLTIMA instancia solo porque ahora está en orden inverso.

Aquí hay un ejemplo práctico para ti:

<!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

Es difícil decirlo sin ver el resto de su CSS, pero intente agregar !importantdelante del color del borde, para que sea así:

#refundReasonMenu #nav li:last-child
{
  border-bottom: 1px solid #b5b5b5 !important;
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.