Come posso impedire l'ereditarietà CSS?


94

Ho un menu di navigazione gerarchico nella mia barra laterale che utilizza elenchi nidificati (tag <ul> e <li>). Sto usando un tema predefinito che ha già stili per gli elementi dell'elenco, ma desidero modificare lo stile per gli elementi di primo livello ma NON farlo applicare agli elementi secondari. Esiste un modo semplice per applicare gli stili al tag dell'elemento dell'elenco di primo livello SENZA che questi stili si sovrappongano agli elementi dell'elenco figli? Capisco che posso aggiungere esplicitamente stili di sovrascrittura agli elementi secondari, ma mi piacerebbe davvero evitare di dover duplicare tutto quel codice di stile se c'è un modo semplice per dire "applica questi stili a questa classe e NON sovrapporre fino agli elementi figli ". Ecco l'html che sto usando:

<ul id="sidebar">
  <li class="top-level-nav">
    <span>HEADING 1</span>
    <ul>
      <li>sub-heading A</li>
      <li>sub-heading B</li>
    </ul>
  </li>
  <li class="top-level-nav">
    <span>HEADING 2</span>
    <ul>
      <li>sub-heading A</li>
      <li>sub-heading B</li>
    </ul>
  </li>
</ul>

Quindi il CSS ha stili per #sidebar ule #sidebar ul ligià, ma mi piacerebbe aggiungere altri stili a #sidebar .top-level-navquello NON ricadono nei suoi sotto-figli. C'è un modo per farlo semplicemente o ho bisogno di riorganizzare tutti gli stili in modo che gli stili che erano #sidebar ulora siano specifici per certe classi?


2
Ho cercato nel sito domande simili e non ho trovato nulla (non ho detto che non ce n'è uno, ma ho cercato). Se sai cos'è, potresti indirizzarmi ad esso? Grazie!

1
stackoverflow.com/questions/747308/breaking-css-inheritance | dice più o meno quello che ha risposto Matteo.
JasonV

1
Quindi presumo che la risposta sia "no, non c'è modo di farlo semplicemente - devi sovrascrivere manualmente ogni impostazione di stile sull'elemento secondario" - lo sto interpretando correttamente? Grazie ancora.

Risposte:


38

Al momento non ci sono selettori genitori (o come li chiama Shaun Inman , selettori qualificati ), quindi dovrai applicare stili agli elementi dell'elenco figlio per sovrascrivere gli stili sugli elementi dell'elenco padre.

Cascading è una specie di punto centrale dei Cascading Style Sheets, da cui il nome.


13
Queste informazioni non sono aggiornate da IE8. Vedi la risposta di Silviu Postavaru. Si prega di considerare di cambiare il segno di spunta con la risposta più appropriata.
tmuecksch

lol, sono d'accordo che la cascata è un po 'l'essenza. Ma dovrebbe esserci un modo per interrompere la propagazione da un genitore specifico che dovrebbe essere diverso.
Obay Abd-Algader

72

Puoi utilizzare il selettore figlio

Quindi usando

#parent > child

Solo i bambini di primo livello avranno gli stili applicati. Purtroppo IE6 non supporta il selettore figlio.

Altrimenti puoi usare

#parent child child

Per impostare altri stili specifici per i bambini che sono più di un livello sotto.


1
Potresti mostrarmi questo in azione in JSFiddle? Ho provato a centrare un div visualizzato in blocco in linea, ma centra comunque il testo all'interno del div.
Calmarius

41

C'è una proprietà chiamata allnel modulo di ereditarietà CSS3 . Funziona così:

#sidebar ul li {
  all: initial;
}

A partire dal 2016-12, tutti i browser tranne IE / Edge e Opera Mini supportano questa proprietà.


4
@AndriusDobrotinas per essere supportato alla fine? Mi sembra di non cogliere completamente il tuo commento. Esiste un plug-in PostCSS che fornisce questa funzionalità, se utilizzi PostCSS: github.com/maximkoretskiy/postcss-initial
Boldewyn

1
@AndriusDobrotinas, il tuo commento è molto non costruttivo. La risposta è stata pubblicata per il bene della comunità; fai del tuo meglio per vederne i benefici.
Cody

2
Al momento, solo IE e Opera Mini non lo supportano, tutti gli altri principali browser lo fanno
Legends

@Boldewyn non esiste un valore 'predefinito', per quanto si può dire dal documento w3 collegato ...
benomatis

@webeno c'era, quando ho scritto la risposta: w3.org/TR/2013/WD-css3-cascade-20130103/#all-shorthand Sembra che ci siano alcune sottili differenze tra il vecchio defaulte il nuovo unset, ma in questo momento io ' non ho tempo per indagare ulteriormente. Sentiti libero di modificare la risposta per aggiornarla.
Boldewyn

