Selector de CSS complejo para el padre del hijo activo

¿Hay alguna manera de seleccionar un elemento principal en función de la clase de un elemento secundario en la clase? El ejemplo que es relevante para mí en relación con la salida de HTML por un buen complemento de menú para http://drupal.org . El resultado se representa así:

 

Mi pregunta es si es posible o no aplicar un estilo al elemento de la lista que contiene el ancla con la clase activa. Obviamente, preferiría que el elemento de la lista se marque como activo, pero no tengo control del código que se produce. Podría realizar este tipo de cosas usando javascript (JQuery me viene a la mente), pero me preguntaba si hay una forma de hacerlo utilizando selectores de CSS.

Para que quede claro, quiero aplicar un estilo al elemento de la lista, no al delimitador.

Lamentablemente, no hay forma de hacerlo con CSS.

Sin embargo, no es muy difícil con JavaScript:

 // JavaScript code: document.getElementsByClassName("active")[0].parentNode; // jQuery code: $('.active').parent().get(0); // This would be the 's parent 
  • .
  • De acuerdo con Wikipedia :

    Los selectores no pueden ascender

    CSS no ofrece forma de seleccionar un padre o antecesor de elemento que satisfaga ciertos criterios. Un esquema de selector más avanzado (como XPath) habilitaría hojas de estilo más sofisticadas. Sin embargo, las principales razones por las cuales el Grupo de Trabajo de CSS rechaza las propuestas de selectores principales están relacionadas con el rendimiento del navegador y los problemas de representación incremental.

    Y para cualquier persona que busque SO en el futuro, esto también podría denominarse selector de ancestros.

    Actualizar:

    La especificación de Level 4 de Selectors le permite seleccionar qué parte de la selección es el tema:

    El sujeto del selector se puede identificar explícitamente anteponiendo un signo de dólar ($) a uno de los selectores compuestos en un selector. Aunque la estructura de elementos que representa el selector es la misma con o sin el signo de dólar, indicar el sujeto de esta manera puede cambiar qué selector compuesto representa el sujeto en esa estructura.

    Ejemplo 1:

    Por ejemplo, el siguiente selector representa un elemento de lista LI hijo único de una lista ordenada OL:

     OL > LI:only-child 

    Sin embargo, el siguiente representa una lista ordenada de OL que tiene un hijo único, ese hijo es un LI:

     $OL > LI:only-child 

    Las estructuras representadas por estos dos selectores son las mismas, pero los sujetos de los selectores no lo son.

    Aunque esto no está disponible (actualmente, noviembre de 2011) en ningún navegador o selector en jQuery.

    Tarde en la fiesta de nuevo, pero por lo que vale, es posible usar jQuery para ser un poco más conciso. En mi caso, necesitaba encontrar la etiqueta padre

      para una etiqueta contenida en el niño

    • . jQuery tiene el selector :has , por lo que es posible identificar un padre por los hijos que contiene (actualizado por ref. del comentario de @ Afrowave: https://api.jquery.com/has-selector/ ):

       $("ul").has("#someId") 

      seleccionará el elemento ul que tiene un elemento hijo con id someId . O para responder a la pregunta original, algo como lo siguiente debería ser el truco (no probado):

       $("li").has(".active") 

      EL SELECTOR “PADRE”

      En este momento, no hay opción para seleccionar el elemento principal de un elemento en CSS (ni siquiera CSS3). Pero con CSS4 , la noticia más importante en el borrador actual del W3C es el soporte para el selector principal.

       $ul li:hover{ background: #fff; } 

      Usando lo anterior, al pasar un elemento de lista, toda la lista desordenada se resaltará al agregarle un fondo blanco.

      Documentación oficial: https://www.w3.org/TR/2011/WD-selectors4-20110929/#overview (última fila).

      El primer borrador de Selectores Nivel 4 describe una forma de establecer explícitamente el tema de un selector. Esto le permitiría al OP $li > a.active el elemento de lista con el selector $li > a.active

      De la determinación del tema de un selector :

      Por ejemplo, el siguiente selector representa un elemento de lista LI hijo único de una lista ordenada OL:

      OL > LI:only-child

      Sin embargo, el siguiente representa una lista ordenada de OL que tiene un hijo único, ese hijo es un LI:

      $OL > LI:only-child

      Las estructuras representadas por estos dos selectores son las mismas, pero los sujetos de los selectores no lo son.

      Editar: teniendo en cuenta qué tan “stream de air” puede ser una especificación de borrador, es mejor controlar esto al consultar la página del CSSWG en el nivel 4 de selectores .

      Tuve el mismo problema con Drupal. Dadas las limitaciones de CSS, la forma de hacerlo funcionar es agregar la clase “activa” a los elementos principales cuando se genera el menú HTML. Hay una buena discusión de esto en http://drupal.org/node/219804 , cuyo resultado es que esta funcionalidad se ha incorporado a la versión 6.x-2.x del módulo nicemenus. Como esto todavía está en desarrollo, copié el parche en 6.x-1.3 en http://drupal.org/node/465738 para poder continuar utilizando la versión del módulo lista para producción.

      Muchas personas respondieron con el padre de jQuery , pero para agregarlo, quería compartir un fragmento de código rápido que uso para agregar clases a mis dispositivos de navegación, así puedo agregar estilo a los que solo tienen submenús y no es que no.

       $("li ul").parent().addClass('has-sub'); 

      De hecho, me encontré con el mismo problema que el cartel original. Hay una solución simple de simplemente usar el selector jQuery .parent() . Mi problema era que estaba usando .parent lugar de .parent() . Estúpido error, lo sé.

      Vincula los eventos (en este caso, ya que mis tabs están en modo modal, necesito unirlas con .live lugar de un .click básico .click .

       $('#testTab1 .tabLink').live('click', function() { $('#modal ul.tabs li').removeClass("current"); //Remove any "current" class $(this).parent().addClass("current"); //Add "current" class to selected tab $('#modal div#testTab1 .tabContent').hide(); $(this).next('.tabContent').fadeIn(); return false; }) $('#testTab2 .tabLink').live('click', function() { $('#modal ul.tabs li').removeClass("current"); //Remove any "current" class $(this).parent().addClass("current"); //Add "current" class to selected tab $('#modal div#testTab2 .tabContent').hide(); $(this).next('.tabContent').fadeIn(); return false; }) 

      Aquí está el HTML …

        

      Por supuesto, puedes repetir ese patrón … con más LI

      Si bien es cierto que CSS no puede ASCEND, es incorrecto que no puedas tomar el elemento padre de otro elemento. Permíteme reiterar:

      Usando su código de ejemplo HTML, puede tomar el li sin especificar li

       ul * a { property:value; } 

      En este ejemplo, el ul es el padre de algún elemento y ese elemento es el padre del ancla. La desventaja de usar este método es que si hay un ul con cualquier elemento secundario que contenga un anclaje, heredará los estilos especificados.

      También puede usar el selector de niños, ya que tendrá que especificar el elemento principal de todos modos.

       ul>li a { property:value; } 

      En este ejemplo, el anclaje debe ser un descendiente de un li que DEBE ser hijo de ul, lo que significa que debe estar dentro del árbol que sigue a la statement ul. Esto va a ser un poco más específico y solo obtendrá un elemento de la lista que contenga un ancla Y sea un hijo de ul.

      ASÍ, para responder su pregunta por código.

       ul.menu > li a.active { property:value; } 

      Esto debería capturar el ul con la clase del menú, y el elemento de la lista infantil que contiene solo un ancla con la clase de activo.

      Se me acaba de ocurrir otro pensamiento que podría ser una solución pura de CSS. Muestra tu clase activa como un bloque absolutamente posicionado y configura su estilo para cubrir el li padre.

       a.active { position:absolute; display:block; width:100%; height:100%; top:0em; left:0em; background-color: whatever; border: whatever; } /* will also need to make sure the parent li is a positioned element so... */ ul.menu li { position:relative; } 

      Para aquellos de ustedes que quieran usar javascript sin jquery …

      Seleccionar el padre es trivial. Necesita una función getElementsByClass de algún tipo, a menos que pueda obtener su complemento drupal para asignarle a la partida activa una ID en lugar de Class. La función que brindé la agarré de otro genio en SO. Funciona bien, solo tenga en cuenta cuando esté depurando que la función siempre devolverá una matriz de nodos, no solo un solo nodo.

       active_li = getElementsByClass("active","a"); active_li[0].parentNode.style.whatever="whatever"; function getElementsByClass(node,searchClass,tag) { var classElements = new Array(); var els = node.getElementsByTagName(tag); // use "*" for all elements var elsLen = els.length; var pattern = new RegExp("\\b"+searchClass+"\\b"); for (i = 0, j = 0; i < elsLen; i++) { if ( pattern.test(els[i].className) ) { classElements[j] = els[i]; j++; } } return classElements; }