Aufbauend auf Geoff's Einführungsartikel über Das zweite „S“ in CSS, wollen wir nun das „C“ in CSS beleuchten – was wir die Kaskade nennen. Hier wird es langsam unübersichtlich und manchmal sogar verwirrend.
Haben Sie jemals eine CSS-Eigenschaft geschrieben, und der Wert scheint nicht zu funktionieren? Mussten Sie vielleicht auf !important zurückgreifen, um sie zum Laufen zu bringen? Oder haben Sie sich damit beholfen, das CSS inline im HTML-File auf dem Element zu schreiben?
<div style="background:orange; height:100px; width:100px;">
Ack, inline!
</div>
Apropos Inline-Styles: Haben Sie sich jemals gefragt, warum SVG-Editoren diese anstelle einer separaten CSS-Datei verwenden? Das erscheint irgendwie seltsam, oder?
<svg id="icon-logo-star" viewBox="0 0 362.62 388.52" width="100%" height="100%">
<style>
.logo {
fill: #ff9800;
}
</style>
<title>CSS Tricks Logo</title>
<path class="logo" d="M156.58 239l-88.3 64.75c-10.59 7.06-18.84 11.77-29.43 11.77-21.19 0-38.85-18.84-38.85-40 0-17.69 14.13-30.64 27.08-36.52l103.6-44.74-103.6-45.92C13 142.46 0 129.51 0 111.85 0 90.66 18.84 73 40 73c10.6 0 17.66 3.53 28.25 11.77l88.3 64.75-11.74-104.78C141.28 20 157.76 0 181.31 0s40 18.84 36.5 43.56L206 149.52l88.3-64.75C304.93 76.53 313.17 73 323.77 73a39.2 39.2 0 0 1 38.85 38.85c0 18.84-12.95 30.61-27.08 36.5l-103.61 45.91L335.54 239c14.13 5.88 27.08 18.83 27.08 37.67 0 21.19-18.84 38.85-40 38.85-9.42 0-17.66-4.71-28.26-11.77L206 239l11.77 104.78c3.53 24.72-12.95 44.74-36.5 44.74s-40-18.84-36.5-43.56z"></path>
</svg>
Nun, die Kaskade hat viel damit zu tun. Lesen Sie weiter, um herauszufinden, wie sich Styling-Methoden darauf auswirken, was auf Ihre Elemente angewendet wird, und wie Sie die Kaskade zu Ihrem Vorteil nutzen können, denn glauben Sie mir, es ist eine wundervolle Sache, wenn man sie erst einmal verstanden hat.
TL;DR: Springen Sie direkt zum CSS-Ordnungsdiagramm für eine visuelle Darstellung, wie alles funktioniert.
Die Kaskade berücksichtigt, wie und wo Stile geschrieben werden
Es gibt unzählige Möglichkeiten, CSS-Regeln auf ein Element anzuwenden. Unten sehen Sie ein Beispiel, wie stroke: red; auf dasselbe Element angewendet werden kann. Die Beispiele sind nach aufsteigender Priorität geordnet, wobei die höchste Priorität unten steht
<!-- Inheritance -->
<g style="stroke: red">
<rect x="1" y="1" width="10" height="10" /> <!-- inherits stroke: red -->
</g>
<!-- Inline attributes -->
<rect x="1" y="1" width="10" height="10" stroke="red" />
<!-- External style sheet -->
<link rel="stylesheet" href="/path/to/stylesheet.css">
<!-- Embedded styles -->
<style>
rect { stroke: red; }
</style>
<!-- Different specificity or selectors -->
rect { stroke: red; }
.myClass { stroke: red; }
#myID { stroke: red; }
<!-- Inline style -->
<g style="stroke: red"></g>
<!-- Important keyword -->
<g style="stroke: red !important"></g>
Vererbung? Eingebettet? Extern? Inline? Spezifität? Wichtig? Ja, viele Begriffe werden herumgeworfen. Lassen Sie uns diese ein wenig aufschlüsseln, denn jeder einzelne bestimmt, was der Browser letztendlich verwendet, wenn eine Webseite geladen wird.
Elemente können Stile von anderen Elementen erben
Sowohl HTML- als auch SVG-Elemente können CSS-Regeln erben, die auf andere Elemente angewendet werden. Dies nennen wir eine Eltern-Kind-Beziehung, wobei das Element, auf das die CSS angewendet wird, das Elternteil ist und das im Elternteil enthaltene Element das Kind ist.
<div class="parent">
<div class="child">I'm the child because the parent is wrapped around me.</div>
</div>

