¿Qué selectores de CSS3 realmente admite jQuery, por ejemplo: nth-last-child ()?

De acuerdo con http://api.jquery.com/category/selectors/ podemos usar una gran cantidad de selectores de CSS en jQuery, pero por ejemplo :nth-last-child() no se menciona allí. Sin embargo, cuando pruebo lo siguiente (con jQuery 1.7.1 desde Google), realmente funciona en Firefox, Chrome e IE 9, pero no en IE 9 en el modo de emulación IE 8:

 $('li:nth-last-child(2)').css('color', 'red'); 

¿Entonces que esta pasando? Parece que jQuery generó código CSS, como li:nth-last-child(2) { color: red } y de alguna manera lo inyectó, que luego funciona bien en navegadores compatibles con el selector utilizado. Pero eso sería extraño.

Lo que es más importante, ¿hay algún truco para que jQuery soporte tales selectores en todos los navegadores?

Si bien jQuery anuncia el cumplimiento del estándar de nivel 3 de Selectores en su página de inicio , no implementa completamente la especificación. En su propia documentación Selectores , aclara que “[toma prestados] de CSS 1-3, y luego [agrega] sus propios” selectores “. 1

A partir de jQuery 1.9, virtualmente todos los selectores en el nivel 3 son compatibles con Sizzle (su biblioteca de selector subyacente), con las siguientes excepciones:

  • jQuery no puede seleccionar ningún pseudo-elemento ya que son abstracciones basadas en CSS del árbol de documentos que no se pueden express a través del DOM .

  • jQuery no puede resolver pseudo-clases dinámicas, tales como :link / :visited para hipervínculos y :hover :active y :focus para la interacción del usuario. El último conjunto de pseudoclases, en particular, se basa en el estado y no está basado en eventos, por lo que necesita utilizar controladores de eventos en lugar de pseudoclases para ejecutar el código cuando los elementos entran y salen de estos estados. Vea esta respuesta para una explicación.

  • jQuery tampoco puede resolver los prefijos del espacio de nombres, ya que no admite el espacio de nombres en CSS .

Los siguientes selectores de nivel 3 se implementan en jQuery 1.9 y posterior , pero no en jQuery 1.8 o anterior 2 :

  • :target
  • :root
  • :nth-last-child()
  • :nth-of-type()
  • :nth-last-of-type()
  • :first-of-type
  • :last-of-type
  • :only-of-type

Adicionalmente:

  • :lang() , introducido en CSS2, también falta.

La razón por la que su selector parece funcionar en Firefox, Chrome e IE9 es porque jQuery primero pasa la cadena de selector a la implementación de document.querySelectorAll() nativo antes de volver a caer en Sizzle. Dado que es un selector de CSS válido, document.querySelectorAll() devolverá con éxito una lista de nodos para que jQuery lo utilice, obviando así el uso de Sizzle.

En caso de que document.querySelectorAll() falle, jQuery vuelve automáticamente a Sizzle. Hay varios escenarios que pueden hacer que falle:

  • El selector no es válido, no es compatible o no se puede usar (consulte la especificación de la API Selectores para obtener más información).

  • El método document.querySelectorAll() sí mismo no es compatible (jQuery realmente lo prueba con una simple statement if para que no falle en ese sentido de la palabra, pero se obtiene la imagen).

En su caso, aunque IE9 e IE8 implementan document.querySelectorAll() , IE8 no es compatible con :nth-last-child() . Dado que jQuery / Sizzle no implementa :nth-last-child() tampoco, no hay comportamiento de reserva para usar, lo que resulta en una falla completa en IE8.

Si no puede actualizar jQuery a 1.9 aunque sea al menos (la twig de versiones compatible con versiones anteriores), siempre puede usar las extensiones de selector personalizadas para implementar las pseudo-clases perdidas usted mismo. Sin embargo, dado que jQuery 1.9 agrega soporte para los selectores anteriores mientras se mantiene la compatibilidad con las versiones anteriores de IE, es mejor actualizar a esa versión como mínimo si necesita la compatibilidad.


1 Admite :contains() , se definió por última vez en esta antigua revisión de CR de la especificación antes de ser descartada posteriormente, y también se extiende :not() desde el estándar. Las diferencias entre la implementación de jQuery y el estándar actual están cubiertas en esta pregunta .

2 Algunos otros selectores (como los combinadores + y ~ hermanos,: :empty :lang() y algunos selectores de atributos CSS2) también se descartarían durante el desarrollo inicial de jQuery, solo porque John Resig no creía que nadie lo usara ellos . Casi todos ellos llegaron a la versión final después de que se hicieron disponibles más pruebas. :lang() fue el único que nunca lo incluyó en ninguna versión anterior a 1.9, como se indicó anteriormente.