hijos css css-selectors

selector de hijos css



Selector de CSS complejo para padre de hijo activo (10)

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


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


El primer borrador del Nivel 4 de selectores describe una manera de establecer explícitamente el tema de un selector. Esto permitiría al OP $li > a.active estilo al 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 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.

Edición: dado que el borrador de una especificación de borrador puede ser, es mejor mantenerse al tanto de esto revisando la página de CSSWG en el nivel 4 de selectores .


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


Muchas personas respondieron con jQuery parent, pero solo para agregar a eso quería compartir un fragmento rápido de código que utilizo para agregar clases a mis navegadores para poder agregar estilos a li ''s que solo tienen submenús y no li Es que no

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


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


Si bien es cierto que CSS no puede ASCENDER, es incorrecto que no pueda capturar el elemento principal de otro elemento. Permítanme reiterar:

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

ul * a { property:value; }

En este ejemplo, la 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 una ul con cualquier elemento secundario que contiene un ancla, hereda los estilos especificados.

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

ul>li a { property:value; }

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

Por lo tanto, para responder a su pregunta por código.

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

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


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.


Vuelve tarde a la fiesta, pero por lo que vale la pena, es posible que jQuery sea un poco más conciso. En mi caso, necesitaba encontrar la etiqueta principal <ul> para una etiqueta <span> contenida en el elemento secundario <li> . jQuery tiene el :has selector para que sea posible identificar a un padre por los hijos que contiene (actualizado por el comentario de @Afrowave ref: https://api.jquery.com/has-selector/ ):

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

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

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


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.