Selector de CSS complejo para el padre del hijo activo


Answers

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.

Question

Esta pregunta ya tiene una respuesta aquí:

¿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í:

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




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).




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.




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 pestañas 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 ...

<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, puedes repetir ese patrón ... con más LI




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;
}



Related