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?

Miral
fuente

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.

VoteyDisciple
fuente
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
25
Fyi, IE 9 admite:last-child .
Jari Keinänen
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.

Branden Silva
fuente
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

Tarik
fuente
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;
}
ccpizza
fuente
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]-->
nzifnab
fuente
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.

lexx
fuente
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.

ecollis6
fuente
0

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

#refundReasonMenu #nav ul
{
    border-bottom: 1px solid #b5b5b5;
}
Chuleta de cerdo
fuente
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>
Ozzy
fuente
-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;
}
registro de cambios
fuente