26

È possibile utilizzare il selettore * per riportare gli stili figlio all'impostazione predefinita

esempio

#parent {
    white-space: pre-wrap;
}

#parent * {
    white-space: initial;
}

1
Questa è una soluzione molto interessante, soprattutto se non conosci la classe dei genitori.
BurninLeo

Penso di conoscere la risposta a questo, ma c'è comunque da impostare questo in linea? <div id="parent" style="white-space:pre-wrap;*white-space:initial;"/>
1,21 gigawatt

11

Il wrapping con iframe rende obsoleto il css genitore.


2
Divertente che questa sia la risposta peggiore perché tecnicamente è l' unico modo fisico per fermare l'ereditarietà CSS. Non che io stia sostenendo che dovresti usarlo in questo modo.
davidelrizzo

2
Suggerirei di non fare il fisico con CSS, lasciarlo nel mondo virtuale a cui appartiene!
michaelward82

In realtà l'aggiunta ha iframereso invisibile il mio componente figlio. Pensieri?
Kevin Ghaboosi

5

La risposta breve è: no, non è possibile impedire l'ereditarietà CSS. È possibile sovrascrivere solo gli stili impostati sui genitori. Vedi le specifiche:

Ogni elemento in un documento HTML erediterà tutte le proprietà ereditabili dal suo genitore eccetto l'elemento radice ( html), che non ha un genitore. - W3C

Oltre a sovrascrivere ogni singola proprietà ereditata. Puoi anche usare initialparole chiave, ad es color: initial;. Può anche essere utilizzato insieme all, ad esempio all: initial;, che ripristinerà tutte le proprietà contemporaneamente. Esempio:

.container {
  color: blue;
  font-style: italic;
}
.initial {
  all: initial;
}
<div class="container">
  The quick brown <span class="initial">fox</span> jumps over the lazy dog
</div>

Tabelle di supporto del browser in base a Posso usare ...

  • all (Attualmente nessun supporto sia in IE che Edge, altri sono buoni)
  • initial (Attualmente nessun supporto in IE, altri sono buoni)

In alcuni casi potresti trovarlo utile utilizzando il selettore diretto dei figli> . Esempio:

.list > li {
  border: 1px solid red;
  color: blue;
}
<ul class="list">
  <li>
    <span>HEADING 1</span>
    <ul>
      <li>sub-heading A</li>
      <li>sub-heading B</li>
    </ul>
  </li>
  <li>
    <span>HEADING 2</span>
    <ul>
      <li>sub-heading A</li>
      <li>sub-heading B</li>
    </ul>
  </li>
</ul>

Lo stile del bordo è stato applicato solo ai figli diretti <li>, poiché borderè una proprietà non ereditata. Ma il colore del testo è stato applicato a tutti i figli, poiché colorè una proprietà ereditata.

Pertanto, il >selettore sarebbe utile solo con proprietà non ereditate, quando si tratta di prevenire l'ereditarietà.


2

Potresti usare qualcosa come jQuery per "disabilitare" questo comportamento, anche se difficilmente penso che sia una buona soluzione dato che ottieni la logica di visualizzazione in css e javascript. Tuttavia, a seconda delle tue esigenze potresti scoprire che le utilità css di jQuery ti semplificano la vita rispetto a provare css hacky, specialmente se stai cercando di farlo funzionare per IE6


2

Ad esempio, se hai due div nel documento XHTML.

<div id='div1'>
    <p>hello, how are you?</p>
    <div id='div2'>
        <p>I am fine, thank you.</p>
    </div>
</div>

Quindi prova questo in CSS.

#div1 > #div2 > p{
    color: red;
}

influisce solo sul paragrafo "div2".

#div1 > p {
    color: red;
} 

influisce solo sul paragrafo "div1".


2

Non hai bisogno del riferimento alla classe per lis. Invece di avere CSS come

li.top-level-nav { color:black; }

tu puoi scrivere

ul#sidebar > li { color:black; }

Questo applicherà lo stile solo ai messaggi liche scendono immediatamente dalla barra laterale ul.


0

basta riportarli ai valori predefiniti nel selettore "#sidebar ul li"


Grazie per la risposta. Sì, capisco che posso reimpostarli nello stile dell'elemento secondario, ma sto cercando di evitarlo perché sto usando un tema che non ho creato e mi chiedo se posso risparmiare un po 'di tempo usando solo una regola "non-cascade: true" o qualcosa del genere, invece di individuare tutti i diversi stili per gli ul e li che sono sparsi dappertutto e quindi preoccuparsi delle conseguenze indesiderate in altre aree del sito .
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.