Come modellare l'elemento genitore quando si passa con il mouse su un elemento figlio?


160

So che non esiste un selettore parent CSS , ma è possibile modellare un elemento parenting quando si passa con il mouse su un elemento child senza tale selettore?

Per fare un esempio: considera un pulsante Elimina che, quando passa con il mouse , evidenzia l'elemento che sta per essere eliminato:

<div>
    <p>Lorem ipsum ...</p>
    <button>Delete</button>
</div>

Per mezzo di CSS puro, come cambiare il colore di sfondo di questa sezione quando il mouse è sopra il pulsante?


3
Possibile duplicato di Esiste un selettore padre CSS?
TylerH,

Risposte:


134

Bene, questa domanda è stata posta molte volte prima, e la breve risposta tipica è: non può essere fatta da CSS puro. È nel nome: Cascading Style Sheets supporta solo lo stile in direzione della cascata, non verso l'alto.

Ma nella maggior parte dei casi in cui si desidera questo effetto, come nell'esempio dato, esiste ancora la possibilità di utilizzare queste caratteristiche a cascata per raggiungere l'effetto desiderato. Considera questo pseudo markup:

<parent>
    <sibling></sibling>
    <child></child>
</parent>

Il trucco è quello di dare al fratello la stessa dimensione e posizione del genitore e di dare uno stile al fratello anziché al genitore. Questo sembrerà che il genitore sia in stile!

Ora, come modellare il fratello?

Quando il bambino è in bilico, anche il genitore lo è, ma il fratello no. Lo stesso vale per il fratello. Questo si conclude in tre possibili percorsi del selettore CSS per lo styling del fratello:

parent sibling { }
parent sibling:hover { }
parent:hover sibling { }

Questi diversi percorsi consentono alcune belle possibilità. Ad esempio, scatenando questo trucco nell'esempio nella domanda si ottiene questo violino :

div {position: relative}
div:hover {background: salmon}
div p:hover {background: white}
div p {padding-bottom: 26px}
div button {position: absolute; bottom: 0}

Esempio di immagine principale dello stile

Ovviamente, nella maggior parte dei casi questo trucco dipende dall'uso del posizionamento assoluto per dare al fratello le stesse dimensioni del genitore e lasciare comunque che il bambino compaia all'interno del genitore.

A volte è necessario utilizzare un percorso selettore più qualificato per selezionare un elemento specifico, come mostrato in questo violino che implementa il trucco più volte in un menu ad albero. Davvero carino davvero.


1
Questo è utile per l'evidenziazione, ma non funzionerà se provi a cambiare il colore del carattere, vero?
Jahanzeb Khan,

1
@JahanzebKhan La modifica del colore del carattere non è un problema .
NGLN,

117

So che è una vecchia domanda, ma sono riuscito a farlo senza uno pseudo figlio (ma uno pseudo wrapper).

Se imposti il ​​genitore in modo che non sia presente pointer-events, e quindi un figlio in divcui è pointer-eventsimpostato su auto, funziona :)
Nota che il <img>tag (ad esempio) non fa il trucco.
Ricorda inoltre di impostare pointer-eventssu autoper altri bambini che hanno il proprio listener di eventi, altrimenti perderanno la funzionalità di clic.

div.parent {  
    pointer-events: none;
}

div.child {
    pointer-events: auto;
}

div.parent:hover {
    background: yellow;
}    
<div class="parent">
  parent - you can hover over here and it won't trigger
  <div class="child">hover over the child instead!</div>
</div>

Modifica:
come gentilmente notato da Shadow Wizard : vale la pena ricordare che questo non funzionerà per IE10 e inferiori. (Vecchie versioni di FF e Chrome, vedi qui )


3
Vale la pena ricordare che questo non funzionerà per IE10 e inferiori. (Vecchie versioni di FF e Chrome, vedi qui )
Shadow Wizard è Ear For You

2
Impostare eventi puntatore su nessuno significa anche che i listener di eventi su quell'elemento non funzioneranno ..!
rhazen,

1
@rhazen hai perfettamente ragione. Anche se dalla mia esperienza questo utilizzo è solitamente collegato a una singola area / elemento di clic, quindi puoi assegnare l'ascoltatore di clic al genitore
guy_m