Wenn wir die Textfarbe des Elternteils festlegen und für das Kind keine Textfarbe deklarieren, dann schaut das Kind zum Elternteil, um zu wissen, welche Farbe sein Text haben soll. Das nennen wir Vererbung und es ist ein Paradebeispiel dafür, wie ein Stil zu einem übereinstimmenden Element kaskadiert ... oder die Kette zum nächsten übereinstimmenden Stil "hochblubbert".
Die Vererbung hat jedoch die niedrigste Priorität unter den Styling-Methoden. Anders ausgedrückt, wenn ein Kind eine Regel hat, die spezifisch für es ist, dann wird der vererbte Wert ignoriert, auch wenn der vererbte Wert ein wichtiges Schlüsselwort haben mag. Das Folgende ist ein Beispiel
<div class="parent" style="color: red !important;">
<div class="child">I'm the child because the parent is wrapped around me.</div>
</div>
Siehe den Pen Child ignores inline inheritance with !important von Geoff Graham (@geoffgraham) auf CodePen.
SVG Inline-Attribute
Für SVG-Elemente können wir Stile auch über Inline-Attribute anwenden, die die zweitniedrigste Priorität in der Kaskade haben. Das bedeutet, dass die CSS-Regeln in einer Stylesheet sie überschreiben können.
<rect x="1" y="1" width="10" height="10" stroke="red" />
rect {
stroke: blue;
}
Siehe den Pen Stylesheet overrides SVG inline attributes von Geoff Graham (@geoffgraham) auf CodePen.
Die meisten SVG-Editoren verwenden Inline-Attribute für die Portabilität; das heißt, die Möglichkeit, einige Elemente zu kopieren und woanders einzufügen, ohne die Attribute zu verlieren. Benutzer können dann das resultierende SVG verwenden und seine Elemente mit einer externen Stylesheet stylen.
Stylesheets
Stylesheets sind in zwei Ausprägungen unterteilt: extern und eingebettet
<!-- External style sheet -->
<link rel="stylesheet" href="/path/to/stylesheet.css">
<!-- Embedded styles -->
<style>
div { border: 1px solid red }
</style>
Eingebettete Stile haben die gleiche Priorität wie externe Stylesheets. Daher gilt, wenn Sie die gleichen CSS-Regeln haben, die Reihenfolgeregeln.
Siehe den Pen Embedded styles override stylesheet rules von Geoff Graham (@geoffgraham) auf CodePen.
Alle Stylesheets folgen Reihenfolgeregeln, wobei später definierte Dateien eine höhere Priorität haben als früher definierte. In diesem Beispiel hat stylesheet-2.css Vorrang vor der Datei stylesheet-1.css, da sie zuletzt definiert wurde.
<link rel="stylesheet" href="/path/to/stylesheet-1.css">
<link rel="stylesheet" href="/path/to/stylesheet-2.css">
Spezifität oder Selektoren
Wie Sie Ihre Elemente auswählen, bestimmt auch, welche Regeln angewendet werden, wobei Tags (z. B. <p>, <div>), Klassen (z. B. .my-class) und IDs (z. B. #myI-id) aufsteigende Prioritäten haben.
Siehe den Pen Specificity by selectors von Geoff Graham (@geoffgraham) auf CodePen.
Im obigen Beispiel, wenn Sie ein Div-Element mit sowohl .my-class als auch #my-id haben, wird der Rand rot sein, weil IDs eine höhere Priorität als Klassen und Tags haben.
*Die Spezifität hat eine höhere Priorität als Reihenfolgeregeln, daher hat die Spezifität unabhängig davon, ob Ihre Regel oben oder unten steht, immer noch eine höhere Priorität und wird angewendet.
Reihenfolge
CSS-Regeln priorisieren immer von links nach rechts und dann von oben nach unten.
<!-- Blue will be applied because it is on the right -->
<div style="border: 1px solid red; border: 1px solid blue;"></div>
<style>
div {
border: 1px solid red;
border: 1px solid blue; /* This will be applied because it is at the bottom */
}
</style>
Inline-Styles
Inline-Stile haben die zweithöchste Priorität, direkt unter dem Schlüsselwort !important. Das bedeutet, dass Inline-Stile nur durch das wichtige Schlüsselwort und nichts anderes überschrieben werden. Innerhalb von Inline-Stilen gelten normale Reihenfolgeregeln, von links nach rechts und von oben nach unten.
<div style="1px solid red;"></div>
Das wichtigste Schlüsselwort
Apropos das Schlüsselwort !important: Es wird verwendet, um Reihenfolge-, Spezifitäts- und Inline-Regeln zu überschreiben. Mit anderen Worten, es hat unglaubliche Kräfte.
Überschreiben von Inline-Regeln
<style>
div {
/* This beats inline styling */
border: 1px solid orange !important;
/* These do not */
height: 200px;
width: 200px;
}
</style>
<div style="border: 1px solid red; height: 100px; width: 100px;"></div>
Im obigen Beispiel würde das Div ohne das wichtige Schlüsselwort einen roten Rand haben, da Inline-Styling eine höhere Priorität als eingebettete Stile hat. Aber mit dem wichtigen Schlüsselwort wird der Div-Rand orange, da das wichtige Schlüsselwort eine höhere Priorität als Inline-Styling hat.
Die Verwendung von !important kann sehr nützlich sein, sollte aber mit Vorsicht eingesetzt werden. Chris hat einige Gedanken dazu, in welchen Situationen es sinnvoll ist, es zu verwenden.
Überschreiben von Spezifitätsregeln
Ohne das wichtige Schlüsselwort hätte dieser Div-Rand blau, weil Klassen eine höhere Priorität als Tags in der Spezifität haben.
<style>
/* Classes have higher priority than tags */
.my-class {
border: 1px solid blue;
height: 100px;
width: 100px;
}
div {
border: 1px solid red;
height: 200px;
width: 200px;
}
</style>
<div class="my-class"></div>
Siehe den Pen Classes beat tags von Geoff Graham (@geoffgraham) auf CodePen.
Aber! Das Hinzufügen des wichtigen Schlüsselworts zu den Tag-Regeln weist das Element an, die Kaskade zu ignorieren und Vorrang vor den Klassenregeln zu haben.
<style>
.my-class { border: 1px solid red; }
/* The important keyword overrides specificity priority */
.my-class { border: 1px solid blue !important; }
</style>
<div class="my-class"></div>
Siehe den Pen !important ignores the cascade von Geoff Graham (@geoffgraham) auf CodePen.
Überschreiben von Reihenfolgeregeln
OK, wir haben bereits darüber gesprochen, wie die Reihenfolge der Regeln die Spezifität beeinflusst: unten schlägt oben und rechts schlägt links. Der sichere Weg, dies zu überschreiben, ist, !important wieder zu verwenden.
In diesem Beispiel erhält der Div den roten Rand, obwohl der blaue Rand die untere Regel ist. Dafür können Sie !important danken.
<style>
div { border: 1px solid red !important; } /* This wins, despite the ordering */
div { border: 1px solid blue; }
</style>
<div></div>
Siehe den Pen Important wins over ordering von Geoff Graham (@geoffgraham) auf CodePen.
Visualisierung der Kaskade
Wer hätte gedacht, dass das „C“ in CSS so viel Bedeutung hat? Wir haben hier eine Menge Stoff behandelt und hoffentlich hilft es, die Art und Weise, wie Stile durch unsere Schreibweise beeinflusst und angewendet werden, zu verdeutlichen. Die Kaskade ist ein mächtiges Werkzeug. Es gibt viele Meinungen darüber, wie man sie richtig einsetzt, aber Sie können die verschiedenen Wege sehen, wie Eigenschaften von Elementen weitergegeben und vererbt werden.
Eher visuell orientiert? Hier ist eine Übersicht, die alles zusammenfasst.
Thomas, danke für die schöne visuelle Anleitung zur CSS-Kaskade. Leider sind Ihr Artikel und dieses Diagramm nicht ganz technisch korrekt: Die Behauptung, dass eingebettete Stile immer verlinkte Stile überschreiben, ist falsch. Die CSS Cascading and Inheritance Spezifikation unterscheidet diese nicht, sondern behandelt sie als die gleiche Kaskadierungsursprung (Author Origin) und sagt im Wesentlichen, dass verlinkte Stile durch äquivalente eingebettete Stile ersetzt werden, wenn die Priorität berechnet wird ("Deklarationen aus Style Sheets, die unabhängig voneinander vom Ursprungsdokument verlinkt sind, werden so behandelt, als ob sie in der Verlinkungsreihenfolge verkettet wären"). Und unter den Stilen von demselben Ursprung und mit derselben Spezifität zählt nur die resultierende Reihenfolge der Deklarationen.
In Ihrer Codepen-Demo gibt es tatsächlich zwei eingebettete Stylesheets – eines in
<head>und eines in<body>(zumindest sehe ich das dort im DOM-Inspektor), und letzteres gewinnt über ersteres nur wegen der Reihenfolge. Wenn Sie jedoch den Link zu denselben Stilen wie die externe Ressource nach dem letzten eingebetteten Stylesheet hinzufügen, würden diese externen Stile es überschreiben, wie in dieser Abzweigung Ihres Codepens: https://codepen.io/SelenIT/pen/pQRGEv@Ilya, vielen Dank, dass Sie auf diesen Fehler hingewiesen haben. Ich werde den Artikel und auch das Diagramm entsprechend ändern, sehr geschätzt!
Ich bin sehr verwirrt von dieser Priorität von rechts nach links. Ihre Beispiele sind, soweit ich das beurteilen kann, unvollständig: style="1px solid red" bewirkt nichts. Könnten Sie präziser sein?
Oder liegt es einfach daran, dass es "nach" dem vorherigen definiert wird? und somit rechts von der vorherigen Definition? Dies ist keine Priorität nach rechts, dies ist die Codierungsreihenfolge ...
@Ben, danke für den Hinweis, das richtige Beispiel wäre
<div style="border: 1px solid red; border: 1px solid blue;">
Einfach ausgedrückt: Wenn Sie 2 Regeln haben, die auf dasselbe Element zutreffen, gewinnt die Regel, die rechts oder unten steht, aufgrund der Reihenfolgeregeln. Hoffentlich hilft das.
Ich habe mich gefragt, welche Art von Eigenschaften in CSS vererbt werden, während ich diesen Beitrag gelesen habe, und welche nicht. Es scheint, dass es nicht einmal einfach ist, eine Liste aller vererbten Eigenschaften zu erhalten, und es scheint keine klaren/logischen Regeln zu geben. Ich denke, es ist für einen CSS-Anfänger nicht so einfach zu erraten, welche davon vererbt werden oder nicht, ohne auf MDN oder eine andere Art von Referenz zurückzugreifen.
@Guillaume, leider ist das richtig, aber das klingt nach einer guten Gelegenheit, ein Diagramm zur einfachen Referenz zu erstellen, und wir lieben Diagramme :) Ich werde sehen, was ich tun kann.
Hallo Thomas, ich habe endlich einen Weg gefunden, diese Werte aufzulisten. Langfassung: Ich habe eine Fetch-Anfrage von der Chromium-Website über ihren Suchformulare-Endpunkt durchgeführt. Sie finden das Skript hier: https://gist.github.com/cdoublev/1a5c4498adde3c6e775de5f0327dead4. Ich habe mein Google Sheet bearbeitet, das ich als persönliche CSS-Konvention zur Ordnung von CSS-Eigenschaften verwende: https://docs.google.com/spreadsheets/d/1JIeXks17Wuad_wtDCoB–GOl1RwBQX7VP1IEd-iDHgo/. Die von mir verwendeten Bezeichnungen zur Gruppierung von Eigenschaften sind möglicherweise semantisch falsch, aber ich glaube nicht, dass eine Nomenklatur existiert. Fühlen Sie sich frei, sie für Ihre eigenen Recherchen zu verwenden (ein Sheet könnte eine gute Option für Diagramme sein).
Hinweis: Veraltete Eigenschaften wurden in meinem Sheet freiwillig weggelassen.
Einige vererbte Eigenschaften fehlten bei dieser Methode. Deshalb gab ich schließlich auf und überprüfte alle manuell auf MDN... Es stellte sich heraus, dass fast alle davon vererbte Kurzschreib-Eigenschaften waren. Aber es war eine bessere Option, als es mit MDN oder W3C zu versuchen. Keiner von beiden bietet eine API an. Es wäre eine echte Qual gewesen, HTML zu parsen, um den Vererbungswert jeder Eigenschaft abzurufen. Darüber hinaus fehlen einige Eigenschaften in ihrer jeweiligen Referenzliste: https://developer.mozilla.org/en-US/docs/Web/CSS/Reference und https://www.w3.org/TR/CSS/#properties.
Vielen Dank, @Guillaume, das ist eine sehr beeindruckende Arbeit. Vielen Dank, dass Sie sie mit uns geteilt haben. Wir werden sehen, wie wir diese Informationen in ein Diagramm umwandeln können, und werden Ihnen einen Entwurf zeigen, bevor wir ihn fertigstellen. Möchten Sie mir Ihre E-Mail-Adresse an [email protected] senden? Danke!