Esiste un selettore padre CSS?


3177

Come seleziono l' <li>elemento che è un genitore diretto dell'elemento anchor?

Ad esempio, il mio CSS sarebbe qualcosa del genere:

li < a.active {
    property: value;
}

Ovviamente ci sono modi per farlo con JavaScript, ma spero che esista una sorta di soluzione alternativa nativa al livello 2 CSS.

Il menu che sto provando a mettere in stile è stato vomitato da un CMS, quindi non posso spostare l'elemento attivo <li>sull'elemento ... (a meno che non tema il modulo di creazione del menu che preferirei non fare).

Qualche idea?

Risposte:


2535

Al momento non è possibile selezionare il genitore di un elemento in CSS.

Se ci fosse un modo per farlo, sarebbe in una delle attuali specifiche dei selettori CSS:

Detto questo, il Draft di lavoro di livello 4 dei selettori include una :has()pseudo-classe che fornirà questa capacità. Sarà simile all'implementazione di jQuery .

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

Tuttavia, a partire da maggio 2020, questo non è ancora supportato da nessun browser .

Nel frattempo, dovrai ricorrere a JavaScript se devi selezionare un elemento padre.


68
Sembrerebbe che è già stato suggerito e respinto: stackoverflow.com/questions/45004/...
RobM

14
Sembra che il selettore del soggetto sia stato rivisitato, tranne utilizzando un !ora: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
Il anteposto $sembrava migliore per me ... l'aggiunta !può essere trascurata più facilmente.
Christoph,

