css-selectors Selector de CSS complejo para padre de hijo activo



5 Answers

Según Wikipedia :

Los selectores no pueden ascender

CSS no ofrece ninguna forma de seleccionar un elemento primario o ancestro que satisfaga ciertos criterios. Un esquema de selección más avanzado (como XPath) habilitaría hojas de estilo más sofisticadas. Sin embargo, los motivos principales por los que el Grupo de trabajo de CSS rechazó las propuestas para los selectores principales están relacionados 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 antecesores.

Actualizar:

Los selectores de nivel 4 le permiten seleccionar qué parte de la selección es el tema:

El tema 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 que 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 como 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, 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 no está disponible (actualmente, noviembre de 2011) en ningún navegador o como selector en jQuery.

css css-selectors

Esta pregunta ya tiene una respuesta aquí:

¿Hay una manera de seleccionar un elemento padre basado en la clase de un elemento hijo en la clase? El ejemplo que es relevante para mí relacionado con la salida HTML por un complemento de menú agradable para http://drupal.org La salida se renderiza 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 o no aplicar un estilo al elemento de la lista que contiene el ancla con la clase activa en él. Obviamente, prefiero 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 utilizando javascript (JQuery me viene a la mente), pero me preguntaba si hay una forma de hacerlo mediante los selectores de CSS.

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




EL SELECTOR DE “PADRES”

En este momento, no hay ninguna opción para seleccionar el elemento primario 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 lista, toda la lista sin ordenar se resaltará agregándole un fondo blanco.

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




Tuve el mismo problema con Drupal. Dadas las limitaciones de CSS, la manera 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 de esto en http://drupal.org/node/219804 , cuyo resultado final 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 implementado el parche en versión 6.x-1.3 en http://drupal.org/node/465738 para poder seguir utilizando la versión del módulo preparada para la producción.




En realidad me encontré con el mismo problema que el cartel original. Hay una solución simple de solo usar .parent() jQuery selector. Mi problema era que estaba usando .parent lugar de .parent() . Error estúpido lo sé.

Enlazar los eventos (en este caso, ya que mis pestañas están en Modal, necesitaba unirlas con .live lugar de un .click básico.

$('#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




Se me ocurrió otra idea ahora mismo que podría ser una solución CSS pura. 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 quieren usar javascript sin jquery ...

La selección del padre es trivial. Necesita una función getElementsByClass de algún tipo, a menos que pueda hacer que su complemento drupal le asigne una identificación al elemento activo en lugar de a Class. 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 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;
}



Related