Wie verhindere ich die CSS-Vererbung?

87

Ich habe ein hierarchisches Navigationsmenü in meiner Seitenleiste, das verschachtelte Listen (<ul> und <li> Tags) verwendet. Ich verwende ein vorgefertigtes Thema, das bereits Stile für Listenelemente enthält, aber ich möchte den Stil für die Elemente der obersten Ebene ändern, aber NICHT auf die Unterelemente anwenden. Gibt es eine einfache Möglichkeit, Stile auf das Listenelement-Tag der obersten Ebene anzuwenden, ohne dass diese Stile auf die untergeordneten Listenelemente herunterkaskadiert werden? Ich verstehe, dass ich den Unterelementen explizit überschreibende Stile hinzufügen kann, aber ich möchte wirklich vermeiden, dass der gesamte Stilcode dupliziert werden muss, wenn es eine einfache Möglichkeit gibt, einfach zu sagen: "Wenden Sie diese Stile auf diese Klasse an und kaskadieren Sie NICHT." sie bis auf Kinderelemente ". Hier ist das HTML, das ich benutze:

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

Das CSS hat also Stile für #sidebar ulund #sidebar ul libereits, aber ich möchte zusätzliche Stile hinzufügen #sidebar .top-level-nav, die NICHT auf seine untergeordneten Elemente übertragen werden. Gibt es eine Möglichkeit, dies einfach zu tun, oder muss ich alle Stile neu anordnen, damit die Stile, die aktiviert waren, #sidebar uljetzt für bestimmte Klassen spezifisch sind?

vandsa01
quelle
2
Ich habe die Site nach ähnlichen Fragen durchsucht und nichts gefunden (ohne zu sagen, dass es keine gibt, aber ich habe nachgesehen). Wenn Sie wissen, was es ist, können Sie mich bitte darauf hinweisen? Vielen Dank!
1
stackoverflow.com/questions/747308/breaking-css-inheritance | es sagt ziemlich genau, was Matthew geantwortet hat.
JasonV
1
Ich gehe davon aus, dass die Antwort lautet: "Nein, es gibt keine Möglichkeit, dies einfach zu tun. Sie müssen jede Stileinstellung für das Unterelement manuell überschreiben." Interpretiere ich das richtig? Danke noch einmal.

Antworten:

36

Bis jetzt gibt es keine übergeordneten Selektoren (oder wie Shaun Inman sie nennt, qualifizierte Selektoren ), daher müssen Sie Stile auf die untergeordneten Listenelemente anwenden, um die Stile auf den übergeordneten Listenelementen zu überschreiben.

Cascading ist sozusagen der springende Punkt bei Cascading Style Sheets, daher der Name.

Scott
quelle
13
Diese Informationen sind seit IE8 veraltet. Siehe die Antwort von Silviu Postavaru. Bitte ändern Sie den Scheck in die passendere Antwort.
Tmuecksch
lol, ich stimme zu, dass Kaskadierung irgendwie die Essenz ist. Es sollte jedoch eine Möglichkeit geben, die Weitergabe von einem bestimmten Elternteil zu stoppen, die anders sein soll.
Obay Abd-Algader
73

Sie verwenden entweder die untergeordnete Auswahl

Also mit

#parent > child

Lässt nur die Kinder der ersten Ebene die Stile anwenden. Leider unterstützt IE6 die untergeordnete Auswahl nicht.

Ansonsten können Sie verwenden

#parent child child

Festlegen eines anderen spezifischen Stils für Kinder, die mehr als eine Ebene darunter liegen.

Silviu Postavaru
quelle
1
Können Sie mir dies in JSFiddle in Aktion zeigen? Ich habe versucht, ein Inline-Block-zentriertes Div zu zentrieren, aber es zentriert immer noch den Text innerhalb des Div.
Calmarius
38

allIm CSS3-Vererbungsmodul wird eine Eigenschaft aufgerufen . Es funktioniert so:

#sidebar ul li {
  all: initial;
}

Ab 2016-12 unterstützen alle Browser außer IE / Edge und Opera Mini diese Eigenschaft.

Boldewyn
quelle
4
@AndriusDobrotinas, um irgendwann unterstützt zu werden? Ich scheine Ihren Kommentar nicht vollständig zu erfassen. Es gibt ein PostCSS-Plugin, das diese Funktion bietet, wenn Sie PostCSS verwenden: github.com/maximkoretskiy/postcss-initial
Boldewyn
1
@AndriusDobrotinas, Ihr Kommentar ist sehr nicht konstruktiv. Die Antwort wurde für die Community veröffentlicht. versuchen Sie Ihr Bestes, um den Nutzen zu erkennen.
Cody
2
Derzeit unterstützen es nur IE und Opera Mini nicht, alle anderen gängigen Browser
Legends
@ Boldewyn gibt es keinen 'Standard'-Wert, soweit man aus dem verknüpften w3-Dokument
ersehen
@webeno gab es, als ich die Antwort schrieb: w3.org/TR/2013/WD-css3-cascade-20130103/#all-shorthand Es scheint, dass es einige subtile Unterschiede zwischen dem alten defaultund dem neuen gibt unset, aber im Moment bin ich ' Ich habe keine Zeit, weiter zu untersuchen. Sie können die Antwort jederzeit bearbeiten, um sie auf den neuesten Stand zu bringen.
Boldewyn
24

