¿Hay un selector padre CSS?

3178

¿Cómo selecciono el <li>elemento que es un padre directo del elemento de anclaje?

Como ejemplo, mi CSS sería algo como esto:

li < a.active {
    property: value;
}

Obviamente, hay formas de hacerlo con JavaScript, pero espero que exista algún tipo de solución nativa para CSS Nivel 2.

El menú que estoy tratando de diseñar está siendo expulsado por un CMS, por lo que no puedo mover el elemento activo al <li>elemento ... (a menos que tema el módulo de creación de menú que prefiero no hacer).

¿Algunas ideas?

jcuenod
fuente

Respuestas:

2535

Actualmente no hay forma de seleccionar el elemento primario de un elemento en CSS.

Si hubiera una manera de hacerlo, estaría en cualquiera de las especificaciones actuales de los selectores CSS:

Dicho esto, el borrador de trabajo de nivel 4 del Selector incluye una :has()pseudoclase que proporcionará esta capacidad. Será similar a la implementación de jQuery .

li:has(> a.active) { /* styles to apply to the li tag */ }

Sin embargo, a partir de mayo de 2020, esto todavía no es compatible con ningún navegador .

Mientras tanto, tendrá que recurrir a JavaScript si necesita seleccionar un elemento principal.

Dan Herbert
fuente
68
Parece que ya ha sido sugerido y rechazado: stackoverflow.com/questions/45004/…
RobM
14
Parece que el selector de temas ha sido revisado, excepto mediante el uso de un !ahora:The subject of the selector can be explicitly identified by appending an exclamation mark (!) to one of the compound selectors in a selector.
animuson
13
El prepended se $veía mejor para mí ... el apéndice !se puede pasar por alto más fácilmente.
Christoph
51
¡Gran giro de la trama! El Selector 4 WD se acaba de actualizar hoy para excluir el indicador de tema del perfil rápido, que se utilizará en las implementaciones de CSS. Si este cambio persiste, significa que ya no podrá usar el indicador de asunto en las hojas de estilo (a menos que agregue algún tipo de polyfill como el que se describe en otra respuesta ): solo puede usarlo con la API de selectores y en cualquier lugar de lo contrario, se puede implementar el perfil completo.
BoltClock
55
Otra actualización importante: parece que están considerando eliminar la sintaxis del selector de temas por completo y reemplazarla con el :has()pseudo que todos han llegado a conocer y amar de jQuery. El último ED ha eliminado todas las referencias al indicador de sujeto y lo reemplazó con el :has()pseudo. No sé las razones exactas, pero el CSSWG realizó una encuesta hace algún tiempo y los resultados deben haber influido en esta decisión. Lo más probable es que sea compatible con jQuery (por lo que puede aprovechar qSA sin modificaciones) y porque la sintaxis del indicador de sujeto resultó demasiado confusa.
BoltClock
152

No creo que pueda seleccionar el padre solo en CSS.

Pero como ya parece tener una .activeclase, sería más fácil mover esa clase al li(en lugar del a). De esta manera se puede acceder tanto al liy la avía única CSS.

jeroen
fuente
44
No puede cambiar el pseudo selector al elemento de la lista, ya que no es un elemento enfocable. Está usando el selector activo, por lo que cuando el ancla está activa quiere que el elemento de la lista se vea afectado. Los elementos de la lista nunca estarán en el estado activo. Por otro lado, es lamentable que dicho selector no exista. Obtener un menú CSS puro para que sea totalmente accesible desde el teclado parece imposible sin él (usando los selectores hermanos puede hacer que aparezcan submenús creados usando listas anidadas, pero una vez que la lista gana el foco, se vuelve a ocultar). Si hay soluciones solo de CSS para esta conun particular
12
@Dominic Aquilina Eche un vistazo a la pregunta, el OP está utilizando una clase, no un pseudo-selector.
jeroen
125

Puedes usar este script :

