Applica gli stili CSS a un elemento in base ai suoi elementi figlio


203

È possibile definire uno stile CSS per un elemento, che viene applicato solo se l'elemento corrispondente contiene un elemento specifico (come elemento figlio diretto)?

Penso che questo sia meglio spiegato usando un esempio.

Nota : sto cercando di dare uno stile all'elemento genitore , a seconda degli elementi figlio che contiene.

<style>
  /* note this is invalid syntax. I'm using the non-existing
   ":containing" pseudo-class to show what I want to achieve. */
  div:containing div.a { border: solid 3px red; }
  div:containing div.b { border: solid 3px blue; }
</style>

<!-- the following div should have a red border because
     if contains a div with class="a" -->
<div>
  <div class="a"></div>
</div>

<!-- the following div should have a blue border -->
<div>
  <div class="b"></div>
</div>

Nota 2 : So di poterlo raggiungere utilizzando JavaScript, ma mi chiedevo solo se ciò fosse possibile utilizzando alcune funzioni CSS (per me) sconosciute.


1
Potresti voler aggiornare la domanda per dichiarare, forse con un testo in grassetto lampeggiante, che stai cercando di dare uno stile al div GEN, non ai suoi figli. So che le informazioni sono nella domanda stessa, ma a meno che tu non voglia ottenere tonnellate di risposte errate, probabilmente ne vale la pena.
Seth Petry-Johnson,

Grazie @Seth. Ho cercato di migliorare il titolo e il testo della domanda. Modifica la domanda se ritieni che non sia ancora chiaro.
M4N,


Questo è l'esempio perfetto del motivo per cui questo tipo di supporto nei CSS sarebbe l'ideale: ol < li:nth-child(n+10) { margin-left: 2rem; } ol < li:nth-child(n+100) { margin-left: 3rem; } ol < li:nth-child(n+1000) { margin-left: 4rem; }in un mondo ideale questo aumenterebbe il margine del oldipendente dal numero di libambini contenuti in modo che il margine a sinistra sia largo solo quanto doveva essere.
Jonmark Weber,

Risposte:


124

Per quanto ne so, lo stile di un elemento padre basato sull'elemento figlio non è una funzione disponibile di CSS. Probabilmente avrai bisogno di script per questo.

Sarebbe meraviglioso se potessi fare qualcosa del genere div[div.a]o div:containing[div.a]come hai detto, ma questo non è possibile.

Potresti prendere in considerazione l' idea di guardare jQuery . I suoi selettori funzionano molto bene con tipi "contenenti". Puoi selezionare il div, in base al suo contenuto figlio e quindi applicare una classe CSS al genitore tutto in una riga.

Se usi jQuery, qualcosa del genere potrebbe funzionare (non testato ma la teoria è lì):

$('div:has(div.a)').css('border', '1px solid red');

o

$('div:has(div.a)').addClass('redBorder');

combinato con una classe CSS:

.redBorder
{
    border: 1px solid red;
}

Ecco la documentazione per il selettore "ha" di jQuery .


15
Nota a margine : per prestazioni migliori, la pagina del documento jQuery per il :hasselettore consiglia di utilizzare il .has()metodo ( api.jquery.com/has ) => applicato alla domanda corrente che darebbe ad esempio$('div').has('div.a').css('border', '1px solid red');
Frosty Z

Perché questo funzioni si dovrebbe usare l'osservatore di mutazione, per verificare se il bambino ha cambiato stato ...
Legends

Questo non risponde veramente alla domanda "Esiste un modo per farlo con i CSS". Afferma chiaramente: "So di poterlo ottenere utilizzando JavaScript, ma mi chiedevo solo se ciò fosse possibile utilizzando alcune funzioni CSS (per me) sconosciute".
SunshinyDoyle,

developer.mozilla.org/en-US/docs/Web/CSS/:has , penso che questo :hasselettore possa funzionare ma è in versione bozza e nessun browser lo supporta.
AliF50

62

Fondamentalmente no. Quanto segue sarebbe quello che stavi cercando in teoria:

div.a < div { border: solid 3px red; }

Sfortunatamente non esiste.

Ci sono alcuni commenti sulla falsariga del "perché diavolo no". Uno ben sviluppato di Shaun Inman è abbastanza buono:

http://www.shauninman.com/archive/2008/05/05/css_qualified_selectors


34
solo un aggiornamento 8 anni dopo: non esiste ancora supporto per questo metodo di selezione.
Kraang Prime,

1
C'è una bozza funzionante per questa funzione sotto forma di una :has()pseudo-classe, ma la useremo solo in CSS4. A partire da ora (fine 2019), JS è ancora l'unico modo per raggiungere questa funzionalità.
zepp.lee,

Credo che questo non abiliterà gli stili CSS, avrà comunque bisogno di JavaScript per usare il selettore. A meno che questo non sia cambiato?
Justin Wignall,

3
9 anni e pensano che questa funzione sia inutile?
Loi Nguyen Huynh,

1

In cima alla risposta di @ kp:

Ho a che fare con questo e nel mio caso, devo mostrare un elemento figlio e correggere l'altezza dell'oggetto padre di conseguenza (il ridimensionamento automatico non funziona in un'intestazione bootstrap per qualche motivo non ho tempo per il debug) .

Ma invece di usare JavaScript per modificare il genitore, penso che aggiungerò dinamicamente una classe CSS al genitore e mostrerò selettivamente i figli di conseguenza. Ciò manterrà le decisioni nella logica e non basate su uno stato CSS.

tl; dr; applicare gli stili ae bal genitore <div>, non al figlio (ovviamente, non tutti saranno in grado di farlo. Cioè componenti angolari che prendono le proprie decisioni).

<style>
  .parent            { height: 50px; }
  .parent div        { display: none; }
  .with-children     { height: 100px; }
  .with-children div { display: block; }
</style>

<div class="parent">
  <div>child</div>
</div>

<script>
  // to show the children
  $('.parent').addClass('with-children');
</script>

0

Nel mio caso, ho dovuto modificare il riempimento di cella di un elemento che conteneva una casella di controllo di input per una tabella che viene dinamicamente renderizzata con DataTables:

<td class="dt-center">
    <input class="a" name="constCheck" type="checkbox" checked="">
</td>

Dopo aver implementato il seguente codice di riga all'interno della funzione initComplete sono stato in grado di produrre il corretto riempimento, che ha impedito che le righe venissero visualizzate con un'altezza anormalmente grande

 $('tbody td:has(input.a)').css('padding', '0px');

Ora puoi vedere che gli stili corretti vengono applicati all'elemento genitore:

<td class=" dt-center" style="padding: 0px;">
    <input class="a" name="constCheck" type="checkbox" checked="">
</td>

In sostanza, questa risposta è un'estensione della risposta di @ KP, ma maggiore è la collaborazione per implementarla, meglio è. Riassumendo, spero che questo aiuti qualcun altro perché funziona! Infine, grazie mille @KP per avermi guidato nella giusta direzione!

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.