51
Colpo di scena principale! Il selettore 4 WD è stato appena aggiornato oggi per escludere l'indicatore del soggetto dal profilo rapido, che deve essere utilizzato dalle implementazioni CSS. Se questa modifica persiste, significa che non sarai più in grado di utilizzare l'indicatore soggetto nei fogli di stile (a meno che tu non usi aggiungere una sorta di polyfill come quello descritto in un'altra risposta ) - puoi usarlo solo con l'API Selettori e ovunque altrimenti è possibile implementare il profilo completo.
BoltClock

55
Un altro importante aggiornamento: sembra che stiano considerando di eliminare del tutto la sintassi del selettore del soggetto e di sostituirlo con lo :has()pseudo che tutti hanno imparato a conoscere e ad amare di jQuery. L'ultima ED ha rimosso tutti i riferimenti all'indicatore del soggetto e lo ha sostituito con lo :has()pseudo. Non conosco i motivi esatti, ma il CSSWG ha tenuto un sondaggio qualche tempo fa e i risultati devono aver influenzato questa decisione. È molto probabile che sia compatibile con jQuery (quindi può sfruttare qSA senza modifiche) e perché la sintassi dell'indicatore del soggetto si è rivelata troppo confusa.
BoltClock

152

Non penso che puoi selezionare il genitore solo in CSS.

Ma siccome sembra che tu abbia già una .activeclasse, sarebbe più semplice spostare quella classe in li(anziché in a). In questo modo è possibile accedere solo a lie atramite CSS.


4
Non è possibile spostare lo pseudo-selettore sulla voce di elenco, in quanto non è un elemento attivabile. Sta usando il selettore: active, quindi quando l'ancoraggio è attivo vuole che la voce dell'elenco sia influenzata. Gli elementi dell'elenco non saranno mai nello stato attivo. A parte questo, è un peccato che un tale selettore non esista. Ottenere un menu CSS puro per essere completamente accessibile da tastiera sembra impossibile senza di esso (usando i selettori di pari livello è possibile creare sottomenu creati usando liste nidificate per apparire, ma una volta che la lista si focalizza diventa di nuovo nascosta). Se ci sono soluzioni solo CSS per questo particolare conun

12
@Dominic Aquilina Dai un'occhiata alla domanda, l'OP sta usando una classe, non uno pseudo-selettore.
jeroen

125

Puoi usare questo script :

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

Questo selezionerà qualsiasi genitore di un input di testo. Ma aspetta, c'è ancora molto di più. Se lo desideri, puoi selezionare un genitore specificato:

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

Oppure selezionalo quando è attivo:

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

Dai un'occhiata a questo HTML:

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

Puoi selezionarlo span.help quando inputè attivo e mostrarlo:

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

Ci sono molte più capacità; basta consultare la documentazione del plugin.

A proposito, funziona in Internet Explorer.


5
supponiamo che l'uso di jquery patent()sia più veloce. Questo ha bisogno di essere testato, tuttavia
Dan,

2
@Idered Non riesce quando si dispone di una dichiarazione CSS di un Selector Subject senza selettore figlio ( #a!solo genera un errore, #a! pfunziona), e quindi gli altri non funzionano neanche a causa di Uncaught TypeError: Cannot call method 'split' of undefined: consultare jsfiddle.net/HerrSerker/VkVPs
yunzen

3
@HerrSerker Penso #a! è un selettore non valido, cosa dovrebbe selezionare?
Idered

2
@Idered non lo so. Le specifiche non dicono che è illegale. #un! dovrebbe selezionare se stesso. Almeno il loro non dovrebbe essere un errore in JavaScript
yunzen

5
Secondo il mio commento sulla risposta accettata, sembra che il polyfill potrebbe essere richiesto anche nel prossimo futuro, poiché l'indicatore del soggetto potrebbe non essere mai implementato dai browser nei CSS.
BoltClock

108

Come accennato da un paio di altri, non esiste un modo per modellare i genitori di un elemento usando solo CSS ma quanto segue funziona con jQuery :

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

21
Il <selettore non esiste (verificato utilizzando jQuery 1.7.1).
Rob W,

6
Forse quella <sintassi ha funzionato nel 2009 ma l'ho aggiornato (per il 2013).
Alastair,

5
Ancora meglio, utilizzare built-in di jQuery :has()selettore : $("li:has(a.active)").css("property", "value");. Legge in modo simile al !selettore proposto da CSS 4 . Vedi anche: :parentselettore , .parents()metodo , .parent()metodo .
Rory O'Kane,

7
E piuttosto che usare .css("property", "value")per dare uno stile agli elementi selezionati, dovresti di solito .addClass("someClass")e avere nel tuo CSS .someClass { property: value }( via ). In questo modo, puoi notare lo stile con tutta la potenza del CSS e di tutti i preprocessori che stai utilizzando.
Rory O'Kane,


69

Non esiste un selettore padre; proprio come non esiste un precedente selettore di pari livello. Un buon motivo per non avere questi selettori è perché il browser deve attraversare tutti i figli di un elemento per determinare se applicare o meno una classe. Ad esempio, se hai scritto:

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

Quindi il browser dovrà attendere fino a quando non avrà caricato e analizzato tutto fino </body>a quando non sarà necessario determinare se la pagina deve essere rossa o meno.

L'articolo Perché non abbiamo un selettore principale lo spiega in dettaglio.


11
quindi rendi il browser più veloce. Internet stesso più veloce. questo selettore è sicuramente necessario, e la ragione per non implementarlo è, purtroppo, perché viviamo in un mondo lento e primitivo.
vsync,

11
in realtà, il selettore renderebbe lento un browser molto veloce.
Salman,

5
Sono fiducioso che gli sviluppatori di browser avrebbero avuto un'implementazione che è (almeno) veloce quanto la versione javascript, che è quella che le persone finiscono per usare comunque.
Marc.2377,

"Viviamo in un mondo lento e primitivo" tosse tosse nuova mela guarda tosse tosse
Marvin

@ Marc.2377 Se provi l'esempio sopra in JS sul tuo sito web, non lo visiterò mai. D'altra parte, direi che la maggior parte delle volte ti preoccupi solo dei bambini immediati, quindi se fosse limitato solo ai bambini immediati, sarebbe una buona aggiunta senza troppi effetti.
xryl669,

54

Non esiste un modo per farlo in CSS 2. È possibile aggiungere la classe a lie fare riferimento a a:

li.active > a {
    property: value;
}

3
facendo visualizzare l'elemento a: blocco puoi modellarlo per adattarlo all'intera area li. se riesci a spiegare quale stile stai cercando, forse potrei aiutare con una soluzione.
Josh,

questa è in realtà una soluzione semplice ed elegante e, in molti casi, ha senso impostare la classe sul genitore.
Ricardo,

35

Prova a passare aalla blockvisualizzazione, quindi utilizza lo stile che desideri. L' aelemento riempirà l' lielemento e sarai in grado di modificarne l'aspetto come desideri. Non dimenticare di impostare il liriempimento su 0.

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

31

Il selettore CSS " General Sibling Combinator " potrebbe forse essere utilizzato per quello che vuoi:

E ~ F {
    property: value;
}

Questo corrisponde a qualsiasi Felemento preceduto da un Eelemento.


24
Questo è solo un selettore di pari livello, non è un bambino, un genitore ... non risponde davvero alla domanda
amico

26

Non in CSS 2 per quanto ne so. CSS 3 ha selettori più robusti ma non è implementato in modo coerente su tutti i browser. Anche con i selettori migliorati, non credo che realizzerà esattamente ciò che hai specificato nel tuo esempio.


24

So che l'OP stava cercando una soluzione CSS ma è semplice da ottenere utilizzando jQuery. Nel mio caso, dovevo trovare il <ul>tag parent per un <span>tag contenuto nel child <li>. jQuery ha il :hasselettore, quindi è possibile identificare un genitore dai figli che contiene:

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

selezionerà l' ulelemento che ha un elemento figlio con id someId . O per rispondere alla domanda originale, qualcosa come il seguente dovrebbe fare il trucco (non testato):

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

3
Oppure usa $yourSpan.closest("ul")e otterrai l'UL genitore del tuo elemento span. Tuttavia la tua risposta è imho completamente offtopica. Siamo in grado di rispondere a tutte le domande gestite da CSS con una soluzione jQuery.
Robin van Baalen,

1
Come identificato in altre risposte, non è possibile farlo utilizzando CSS 2. Dato questo vincolo, la risposta che ho fornito è quella che conosco sia efficace ed è il modo più semplice per rispondere alla domanda utilizzando javascript imho.
David Clarke,

Dati i tuoi voti, alcune persone sono d'accordo con te. Ma l'unica risposta rimane quella accettata; chiaro e semplice "non può essere fatto nel modo desiderato". Se la domanda è come archiviare 60 miglia all'ora su una bicicletta e tu rispondi con "semplice; sali in macchina e fai benzina", non è ancora una risposta. Da qui il mio commento.
Robin van Baalen,

1
Tale approccio renderebbe SO quasi completamente inutile. Cerco SO per risolvere i problemi, non trovare la "sola risposta" non risolve il problema. Ecco perché SO è così fantastico, perché c'è sempre più di un modo per scuoiare un gatto.
David Clarke,

23

Lo pseudo elemento :focus-within consente di selezionare un genitore se un discendente ha lo stato attivo.

Un elemento può essere focalizzato se ha un tabindexattributo.

Supporto del browser per focus-inside

tabindex

Esempio

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


2
Questo funziona bene nel mio caso, grazie! Solo un no, l'esempio sarebbe più Ilustrative se si cambia il colore al genitore, non il fratello, questo è sostituire .color:focus-within .changecon .color:focus-within. Nel mio caso sto usando la barra di navigazione bootstrap che aggiunge la classe ai bambini quando è attiva e voglio aggiungere una classe alla barra .nav principale. Penso che questo sia uno scenario abbastanza comune in cui possiedo il markup ma il componente css + js è bootstrap (o altro), quindi non posso cambiare il comportamento. Anche se posso aggiungere tabindex e usare questo css. Grazie!
cancerbero,

22

Questo è l'aspetto più discusso del livello 4 dei selettori specifica . Con questo, un selettore sarà in grado di modellare un elemento in base al suo figlio usando un punto esclamativo dopo il selettore dato (!).

Per esempio:

body! a:hover{
   background: red;
}

imposterà un colore di sfondo rosso se l'utente passa sopra un punto di ancoraggio.

Ma dobbiamo aspettare l'implementazione dei browser :(


21

Potresti provare a utilizzare il collegamento ipertestuale come genitore, quindi modificare gli elementi interni al passaggio del mouse. Come questo:

a.active h1 {color:red;}

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

a.active h2 {color:blue;}

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

In questo modo è possibile modificare lo stile in più tag interni, in base al rollover dell'elemento padre.


1
Ciò è corretto, ma limita il codice di markup all'interno del atag solo a determinati elementi, se si desidera conformarsi agli standard XHTML. Ad esempio, non è possibile utilizzare un divinside a, senza ricevere un avviso di violazione dello schema.
Ivaylo Slavov,

2
Sicuramente Ivaylo! "a" è un elemento non a blocchi, quindi non può utilizzare elementi a blocchi al suo interno.
riverst

1
In HTML5 è perfettamente corretto inserire elementi di blocco all'interno di collegamenti.
Matthew James Taylor,

2
... se fosse stato semanticamente sbagliato, non lo avrebbero permesso in HTML5 dove non lo era prima.
BoltClock

14

Attualmente non esiste un selettore dei genitori e non viene nemmeno discusso in nessuno dei discorsi del W3C. Devi capire come il CSS viene valutato dal browser per capire se ne abbiamo bisogno o no.

Ci sono molte spiegazioni tecniche qui.

Jonathan Snook spiega come viene valutato il CSS .

Chris Coyier parla dei selettori di Parent .

Harry Roberts di nuovo sulla scrittura di efficienti selettori CSS .

Ma Nicole Sullivan ha alcuni fatti interessanti su tendenze positive .

Queste persone sono tutte di prima classe nel campo dello sviluppo del front-end.


12
Il needè definita da esigenze sviluppatori web, se avere nella specifica è deciso da altri fattori.
nicodemus13,

14

Solo un'idea per il menu orizzontale ...

Parte di HTML

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

Parte del 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 aggiornata e resto del codice

Un altro esempio su come utilizzarlo con input di testo: selezionare il set di campi principale


3
Non è affatto chiaro per me come intendi generalizzare questo ad alcuni / molti / la maggior parte dei casi d'uso del selettore genitore, o anche esattamente quali parti di questo CSS stanno facendo cosa. Puoi aggiungere una spiegazione approfondita?
Nathan Tuggy,

2
Non ho provato ad applicarlo a scenari del mondo reale, ecco perché dico "Non per la produzione". Ma penso che possa essere applicato al menu a 2 livelli solo con larghezza elemento fissa. "quali parti di questo CSS stanno facendo cosa". Il fratello .test qui è in realtà lo sfondo dell'elemento principale (l'ultima riga del CSS).
Ilya B.,

2
Aggiunta spiegazione (sezione css di jsfiddle, a partire da "PARTE PRINCIPALE") ... E mi sono sbagliato - potrebbe esserci un numero qualsiasi di livelli secondari.
Ilya B.

13

Ecco un trucco che usa 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>


12

C'è un plugin che estende i CSS per includere alcune funzionalità non standard che possono davvero aiutare nella progettazione di siti Web. Si chiama EQCSS .

Una delle cose che aggiunge EQCSS è un selettore padre. Funziona su tutti i browser, Internet Explorer 8 e versioni successive. Ecco il formato:

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

Quindi qui abbiamo aperto una query elemento su ogni elemento a.active, e per gli stili all'interno di quella query, cose come $parenthanno senso, perché c'è un punto di riferimento. Il browser può trovare il genitore, perché è molto simile a parentNodeJavaScript.

Ecco una demo$parent e un'altra $parentdemo che funziona in Internet Explorer 8 , nonché uno screenshot nel caso in cui non hai Internet Explorer 8 in giro con cui provare .

EQCSS include anche meta-selettori : $prevper l'elemento prima di un elemento selezionato e $thissolo per quegli elementi che corrispondono a una query di elementi e altro.


11

È ora il 2019 e l' ultima bozza del modulo di nidificazione CSS ha in realtà qualcosa del genere. Introduzione @nestalle regole.

3.2. La regola della nidificazione: @nest

Mentre l'annidamento diretto sembra bello, è alquanto fragile. Alcuni selettori di annidamento validi, come .foo &, non sono consentiti e la modifica del selettore in determinati modi può rendere la regola non valida in modo imprevisto. Inoltre, alcune persone trovano l'annidamento impegnativo per distinguere visivamente dalle dichiarazioni circostanti.

Per aiutare in tutti questi problemi, questa specifica definisce la regola @nest, che impone meno restrizioni su come nidificare validamente le regole di stile. La sua sintassi è:

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

La regola @nest funziona in modo identico a una regola di stile: inizia con un selettore e contiene dichiarazioni che si applicano agli elementi corrispondenti al selettore. L'unica differenza è che il selettore utilizzato in una regola @nest deve contenere un nido, il che significa che contiene un selettore di nidificazione da qualche parte. Un elenco di selettori contiene nido se tutti i singoli selettori complessi sono contenenti nido.

(Copia e incolla dall'URL sopra).

Esempio di selettori validi in base a questa specifica:

.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; }
 */

10

Tecnicamente non esiste un modo diretto per farlo. Tuttavia, puoi risolverlo con jQuery o JavaScript.

Tuttavia, puoi fare anche qualcosa del genere.

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

jQuery

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

Se si desidera ottenere ciò utilizzando jQuery, ecco il riferimento per il selettore genitore jQuery .


9

Il W3C ha escluso un tale selettore a causa dell'enorme impatto sulle prestazioni che avrebbe avuto su un browser.


27
falsa. poiché il DOM è un albero, devono andare dal genitore prima di arrivare al figlio, quindi semplicemente tornano indietro di un nodo. oo
NullVoxPopuli,

9
I selettori CSS sono una coda, pertanto viene valutato l' ordine dei selettori anziché la gerarchia XPath o DOM del documento.
Paul Sweatte,

3
@rgb Almeno questo è quello che ci hanno detto.
yunzen,

9

La risposta breve è NO ; non abbiamo parent selectora questo punto in CSS, ma se non è necessario scambiare comunque gli elementi o le classi, la seconda opzione sta usando JavaScript. Qualcosa come questo:

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 un modo più breve se usi jQuery nella tua applicazione:

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

5

Sebbene al momento non ci siano selettori principali nei CSS standard, sto lavorando a un progetto (personale) chiamato ax (ovvero Sintassi / selettore CSS aumentati / ACSSSS ) che, tra i suoi 7 nuovi selettori, include entrambi:

  1. un selettore genitore immediato< (che consente alla selezione opposta di >)
  2. un selettore antenato ^ (che consente alla selezione opposta di [SPACE])

ax è attualmente in una fase di sviluppo BETA relativamente precoce.

Guarda una demo qui:

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

(confronta i due elenchi a sinistra in stile con selettori standard e i due elenchi a destra in stile con selettori ascia)


3
Il progetto è attualmente in una fase beta iniziale. Puoi (almeno attualmente) attivare i selettori di ax nei tuoi stili CSS includendo <script src="https://rouninmedia.github.io/axe/axe.js"></script>alla fine del tuo documento html, poco prima </body>.
Rounin,

4

Almeno fino a CSS 3 compreso non è possibile selezionare in questo modo. Ma può essere fatto abbastanza facilmente al giorno d'oggi in JavaScript, devi solo aggiungere un po 'di vaniglia JavaScript, nota che il codice è piuttosto breve.

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>


4

Qualche idea?

CSS 4 sarà fantasioso se aggiunge alcuni ganci nel camminare all'indietro . Fino ad allora è possibile (anche se non consigliabile) usare checkboxe / oradio input s per interrompere il solito modo in cui le cose sono connesse, e attraverso ciò consentire anche ai CSS di operare al di fuori del suo normale ambito ...

/* 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>

... piuttosto grossolano , ma con solo CSS e HTML è possibile toccare e ri-toccare qualsiasi cosa tranne il bodye:root da qualsiasi luogo collegando il ide forle proprietà di radio/ checkbox inputs e label trigger ; probabilmente qualcuno mostrerà come ri-toccare quelli ad un certo punto.

Un avvertimento supplementare è che solo uno input di uno specifico può essere idusato, in primo luogo checkbox/ radio vince uno stato alternato in altre parole ... Ma più etichette possono puntare allo stesso input, sebbene ciò renderebbe sia l'HTML che i CSS ancora più grossolani.


... Spero che esista una sorta di soluzione alternativa nativa al livello 2 CSS ...

Non sono sicuro degli altri :selettori, ma io :checkedper i pre-CSS 3. Se ricordo bene, è stato qualcosa di simile al [checked]motivo per cui potresti trovarlo nel codice sopra, ad esempio,

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

... ma per cose come ::aftere :hover, non sono affatto sicuro in quale versione CSS siano apparse per la prima volta.

Detto questo, per favore non usarlo mai in produzione, nemmeno con rabbia. Sicuramente uno scherzo o, in altre parole, solo perché qualcosa può essere fatto non significa sempre dovrebbe .


3

No, non puoi selezionare il genitore solo nel CSS.

Ma siccome sembra che tu abbia già una .activeclasse, sarebbe più semplice spostare quella classe in li(anziché in a). In questo modo è possibile accedere solo a lie atramite CSS.


1

La modifica dell'elemento genitore in base all'elemento figlio può attualmente avvenire solo quando abbiamo un <input>elemento all'interno dell'elemento genitore. Quando un input viene attivato, il suo elemento genitore corrispondente può essere influenzato tramite CSS.

L'esempio seguente ti aiuterà a capire l'utilizzo :focus-withinnei 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>


1

È possibile con la e commerciale in Sass :

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

Uscita CSS:

h3 {
  font-size: 20px;
  margin-bottom: 10px;
}
.some-parent-selector h3 {
  font-size: 24px;
  margin-bottom: 20px;
}

2
è vero, ma solo se conosci il selettore in anticipo.
Shahar,

11
Questo non seleziona h3il genitore, che era l'obiettivo. Questo selezionerebbe h3s di cui sono discendenti .some-parent-selector.
Jacob Ford,

1

Assumerei un codice JavaScript per farlo. Ad esempio, in React quando si esegue l'iterazione su un array, aggiungere un'altra classe al componente padre, che indica che contiene i propri figli:

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

E poi semplicemente:

.parent {
    color: #000;
}

.parent.has-kiddos {
    color: red;
}

0

Non esiste un selettore padre css (e quindi nei preprocessori css) a causa di "I motivi principali per cui il gruppo di lavoro CSS ha precedentemente rifiutato proposte per i selettori padre sono legati alle prestazioni del browser e ai problemi di rendering incrementale".

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.