Pregunta

Esta pregunta ya tiene respuesta aquí:

¿Hay alguna manera de seleccionar un elemento principal según la clase de un elemento secundario en la clase?El ejemplo que es relevante para mí relacionado con la salida HTML mediante un bonito complemento de menú para http://drupal.org.La salida se muestra así:

<ul class="menu">  
    <li>  
        <a class="active">Active Page</a>  
    </li>  
    <li>    
        <a>Some Other Page</a>  
    </li>  
</ul>  

Mi pregunta es si es posible 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 esté marcado como activo, pero no tengo control del código que se produce.Podría realizar este tipo de cosas usando javascript (me viene a la mente JQuery), pero me preguntaba si hay una manera de hacerlo usando selectores CSS.

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

¿Fue útil?

Solución

Desafortunadamente, no hay manera de hacer eso 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 <a>'s parent <li>.

Otros consejos

Según Wikipedia:

Los selectores no pueden ascender.

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

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

Actualizar:

El Selectores Nivel 4 Especificaciones le permite seleccionar qué parte de la selección es el tema:

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

Ejemplo 1:

Por ejemplo, el siguiente selector representa un elemento de lista Li niño único de una lista ordenada OL:

OL > LI:only-child

Sin embargo, el siguiente representa una lista ordenada de tener un hijo único, ese niño 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 ni como selector en jQuery.

Llega tarde a la fiesta otra vez, pero por si sirve de algo, es posible usar jQuery para ser un poco más conciso.En mi caso necesitaba encontrar el <ul> etiqueta principal para un <span> etiqueta contenida en el niño <li>.jQuery tiene la :has selector para que sea posible identificar a un padre por los hijos que contiene (actualizado según la referencia del comentario de @Afrowave: https://api.jquery.com/has-selector/):

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

seleccionará el ul elemento que tiene un elemento hijo con id algún ID.O para responder a la pregunta original, algo como lo siguiente debería funcionar (no probado):

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

EL SELECTOR “PADRE”

En este momento, no hay ninguna opción para seleccionar el padre 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 el cursor sobre un elemento de la lista, toda la lista desordenada se resaltará agregándole 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 manera de establecer explícitamente el sujeto de un selector.Esto permitiría al OP diseñar el elemento de la lista con el selector $li > a.active

De Determinar el 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 OL que tiene un hijo único, siendo ese hijo 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:Dado lo "borrador" que puede ser un borrador de especificación, es mejor estar al tanto de esto revisando el Página de CSSWG sobre selectores de nivel 4.

Respuesta futura con selectores CSS4

Las nuevas especificaciones CSS contienen una versión experimental. :has pseudo selector que podría ser capaz de hacer esto.

li:has(a:active) {
  /* ... */
}

El soporte del navegador sobre esto es básicamente inexistente en este momento, pero se está considerando en el especificaciones oficiales.


Respuesta en 2012 que estaba equivocada en 2012 y está aún más equivocada en 2018

Si bien es cierto que CSS no puede ASCENDIR, es incorrecto que no se pueda tomar el elemento padre de otro elemento.Déjame reiterar:

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

ul * a {
    property:value;
}

En este ejemplo, 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 algún elemento secundario que contiene un ancla, hereda los estilos especificados.

También puede utilizar el selector secundario, ya que de todos modos tendrá que especificar el elemento principal.

ul>li a {
    property:value;
}

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

Entonces, para responder a tu pregunta por código.

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

Esto debería tomar la ul con la clase de menú y el elemento de la lista secundaria que contiene solo un ancla con la clase activa.

Tuve el mismo problema con Drupal.Dadas las limitaciones de CSS, la forma de hacer que esto funcione es agregar la clase "activa" a los elementos principales cuando se genera el menú HTML.Hay una buena discusión sobre esto en http://drupal.org/node/219804, el 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, he respaldado el parche a 6.x-1.3 en http://drupal.org/node/465738 para poder seguir usando la versión lista para producción del módulo.

Mucha gente respondió con jQuery padre, pero solo para agregar a eso, quería compartir un fragmento rápido de código que uso para agregar clases a mis navegadores para poder agregar estilo a lies que solo tienen submenús y no liEs 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 .parent() Selector jQuery.Mi problema era que estaba usando .parent en lugar de .parent().Error estúpido, lo sé.

Vincular los eventos (en este caso, dado que mis pestañas están en modal, necesitaba vincularlas con .live en lugar de un 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...

<div id="tabView1" style="display:none;">
  <!-- start: the code for tabView 1 -->
  <div id="testTab1" style="width:1080px; height:640px; position:relative;">
    <h1 class="Bold_Gray_45px">Modal Header</h1>
    <div class="tabBleed"></div>
    <ul class="tabs">
      <li class="current"> <a href="#" class="tabLink" id="link1">Tab Title Link</a>
        <div class="tabContent" id="tabContent1-1">
          <div class="modalCol">
            <p>Your Tab Content</p>
            <p><a href="#" class="tabShopLink">tabBased Anchor Link</a> </p>
          </div>
          <div class="tabsImg"> </div>
        </div>
      </li>
      <li> <a href="#" class="tabLink" id="link2">Tab Title Link</a>
        <div class="tabContent" id="tabContent1-2">
          <div class="modalCol">
            <p>Your Tab Content</p>
            <p><a href="#" class="tabShopLink">tabBased Anchor Link</a> </p>
          </div>
          <div class="tabsImg"> </div>
        </div>
      </li>
    </ul>
  </div>
</div>

Por supuesto que puedes repetir ese patrón... con más LI.

Hace un momento se me ocurrió otra idea que podría ser una solución CSS pura.Muestre su clase activa como un bloque absolutamente posicionado y establezca su estilo para cubrir el li principal.

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.Tu necesitas un getElementsByClass función de algún tipo, a menos que pueda hacer que su complemento drupal asigne al elemento activo una ID en lugar de Clase.La función que proporcioné la tomé de algún otro genio en SO.Funciona bien, solo tenga en cuenta cuando esté depurando que la función siempre devolverá una serie de nodos, no solo un 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;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top