Che ne dici se ho due livelli, genitore, figlio1 e figlio di figlio1. Ho aggiunto nessuna puntatore-eventi a genitore e puntatore-eventi auto a figlio. Voglio passare il mouse su child1 tranne il figlio del bambino 1. Demo qui: codepen.io/lion5893/pen/WNQgyVx
Nam Lê Quý

13

Un altro approccio più semplice (a una vecchia domanda) ..
sarebbe quello di posizionare elementi come fratelli e usare:

Selettore di pari livello adiacente ( +) o Selettore di pari livello generale ( ~)

<div id="parent">
  <!-- control should come before the target... think "cascading" ! -->
  <button id="control">Hover Me!</button>
  <div id="target">I'm hovered too!</div>
</div>
#parent {
  position: relative;
  height: 100px;
}

/* Move button control to bottom. */
#control {
  position: absolute;
  bottom: 0;
}

#control:hover ~ #target {
  background: red;
}

inserisci qui la descrizione dell'immagine

Demo Fiddle qui .


1
vale la pena notare che funziona solo #targets viene dopo #control nel DOM (cioè non puoi influenzare i fratelli precedenti, solo seguendo i fratelli)
Gio

10

non esiste un selettore CSS per selezionare un genitore di un figlio selezionato.

potresti farlo con JavaScript


3
vero. qualcosa come $ (child) .hover (function () {$ (this) .closest (parentSelector) .addClass ('hoverClass')}, function () {$ (this) .closest (parentSelector) .removeClass ('hoverClass' )});
Aamir Afridi,

8
@AamirAfridi Non è JS puro, però devi usare jQuery.
Ivotje50,

6

Come accennato in precedenza "non esiste un selettore CSS per selezionare un genitore di un figlio selezionato".

Quindi anche tu:


Ecco l'esempio per la soluzione javascript / jQuery

Sul lato javascript:

$('#my-id-selector-00').on('mouseover', function(){
  $(this).parent().addClass('is-hover');
}).on('mouseout', function(){
  $(this).parent().removeClass('is-hover');
})

E dal lato CSS, avresti qualcosa del genere:

.is-hover {
  background-color: red;
}

3

Questa soluzione dipende completamente dal design, ma se si dispone di un div parent su cui si desidera modificare lo sfondo quando si passa il mouse su un bambino, è possibile provare a imitare il genitore con un ::after/ ::before.

<div class="item">
    design <span class="icon-cross">x</span>
</div>

CSS:

.item {
    background: blue;
    border-radius: 10px;
    position: relative;
    z-index: 1;
}
.item span.icon-cross:hover::after {
    background: DodgerBlue;
    border-radius: 10px;
    display: block;
    position: absolute;
    z-index: -1;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    content: "";
}

Vedi un esempio di violino completo qui


-1

Una semplice soluzione jquery per chi non ha bisogno di una soluzione css pura:

    $(".letter").hover(function() {
      $(this).closest("#word").toggleClass("hovered")
    });
.hovered {
  background-color: lightblue;
}

.letter {
  margin: 20px;
  background: lightgray;
}

.letter:hover {
  background: grey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="word">
  <div class="letter">T</div>
  <div class="letter">E</div>
  <div class="letter">S</div>
  <div class="letter">T</div>
</div>


-8

Questo è estremamente facile da fare a Sass! Non approfondire JavaScript per questo. Il selettore & in sass fa esattamente questo.

http://thesassway.com/intermediate/referencing-parent-selectors-using-ampersand


6
-1 Sass non aggiunge più funzionalità ai CSS, ma semplifica la scrittura. Tutto ciò che puoi fare in sass può essere fatto in CSS e viceversa.
Dastur,

3
@Dastur Date variabili e mixin, direi che Sass aggiunge molto al CSS. Puoi fare tutto in CSS, allo stesso modo in cui potresti ancora scrivere software sofisticato usando semplicemente vecchi C. I linguaggi moderni aggiungono molto senza abilitare qualcosa che prima non si poteva fare. Lo stesso con Sass e CSS.
Cobus Kruger,

6
@Cobus Kruger Hai ragione, ma non puoi fare questo confronto. Mentre linguaggi come c ++ c # e javascript possono essere basati su C, non si trasformano in C prima del runtime. Sass viene convertito in CSS prima del runtime, quindi non si sta mai veramente caricando un foglio di stile sass, solo un CSS.
Dastur,
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.