Mit dem Selektor * können Sie die untergeordneten Stile auf den Standardwert zurücksetzen

Beispiel

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

#parent * {
    white-space: initial;
}
danke: D
quelle
1
Das ist eine sehr schöne Lösung - besonders wenn Sie die Klasse der Eltern nicht kennen.
BurninLeo
Ich glaube, ich kenne die Antwort darauf, aber gibt es trotzdem eine Möglichkeit, dies inline zu setzen? <div id="parent" style="white-space:pre-wrap;*white-space:initial;"/>
1,21 Gigawatt
10

Das Umschließen mit iframe macht das übergeordnete CSS überflüssig.

Tuğrul
quelle
2
Komisch, dass dies die schlechteste Antwort ist, da dies technisch die einzige physische Möglichkeit ist, die CSS-Vererbung zu stoppen. Nicht, dass ich argumentiere, dass Sie es so verwenden sollten.
Davidelrizzo
2
Ich würde vorschlagen, mit CSS nicht physisch zu werden, sondern es in der virtuellen Welt zu belassen, in die es gehört!
michaelward82
Durch das Hinzufügen iframewurde meine untergeordnete Komponente unsichtbar. Gedanken?
Kevin Ghaboosi
5

Die kurze Antwort lautet: Nein, die CSS-Vererbung kann nicht verhindert werden. Sie können nur die Stile überschreiben, die für die übergeordneten Elemente festgelegt wurden. Siehe die Spezifikation:

Jedes Element in einem HTML-Dokument erbt alle vererbbaren Eigenschaften von seinem übergeordneten Element mit Ausnahme des Stammelements ( html), das kein übergeordnetes Element hat. - W3C

Abgesehen davon, dass jede einzelne geerbte Eigenschaft überschrieben wird. Sie können auch initialSchlüsselwörter verwenden, z color: initial;. Es kann auch zusammen mit allz. B. verwendet all: initial;werden, um alle Eigenschaften auf einmal zurückzusetzen. Beispiel:

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

Browser-Support-Tabellen gemäß Kann ich verwenden ...

  • all (Derzeit keine Unterstützung in IE und Edge, andere sind gut)
  • initial (Derzeit keine Unterstützung im IE, andere sind gut)

In einigen Fällen kann es hilfreich sein, die direkte Kinderauswahl zu> verwenden. Beispiel:

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

Der Rahmenstil wurde nur auf die direkten untergeordneten <li>s angewendet , ebenso borderwie eine nicht vererbte Eigenschaft. Die Textfarbe wurde jedoch auf alle untergeordneten Elemente angewendet, ebenso colorwie eine geerbte Eigenschaft.

Daher >wäre der Selektor nur bei nicht vererbten Eigenschaften nützlich, wenn es darum geht, die Vererbung zu verhindern.

Aufkleber
quelle
2

Sie könnten so etwas wie jQuery verwenden, um dieses Verhalten zu "deaktivieren", obwohl ich kaum denke, dass es eine gute Lösung ist, da Sie die Anzeigelogik in CSS und Javascript erhalten. Abhängig von Ihren Anforderungen können Sie jedoch feststellen, dass die CSS-Dienstprogramme von jQuery Ihnen das Leben leichter machen als das Ausprobieren von hackigem CSS, insbesondere wenn Sie versuchen, es für IE6 zum Laufen zu bringen

Neil Richards
quelle
2

Zum Beispiel, wenn Sie zwei div im XHTML-Dokument haben.

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

Versuchen Sie dies dann in CSS.

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

betreffen nur 'div2' Absatz.

#div1 > p {
    color: red;
} 

betrifft nur den Absatz 'div1'.

user2848911
quelle
2

Sie benötigen keine Klassenreferenz für das lis. Anstatt CSS wie zu haben

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

Du kannst schreiben

ul#sidebar > li { color:black; }

Dadurch wird das Styling nur auf lis angewendet, die unmittelbar von der Seitenleiste absteigen ul.

stevenvh
quelle
0

Setzen Sie sie einfach in der Auswahl "#sidebar ul li" auf ihre Standardeinstellungen zurück

Matthew Vines
quelle
Danke für die Antwort. Ja, ich verstehe, dass ich sie im Stil des Unterelements zurücksetzen kann, aber ich versuche dies zu vermeiden, da ich ein Thema verwende, das ich nicht erstellt habe, und mich frage, ob ich eine Menge Zeit sparen kann indem Sie einfach eine "Do-not-Cascade: True" -Regel oder ähnliches verwenden, anstatt alle verschiedenen Stile für die Uls und Lis zu lokalisieren, die überall verstreut sind, und sich dann über unbeabsichtigte Konsequenzen in anderen Bereichen der Site Gedanken machen .