*! > input[type=text] { background: #000; }

Esto seleccionará cualquier padre de una entrada de texto. Pero espera, todavía hay mucho más. Si lo desea, puede seleccionar un padre específico:

.input-wrap! > input[type=text] { background: #000; }

O selecciónelo cuando esté activo:

.input-wrap! > input[type=text]:focus { background: #000; }

Mira este HTML:

<div class="input-wrap">
    <input type="text" class="Name"/>
    <span class="help hide">Your name sir</span>
</div>

Puede seleccionar eso span.helpcuando el inputestá activo y mostrarlo:

.input-wrap! .help > input[type=text]:focus { display: block; }

Hay muchas más capacidades; solo echa un vistazo a la documentación del complemento.

Por cierto, funciona en Internet Explorer.

Idered
fuente
55
supongamos que usar jquery patent()sería más rápido. Sin embargo, esto necesita pruebas
Dan
2
@Idered Falla cuando tiene la declaración CSS de un Asunto selector sin un selector secundario ( #a!solo arroja un error, #a! pfunciona), por lo que los demás tampoco funcionarán debido a Uncaught TypeError: Cannot call method 'split' of undefined: ver jsfiddle.net/HerrSerker/VkVPs
yunzen
3
@HerrSerker Creo que #a! es un selector no válido, ¿qué debería seleccionar?
Leí el
2
@Idered no lo sé. La especificación no dice que sea ilegal. #¡una! debe seleccionarse a sí mismo. Al menos no debería haber ningún error en el JavaScript
yunzen
55
Según mi comentario sobre la respuesta aceptada, parece que el polyfill puede ser requerido incluso en un futuro cercano después de todo, porque el indicador de tema nunca puede ser implementado por los navegadores en CSS.
BoltClock
108

Como lo mencionaron algunos otros, no hay una manera de diseñar el / los padre / s de un elemento usando solo CSS, pero lo siguiente funciona con jQuery :

$("a.active").parents('li').css("property", "value");
zcrar70
fuente
21
El <selector no existe (verificado con jQuery 1.7.1).
Rob W
66
Quizás esa <sintaxis funcionó en 2009, pero la actualicé (para 2013).
Alastair
55
Mejor aún, utilizar una función de jQuery :has()selector de : $("li:has(a.active)").css("property", "value");. Se lee de manera similar al !selector propuesto por CSS 4 . Ver también: :parentselector , .parents()método , .parent()método .
Rory O'Kane
77
Y en lugar de usar .css("property", "value")para dar estilo a los elementos seleccionados, por lo general, debe .addClass("someClass")tener en su CSS .someClass { property: value }( vía ). De esa manera, puede anotar el estilo con toda la potencia de CSS y cualquier preprocesador que esté utilizando.
Rory O'Kane
69

No hay selector de padres; tal como no hay un selector de hermanos anterior. Una buena razón para no tener estos selectores es porque el navegador tiene que recorrer todos los elementos secundarios de un elemento para determinar si una clase debe aplicarse o no. Por ejemplo, si escribiste:

body:contains-selector(a.active) { background: red; }

Luego, el navegador tendrá que esperar hasta que se haya cargado y analizado todo hasta </body>determinar si la página debe estar roja o no.

El artículo Por qué no tenemos un selector principal lo explica en detalle.

Salman A
fuente
11
así que haz el navegador más rápido. Internet en sí más rápido. Este selector es definitivamente necesario, y la razón para no implementarlo es, lamentablemente, porque vivimos en un mundo lento y primitivo.
vsync
11
en realidad, el selector haría que un navegador muy rápido parezca lento.
Salman A
55
Confío en que los desarrolladores de navegadores propongan una implementación que sea (al menos) tan rápida como la versión de JavaScript, que es la que las personas utilizan de todos modos.
Marc.2377
"vivimos en un mundo lento y primitivo" tos tos nueva tos del
Marvin
@ Marc.2377 Si prueba el ejemplo anterior en JS en su sitio web, nunca lo visitaré. Por otro lado, diría que la mayoría de las veces, solo te importan los niños inmediatos, por lo que si solo se limitara a los niños inmediatos, sería una buena adición sin demasiado impacto.
xryl669
54

No hay una manera de hacer esto en CSS 2. Puede agregar la clase al liy hacer referencia a a:

li.active > a {
    property: value;
}
Josh
fuente
3
haciendo que se muestre un elemento: bloque, puede diseñarlo para que se ajuste a toda el área li. Si puede explicar qué estilo está buscando, tal vez podría ayudarlo con una solución.
Josh
Esta es realmente una solución simple y elegante y, en muchos casos, tiene sentido establecer la clase en el padre.
Ricardo
35

Intente cambiar aa la blockpantalla y luego use el estilo que desee. El aelemento llenará el lielemento y podrá modificar su aspecto como desee. No olvide establecer el lirelleno en 0.

li {
  padding: 0;
  overflow: hidden;
}
a {
  display: block;
  width: 100%;
  color: ..., background: ..., border-radius: ..., etc...
}
a.active {
  color: ..., background: ...
}
Raseko
fuente
31

El selector CSS " General Sibling Combinator " podría usarse para lo que desea:

E ~ F {
    property: value;
}

Esto coincide con cualquier Felemento precedido por un Eelemento.

cobaasta
fuente
24
Esto es solo un selector de hermanos, no es niño, padre ... realmente no responde a la pregunta compañero
Alireza
26

No en CSS 2, que yo sepa. CSS 3 tiene selectores más robustos pero no se implementa consistentemente en todos los navegadores. Incluso con los selectores mejorados, no creo que logre exactamente lo que ha especificado en su ejemplo.

Mark Hurd
fuente
24

Sé que el OP estaba buscando una solución CSS, pero es fácil de lograr con jQuery. En mi caso, necesitaba encontrar la <ul>etiqueta padre para una <span>etiqueta contenida en el niño <li>. jQuery tiene el :hasselector para que sea posible identificar a un padre por los hijos que contiene:

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

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

$("li:has(.active)")
David Clarke
fuente
3
O use $yourSpan.closest("ul")y obtendrá el UL padre de su elemento span. Sin embargo, su respuesta es completamente offtopic en mi humilde opinión. Podemos responder a todas las preguntas con CSS-CSS con una solución jQuery.
Robin van Baalen
1
Como se identificó en otras respuestas, no hay forma de hacer esto usando CSS 2. Dada esa restricción, la respuesta que proporcioné es una que sé que es efectiva y es la forma más simple de responder la pregunta usando javascript imho.
David Clarke
Dados sus votos positivos, algunas personas están de acuerdo con usted. Pero la única respuesta sigue siendo la aceptada; simple y llanamente "no se puede hacer de la manera que lo desee". Si la pregunta es cómo archivar 60 mph en una bicicleta y la responde con "simple; suba a un automóvil y acelere", aún no es una respuesta. De ahí mi comentario.
Robin van Baalen
1
Ese enfoque haría SO casi completamente inútil. Busco SO para resolver problemas y no encontrar la "única respuesta" que no resuelve el problema. Es por eso que SO es tan increíble, porque siempre hay más de una forma de desollar a un gato.
David Clarke
23

El pseudo elemento :focus-withinpermite seleccionar un padre si un descendiente tiene foco.

Un elemento puede enfocarse si tiene un tabindexatributo.

Soporte de navegador para foco dentro

Tabindex

Ejemplo

.click {
  cursor: pointer;
}

.color:focus-within .change {
  color: red;
}

.color:focus-within p {
  outline: 0;
}
<div class="color">
  <p class="change" tabindex="0">
    I will change color
  </p>
  <p class="click" tabindex="1">
    Click me
  </p>
</div>

Sol
fuente
2
Esto funciona bien en mi caso, ¡gracias! Simplemente no, el ejemplo sería más ilustrativo si cambia el color al padre, no al hermano, esto se reemplaza .color:focus-within .changecon .color:focus-within. En mi caso, estoy usando la barra de navegación de arranque que agrega la clase a los niños cuando está activa y quiero agregar una clase a la barra principal .nav. Creo que este es un escenario bastante común en el que soy propietario del marcado, pero el componente css + js es bootstrap (u otro), por lo que no puedo cambiar el comportamiento. Aunque puedo agregar tabindex y usar este css. ¡Gracias!
cancerbero
22

Este es el aspecto más discutido de la especificación Selectores Nivel 4 . Con esto, un selector podrá diseñar un elemento de acuerdo con su elemento secundario utilizando un signo de exclamación después del selector dado (!).

Por ejemplo:

body! a:hover{
   background: red;
}

establecerá un color de fondo rojo si el usuario se desplaza sobre cualquier ancla.

Pero tenemos que esperar la implementación de los navegadores :(

Marco Allori
fuente
21

Puede intentar usar el hipervínculo como padre y luego cambiar los elementos internos al pasar el mouse sobre él. Me gusta esto:

a.active h1 {color:red;}

a.active:hover h1 {color:green;}

a.active h2 {color:blue;}

a.active:hover h1 {color:yellow;}

De esta manera, puede cambiar el estilo en varias etiquetas internas, en función del rollover del elemento principal.

tormenta de río
fuente
1
Eso es correcto, pero limita el código de marcado dentro de la aetiqueta solo a ciertos elementos, si desea cumplir con los estándares XHTML. Por ejemplo, no puede usar un divinside asin recibir una advertencia de violación del esquema.
Ivaylo Slavov
2
Totalmente correcto Ivaylo! "a" es un elemento que no es de bloque, por lo que no puede usar elementos de bloque dentro de él.
tormenta de río
1
En HTML5, está perfectamente bien poner elementos de bloque dentro de los enlaces.
Matthew James Taylor
2
... si fuera semánticamente incorrecto, no lo habrían permitido en HTML5 donde no estaba antes.
BoltClock
14

Actualmente no hay un selector principal y ni siquiera se está discutiendo en ninguna de las conversaciones del W3C. Debe comprender cómo evalúa CSS el navegador para comprender realmente si lo necesitamos o no.

Hay mucha explicación técnica aquí.

Jonathan Snook explica cómo se evalúa CSS .

Chris Coyier sobre las conversaciones del selector de padres .

Harry Roberts nuevamente sobre escribir selectores CSS eficientes .

Pero Nicole Sullivan tiene algunos datos interesantes sobre tendencias positivas .

Estas personas son todas de primera clase en el campo del desarrollo front-end.

Suraj Naik
fuente
12
El needse define por los requisitos de los desarrolladores web, ya que otros factores deciden si tenerlo en la especificación
nicodemus13
14

Solo una idea para el menú horizontal ...

Parte de HTML

<div class='list'>
  <div class='item'>
    <a>Link</a>
  </div>
  <div class='parent-background'></div>
  <!-- submenu takes this place -->
</div>

Parte de CSS

/* Hide parent backgrounds... */
.parent-background {
  display: none; }

/* ... and show it when hover on children */
.item:hover + .parent-background {
  display: block;
  position: absolute;
  z-index: 10;
  top: 0;
  width: 100%; }

Demo actualizada y el resto del código

Otro ejemplo de cómo usarlo con entradas de texto: seleccione el conjunto de campos principal

Ilya B.
fuente
3
Para mí no está nada claro cómo quiere generalizar esto a algunos / muchos / la mayoría de los casos de uso del selector principal, o incluso exactamente qué partes de este CSS están haciendo qué. ¿Puedes agregar una explicación detallada?
Nathan Tuggy
2
No traté de aplicar esto a escenarios del mundo real, por eso digo "No para producción". Pero creo que se puede aplicar al menú de 2 niveles solo con un ancho de elemento fijo. "qué partes de este CSS están haciendo qué" - .test-sibling aquí es en realidad el fondo del elemento principal (la última línea de CSS).
Ilya B.
2
Explicación agregada (sección css de jsfiddle, comenzando desde "PARTE PRINCIPAL") ... Y me equivoqué: puede haber cualquier número de subniveles.
Ilya B.
13

Aquí hay un truco pointer-eventscon hover:

<!doctype html>
<html>
	<head>
		<title></title>
		<style>
/* accessory */
.parent {
	width: 200px;
	height: 200px;
	background: gray;
}
.parent, 
.selector {
	display: flex;
	justify-content: center;
	align-items: center;
}
.selector {
	cursor: pointer;
	background: silver;
	width: 50%;
	height: 50%;
}
		</style>
		<style>
/* pertinent */
.parent {
	background: gray;
	pointer-events: none;
}
.parent:hover {
	background: fuchsia;
}
.parent 
.selector {
	pointer-events: auto;
}
		</style>
	</head>
	<body>
		<div class="parent">
			<div class="selector"></div>
		</div>
	</body>
</html>

Jan Kyu Peblik
fuente
12

Hay un complemento que extiende CSS para incluir algunas características no estándar que realmente pueden ayudar al diseñar sitios web. Se llama EQCSS .

Una de las cosas que agrega EQCSS es un selector principal. Funciona en todos los navegadores, Internet Explorer 8 y superiores. Aquí está el formato:

@element 'a.active' {
  $parent {
    background: red;
  }
}

Así que aquí hemos abierto una consulta de elemento en cada elemento a.active, y para los estilos dentro de esa consulta, cosas como $parenttienen sentido, porque hay un punto de referencia. El navegador puede encontrar el padre, porque es muy similar a parentNodeJavaScript.

Aquí hay una demostración$parent y otra $parentdemostración que funciona en Internet Explorer 8 , así como una captura de pantalla en caso de que no tenga Internet Explorer 8 para probar .

EQCSS también incluye meta-selectores : $prevpara el elemento antes de un elemento seleccionado y $thissolo para aquellos elementos que coinciden con una consulta de elementos, y más.

innovati
fuente
11

Ahora es 2019, y el último borrador del Módulo de anidamiento CSS en realidad tiene algo como esto. Introducción @nesta las reglas.

3.2. La regla de anidamiento: @nest

Si bien la anidación directa se ve bien, es algo frágil. Algunos selectores de anidamiento válidos, como .foo &, no están permitidos, y editar el selector de ciertas maneras puede invalidar la regla inesperadamente. Además, algunas personas encuentran el anidamiento desafiante para distinguir visualmente de las declaraciones circundantes.

Para ayudar en todos estos problemas, esta especificación define la regla @nest, que impone menos restricciones sobre cómo anidar válidamente las reglas de estilo. Su sintaxis es:

@nest = @nest <selector> { <declaration-list> }

La regla @nest funciona de manera idéntica a una regla de estilo: comienza con un selector y contiene declaraciones que se aplican a los elementos que coincide con el selector. La única diferencia es que el selector utilizado en una regla @nest debe contener nidos, lo que significa que contiene un selector de anidamiento en alguna parte. Una lista de selectores contiene nidos si todos sus selectores complejos individuales contienen nidos.

(Copiar y pegar desde la URL anterior).

Ejemplo de selectores válidos bajo esta especificación:

.foo {
  color: red;
  @nest & > .bar {
    color: blue;
  }
}
/* Equivalent to:
   .foo { color: red; }
   .foo > .bar { color: blue; }
 */

.foo {
  color: red;
  @nest .parent & {
    color: blue;
  }
}
/* Equivalent to:
   .foo { color: red; }
   .parent .foo { color: blue; }
 */

.foo {
  color: red;
  @nest :not(&) {
    color: blue;
  }
}
/* Equivalent to:
   .foo { color: red; }
   :not(.foo) { color: blue; }
 */
roberrrt-s
fuente
10

Técnicamente no hay una forma directa de hacer esto. Sin embargo, puede solucionarlo con jQuery o JavaScript.

Sin embargo, también puedes hacer algo como esto.

a.active h1 {color: blue;}
a.active p {color: green;}

jQuery

$("a.active").parents('li').css("property", "value");

Si desea lograr esto usando jQuery aquí está la referencia para el selector padre jQuery .

Prabhakar Undurthi
fuente
9

El W3C excluyó dicho selector debido al enorme impacto en el rendimiento que tendría en un navegador.

rgb
fuente
27
falso. Debido a que el DOM es un árbol, tienen que ir al padre antes de llegar al niño, por lo que simplemente retroceden un nodo. oo
NullVoxPopuli
99
Los selectores CSS son una cola, por lo que se evalúa el orden del selector en lugar de la jerarquía XPath o DOM del documento.
Paul Sweatte
3
@rgb Al menos eso es lo que nos dijeron.
Yunzen
9

La respuesta corta es NO ; no tenemos un parent selectorCSS en esta etapa, pero si no tiene que intercambiar los elementos o clases de todos modos, la segunda opción es usar JavaScript. Algo como esto:

var activeATag = Array.prototype.slice.call(document.querySelectorAll('a.active'));

activeATag.map(function(x) {
  if(x.parentNode.tagName === 'LI') {
    x.parentNode.style.color = 'red'; // Your property: value;
  }
});

O una forma más corta si usa jQuery en su aplicación:

$('a.active').parents('li').css('color', 'red'); // Your property: value;
Alireza
fuente
5

Aunque actualmente no hay un selector principal en CSS estándar, estoy trabajando en un proyecto (personal) llamado ax (es decir, Sintaxis de selector de CSS aumentado / ACSSSS ) que, entre sus 7 nuevos selectores, incluye ambos:

  1. un selector primario inmediato< (que permite la selección opuesta a >)
  2. un selector de cualquier ancestro ^ (que permite la selección opuesta a [SPACE])

axe se encuentra actualmente en una etapa de desarrollo BETA relativamente temprana.

Vea una demostración aquí:

http://rounin.co.uk/projects/axe/axe2.html

(compare las dos listas a la izquierda con estilo con selectores estándar y las dos listas a la derecha con estilo con selectores de hacha)

Rounin
fuente
3
El proyecto se encuentra en una etapa beta temprana en la actualidad. Puede (al menos actualmente) activar los selectores de hacha en sus estilos CSS al incluirlos <script src="https://rouninmedia.github.io/axe/axe.js"></script>al final de su documento html, justo antes </body>.
Rounin
4

Al menos hasta CSS 3 incluido, no puede seleccionar así. Pero hoy en día se puede hacer con bastante facilidad en JavaScript, solo necesita agregar un poco de JavaScript vainilla, tenga en cuenta que el código es bastante corto.

cells = document.querySelectorAll('div');
[].forEach.call(cells, function (el) {
    //console.log(el.nodeName)
    if (el.hasChildNodes() && el.firstChild.nodeName=="A") {
        console.log(el)
    };
});
<div>Peter</div>
<div><a href="#">Jackson link</a></div>
<div>Philip</div>
<div><a href="#">Pullman link</a></div>

Eduard Florinescu
fuente
4

¿Algunas ideas?

CSS 4 será elegante si agrega algunos ganchos para caminar hacia atrás . Hasta entonces, es posible (aunque no recomendable) usar checkboxy / o radio inputs para romper la forma habitual en que las cosas están conectadas, y a través de eso también permite que CSS funcione fuera de su alcance normal ...

/* Hide things that may be latter shown */
.menu__checkbox__selection,
.menu__checkbox__style,
.menu__hidden {
  display: none;
  visibility: hidden;
  opacity: 0;
  filter: alpha(opacity=0); /* Old Microsoft opacity */
}


/* Base style for content and style menu */
.main__content {
  background-color: lightgray;
  color: black;
}

.menu__hidden {
  background-color: black;
  color: lightgray;
  /* Make list look not so _listy_ */
  list-style: none;
  padding-left: 5px;
}

.menu__option {
  box-sizing: content-box;
  display: block;
  position: static;
  z-index: auto;
}

/* &#9660; - \u2630 - Three Bars */
/*
.menu__trigger__selection::before {
  content: '\2630';
  display: inline-block;
}
*/

/* &#9660; - Down Arrow */
.menu__trigger__selection::after {
  content: "\25BC";
  display: inline-block;
  transform: rotate(90deg);
}


/* Customize to look more `select` like if you like */
.menu__trigger__style:hover,
.menu__trigger__style:active {
  cursor: pointer;
  background-color: darkgray;
  color: white;
}


/**
 * Things to do when checkboxes/radios are checked
 */

.menu__checkbox__selection:checked + .menu__trigger__selection::after,
.menu__checkbox__selection[checked] + .menu__trigger__selection::after {
  transform: rotate(0deg);
}

/* This bit is something that you may see elsewhere */
.menu__checkbox__selection:checked ~ .menu__hidden,
.menu__checkbox__selection[checked] ~ .menu__hidden {
  display: block;
  visibility: visible;
  opacity: 1;
  filter: alpha(opacity=100); /* Microsoft!? */
}


/**
 * Hacky CSS only changes based off non-inline checkboxes
 * ... AKA the stuff you cannot unsee after this...
 */
.menu__checkbox__style[id="style-default"]:checked ~ .main__content {
  background-color: lightgray;
  color: black;
}

.menu__checkbox__style[id="style-default"]:checked ~ .main__content .menu__trigger__style[for="style-default"] {
  color: darkorange;
}

.menu__checkbox__style[id="style-one"]:checked ~ .main__content {
  background-color: black;
  color: lightgray;
}

.menu__checkbox__style[id="style-one"]:checked ~ .main__content .menu__trigger__style[for="style-one"] {
  color: darkorange;
}

.menu__checkbox__style[id="style-two"]:checked ~ .main__content {
  background-color: darkgreen;
  color: red;
}

.menu__checkbox__style[id="style-two"]:checked ~ .main__content .menu__trigger__style[for="style-two"] {
  color: darkorange;
}
<!--
  This bit works, but will one day cause troubles,
  but truth is you can stick checkbox/radio inputs
  just about anywhere and then call them by id with
  a `for` label. Keep scrolling to see what I mean
-->
<input type="radio"
       name="colorize"
       class="menu__checkbox__style"
       id="style-default">
<input type="radio"
       name="colorize"
       class="menu__checkbox__style"
       id="style-one">
<input type="radio"
       name="colorize"
       class="menu__checkbox__style"
       id="style-two">


<div class="main__content">

  <p class="paragraph__split">
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
    quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
  </p>

  <input type="checkbox"
         class="menu__checkbox__selection"
         id="trigger-style-menu">
  <label for="trigger-style-menu"
         class="menu__trigger__selection"> Theme</label>

  <ul class="menu__hidden">
    <li class="menu__option">
      <label for="style-default"
             class="menu__trigger__style">Default Style</label>
    </li>

    <li class="menu__option">
      <label for="style-one"
             class="menu__trigger__style">First Alternative Style</label>
    </li>

    <li class="menu__option">
      <label for="style-two"
             class="menu__trigger__style">Second Alternative Style</label>
    </li>
  </ul>

  <p class="paragraph__split">
    consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
    cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
    proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>

</div>

... bastante asqueroso , pero con solo CSS y HTML es posible tocar y volver a tocar cualquier cosa menos el bodyy :rootdesde casi cualquier lugar al vincular las propiedades idy forde radio/ checkbox inputs y los label desencadenantes ; es probable que alguien muestre cómo volver a tocarlos en algún momento.

Una advertencia adicional es que solo se puede usar unoinput de un específico id, primero checkbox/ radio gana un estado conmutado en otras palabras ... Pero múltiples etiquetas pueden apuntar a lo mismo input, aunque eso haría que tanto el HTML como el CSS se vean aún más groseros.


... espero que exista algún tipo de solución nativa para CSS Nivel 2 ...

No estoy seguro acerca de los otros :selectores, pero sí :checkedpara pre-CSS 3. Si no recuerdo mal, fue algo así como [checked]por qué puede encontrarlo en el código anterior, por ejemplo,

.menu__checkbox__selection:checked ~ .menu__hidden,
.menu__checkbox__selection[checked] ~ .menu__hidden {
 /* rules: and-stuff; */
}

... pero para cosas como ::aftery :hover, no estoy del todo seguro en qué versión de CSS aparecieron por primera vez.

Dicho todo esto, por favor, nunca uses esto en producción, ni siquiera con ira. Como una broma, claro, o en otras palabras, solo porque se puede hacer algo no siempre significa que deba hacerse .

S0AndS0
fuente
3

No, no puede seleccionar el padre solo en CSS.

Pero como ya parece tener una .activeclase, sería más fácil mover esa clase al li(en lugar del a). De esta manera se puede acceder tanto al liy la avía única CSS.

Gaurav Aggarwal
fuente
1

Actualmente, el cambio del elemento primario basado en el elemento secundario solo puede ocurrir cuando tenemos un <input>elemento dentro del elemento primario. Cuando una entrada se enfoca, su elemento padre correspondiente puede verse afectado mediante CSS.

El siguiente ejemplo lo ayudará a comprender el uso :focus-withinen CSS.

.outer-div {
  width: 400px;
  height: 400px;
  padding: 50px;
  float: left
}

.outer-div:focus-within {
  background: red;
}

.inner-div {
  width: 200px;
  height: 200px;
  float: left;
  background: yellow;
  padding: 50px;
}
<div class="outer-div">
  <div class="inner-div">
    I want to change outer-div(Background color) class based on inner-div. Is it possible?
    <input type="text" placeholder="Name" />
  </div>
</div>

Sethuraman
fuente
1

Es posible con ampersand en Sass :

h3
  font-size: 20px
  margin-bottom: 10px
  .some-parent-selector &
    font-size: 24px
    margin-bottom: 20px

Salida CSS:

h3 {
  font-size: 20px;
  margin-bottom: 10px;
}
.some-parent-selector h3 {
  font-size: 24px;
  margin-bottom: 20px;
}
Rodolfo Jorge Nemer Nogueira
fuente
2
es cierto, pero solo si conoce el selector de antemano.
Shahar
11
Esto no selecciona h3el padre, que era el objetivo. Esto seleccionaría h3s que son descendientes de .some-parent-selector.
Jacob Ford
1

Contrataría un código JavaScript para hacer eso. Por ejemplo, en Reaccionar cuando itera sobre una matriz, agregue otra clase al componente padre, lo que indica que contiene sus hijos:

<div className={`parent ${hasKiddos ? 'has-kiddos' : ''}`}>
    {kiddos.map(kid => <div key={kid.id} />)}
</div>

Y luego simplemente:

.parent {
    color: #000;
}

.parent.has-kiddos {
    color: red;
}
Damiano
fuente
0

No hay un selector principal css (y, por lo tanto, en preprocesadores css) debido a "Las razones principales por las que el Grupo de trabajo CSS rechazó previamente las propuestas de selectores principales están relacionadas con el rendimiento del navegador y los problemas de representación incremental".

Dmitry Sokolov
fuente