Einführung
Wenn Sie als Frontend-Entwickler bereits mit einem CSS-Präprozessor gearbeitet haben, sind Sie wahrscheinlich schon auf die Verschachtelungsfunktion gestoßen oder haben sie sogar selbst genutzt. Sie ist eine beliebte Funktion und war für mich einer der Gründe, warum ich überhaupt einen CSS-Präprozessor verwende.
Dieses Jahr wurde die native CSS-Verschachtelung in allen gängigen Browsern – Chrome, Firefox und Safari – eingeführt. Sie ist eine grundlegende CSS-Funktion, die das Schreiben von CSS deutlich vereinfacht. In diesem Artikel dokumentiere ich meine bisherigen Erkenntnisse zur CSS-Verschachtelung und teile sie mit Ihnen, inklusive Anwendungsbeispielen.
Es gibt keine Voraussetzungen außer Ihrer Begeisterung und Konzentration.
Verschachtelung in CSS war für viele Entwickler ein lang ersehntes Feature. Früher waren wir auf CSS-Präprozessoren wie Sass oder Less angewiesen. Hier ein kurzer Überblick:
Betrachten wir folgendes Beispiel. Wir haben ein Symbol, das sich im Selektor .nav__item befindet.
.nav__item {
.icon {
display: flex;
padding: 1rem;
}
}Der obige Code ist gültiger Sass-Code. Nach dem Kompilieren sieht er im Browser folgendermaßen aus:
.nav__item .icon {
display: flex;
padding: 1rem;
}Bei nativer CSS-Verschachtelung funktioniert derselbe CSS-Code unverändert. Die folgende Abbildung zeigt einen Vergleich zwischen nativer CSS-Verschachtelung und den Entwicklertools des Browsers.
Beachten Sie, wie der Browser das CSS ähnlich (fast) so anzeigt, wie es im CSS angezeigt wird.
Wenn dieser CSS-Code in Sass kompiliert würde, würde der Browser ihn wie folgt anzeigen:
Vorteile der CSS-Verschachtelung
Meiner Meinung nach gibt es triftige Gründe, warum verschachteltes CSS nützlich ist:
- CSS ist leichter lesbar.
- Gruppierungsstil zusammen
- Einschränkung bestimmter Stile
- Formatierung von HTML-Elementen ohne Klassen oder IDs.
CSS-Verschachtelungsregeln
Um Sie über CSS-Verschachtelung aufzuklären, werde ich versuchen, Ihnen visuelle Beispiele für verschiedene CSS-Probleme zu geben und zu zeigen, wie Verschachtelung bei deren Lösung helfen kann.
Zunächst einmal müssen Sie das kaufmännische Und-Zeichen (&) kennenlernen. Es gibt mehrere Situationen, in denen dieses Symbol unerlässlich ist.
Ein Element ohne Klasse oder ID verschachteln
In diesem Beispiel ist das Element <a> Die Formatierung erfolgt über .nav__item. Die Verwendung des <head>-Tags ist für die Gültigkeit des CSS optional.
.nav__item {
& a {
display: block;
padding: 1.5rem 1rem;
}
}
/* Same as: */
.nav__item a {
}Sie können das Häkchen auch entfernen:
.nav__item {
a {
display: block;
padding: 1.5rem 1rem;
}
}
/* Same as: */
.nav__item a {
}Beachten Sie, dass es sich hierbei um ein aktuelles Update handelt, das als „Relaxed CSS Nesting“ bezeichnet wird. Es funktioniert in der neuesten Chrome Canary- und Safari Technology Preview-Version. Lesen Sie dazu den Beitrag von Adam Argyle.
Ein Element mit einer Klasse verschachteln
Betrachten wir dasselbe Beispiel wie zuvor, aber nehmen wir an, dass das Element <a> Es besitzt eine HTML-Klasse.
.nav__item {
.link {
display: block;
padding: 1.5rem 1rem;
}
}
/* Same as: */
.nav__item .link {
}Hier ist kein Symbol nötig. Der Klassenname genügt völlig.
Verschachtelte CSS-Kombinatoren
Einer der Vorteile von CSS Native Nesting ist die Verwendung von Kombinatoren. Schauen wir uns einige Beispiele an.
Im folgenden Beispiel möchte ich alle Elemente mit der Klasse `.nav__item` auswählen, denen ein anderes Element mit derselben Klasse vorangeht. Dazu habe ich den Selektor für benachbarte Geschwisterelemente verwendet.
In nativem CSS können wir dies mit dem kaufmännischen Und-Zeichen (&) nachbilden. Beachten Sie, dass ich es zweimal wiederholt habe.
.nav__item {
& + & {
border-left: 2px solid;
}
}
Die Magie geschieht in der zweiten Iteration des kaufmännischen Und-Zeichens. Hier erkennt der Browser, dass ich den Selektor für das benachbarte Geschwisterelement verwenden möchte. Ich zeige Ihnen eine Abbildung, die dies veranschaulicht:
Ein weiteres Beispiel für Verschachtelung ist der Kindkombinator. Er kann das direkte Kindelement eines Elements auswählen.
.nav__item {
> a {
padding: 1rem;
}
}Ampersand-Symbol
.nav__item {
& a {
color: blue;
}
}Dies war in der ursprünglichen CSS-Spezifikation für Verschachtelungen erforderlich. In Safari TP 179+ und Chrome Canary 120 ist das kaufmännische Und-Zeichen (&) für verschachtelte Elemente nicht mehr notwendig.
Als Ergebnis ergeben sich folgende Werke:
.nav__item {
a {
color: blue;
}
}Das einzige Problem ist, dass Sie auf die vorherige Version der Spezifikation zurückgreifen müssen, die die Auszeichnung und die Auszeichnung enthalten muss.
Verschachtelung mit Beispiel: Aktiv, Fokus, Hover
:active, :focus und :hover sind CSS-Pseudoklassen, die durch Benutzeraktionen aktiviert werden.
Mithilfe von CSS-Verschachtelung können wir alle Elemente gleichzeitig verschachteln, um Code-Duplizierung zu vermeiden. Nehmen wir :hover als Beispiel:
button {
&:hover {
background-color: var(--bg-color);
}
&:focus {
outline: solid 2px;
}
}Der Unterschied bei der Verwendung eines Präprozessors für Verschachtelungen besteht darin, dass der Browser sie wie folgt darstellt:
button:hover {
background-color: var(--bg-color);
}
button:focus {
outline: solid 2px;
}Schauen wir uns an, wie CSS-Verschachtelungen in Chrome, Safari und Firefox dargestellt werden.
Ich habe einige Gedanken zur Benutzerfreundlichkeit der Entwicklertools für die CSS-Verschachtelung, auf die ich später im Artikel eingehen werde.
Verschachtelung mit Beispiel: Veröffentlichung von Inhalten
Eines der ersten Beispiele für das Testen von verschachteltem CSS ist die Gestaltung des Inhalts eines Beitrags. Stellen Sie sich einen Artikel mit Überschriften, Text, Bildern, Zitaten und mehr vor.
Schlagzeilen
Wir neigen dazu, Titel wie folgt zu gestalten:
.post-content h1,
.post-content h2,
.post-content h3,
.post-content h4 {
/* styles here */
}Mit verschachteltem CSS ist es einfacher:
.post-content {
h1,
h2,
h3,
h4 {
color: var(--heading-color);
font-weight: var(--heading-font-bold);
margin-bottom: var(--size-2);
}
}Dasselbe können wir auch mit dem Selektor :is() erreichen.
.post-content {
:is(h1, h2, h3, h4) {
color: var(--heading-color);
font-weight: var(--heading-font-bold);
margin-bottom: var(--size-2);
}
}Absatzelement
Ein häufiger Anwendungsfall ist die Gestaltung eines Links innerhalb eines Absatzes. In solchen Fällen eignet sich die CSS-Verschachtelung hervorragend.
.post-content {
& p {
color: var(--color-black);
& a {
font-weight: bold;
text-decoration: underline;
}
}
}Der Link erfordert möglicherweise auch einen Hover- oder Fokus-Effekt.
.post-content {
& p {
color: var(--color-black);
& a {
font-weight: bold;
text-decoration: underline;
&:hover {
/* hover styles */
}
}
}
}Wir können auch Media Queries verschachteln.
.post-content {
& p {
/* base styles */
@media (min-width: 400px) {
/* do something */
}
}
}In einigen Fällen kann ein CMS ein Element sein. <p> Umschließen Sie es mit einem anderen Element, und aus stilistischen Gründen sollte es nur für direkte Elemente verwendet werden. <p> Style es.
.post-content {
/* Select the direct <p> elements */
> p {
/* base styles */
}
}Zitat
In diesem Beispiel erhält das Zitat einen eigenen benutzerdefinierten Stil und das Element <p> Innerhalb des Zitats können Sie die Option wählen, den unteren Rand auf Null zurückzusetzen.
.post-content {
& blockquote {
/* custom quote styling */
& p {
margin-bottom: 0;
}
}
}Pfostenform
Das Formular enthält ein Bild und ein
In meinem Beispiel, wenn
.post-content {
& figure {
& img {
/* the figure's image styles */
}
/* changes to the <figure> container, if it has a figcaption element */
&:has(figcaption) {
display: flex;
align-items: start;
}
& figcaption {
/* caption styling */
}
}
}Liste der Beiträge
Ich möchte allen Listenelementen außer dem letzten einen Rahmen hinzufügen. Dazu habe ich den Selektor :not() verwendet.
.post-content {
li {
&:not(:last-child) {
border-bottom: 1px solid;
}
}
}Um :not() verwenden zu können, muss ein kaufmännisches Und-Zeichen davor gesetzt werden.
Benutzerdefinierter Abstand für Überschriften
Der folgende Abstand sollte betragen <h3> Und <h4> Ich werde die Anzahl reduzieren, wenn auf einen der Punkte ein Code-Snippet folgt.
.post-content {
& h3 + [class*="language-"],
& h4 + [class*="language-"] {
margin-top: 0.5rem;
}
}Wie Sie in diesem praktischen Beispiel gesehen haben, ist die Verwendung von CSS-Verschachtelung einfach, insbesondere wenn Sie Erfahrung mit CSS-Präprozessoren haben.
Verschachtelung mit Beispiel: Kartenkomponente
Ich werde eine einfache Kartenkomponente vorstellen, die mithilfe von CSS-Verschachtelung die gewünschten Stile erzielt.
Angenommen, es gibt ein .card-Element mit Standard- oder Basisstilen, werde ich die Verwendung von verschachteltem CSS demonstrieren.
.card {
/* default card styles */
}
VERSCHNITTENE CONTAINER-ABFRAGEN
Wenn die Containerbreite größer als 400px ist, soll die Karte in einen flexiblen Container umgewandelt werden.
.card {
/* default card styles */
/* if the container width is 400px or bigger */
@container card (min-width: 400px) {
display: flex;
}
}Formatierung eines Absatzelements
Ich möchte das Absatz-Element verwenden über <h3> Auf diese Weise kann ich dem Element Ränder und Innenabstände zuweisen. <p> Ich füge noch etwas hinzu: Wenn es nicht vorhanden ist, fehlt der zusätzliche Abstand in der Benutzeroberfläche.
.card__content {
& h3 + p {
border-top: 1px solid #000;
padding-top: 0.5rem;
margin-top: 0.5rem;
}
}Wenn die Containerbreite 400 Pixel oder mehr beträgt, sollte das .card__content-Element ebenfalls in einen flexiblen Container umgewandelt werden.
.card__content {
& h3 + p {
border-top: 1px solid #000;
padding-top: 0.5rem;
margin-top: 0.5rem;
}
@container card (min-width: 400px) {
display: flex;
flex-direction: column;
justify-content: center;
}
}Verschachtelung mit Beispiel: Formulareingabe
Ein häufiger Anwendungsfall ist die Formatierung eines Eingabefeldplatzhalters. Das Problem ist, dass jeder Browserhersteller sein eigenes Präfix verwendet (ach, wir haben 2023).
Da Präfixstile einen Doppelpunkt erfordern, müssen wir das &-Symbol verwenden, sonst funktionieren die Stile nicht.
input {
--placeholder-color: #969696;
/* other styles */
&::-webkit-input-placeholder {
color: var(--placeholder-color);
}
&::-moz-placeholder {
color: var(--placeholder-color);
opacity: 1;
}
&:-moz-placeholder {
color: var(--placeholder-color);
}
}Sie fragen sich vielleicht, worin der Unterschied zwischen der Verwendung von verschachteltem CSS und dem direkten Schreiben eines Präfixstils ohne Verschachtelung besteht.
/********** Option 1: native nesting **********/
input {
&::-webkit-input-placeholder {
color: var(--placeholder-color);
}
}
/********** Option 2: without nesting **********/
input::-webkit-input-placeholder {
color: var(--placeholder-color);
}Zwischen den beiden besteht kein Unterschied. Beide haben die gleichen Eigenschaften (0, 1, 1).
Verschachtelung mit Beispiel: Ein Element über sein übergeordnetes Element formatieren
Mithilfe von CSS-Verschachtelung können wir die Stile eines Kindelements abhängig von seinem Speicherort ändern. Befindet sich beispielsweise ein .button-Element in einem .box-Elternelement, sollte es die volle Breite einnehmen.
<div class="box">
<h2>Get access to all features</h2>
<p>Create an account now and get access to all exclusive features.</p>
<a href="/offer" class="button">Create an account</a>
</div>.button {
.box & {
width: 100%;
}
}
/* equivalent to */
.box .button {
}Fehler, die mir beim Erkunden von CSS-Verschachtelung aufgefallen sind
Verwendung des unsigned globalen Selektors
Angenommen, wir haben eine Karte und möchten alle darin enthaltenen Elemente auswählen. Mit der nativen CSS-Verschachtelung sollte dies funktionieren:
.card {
* {
/* styles here */
}
}Mir ist aufgefallen, dass dies in Chrome Stable nicht funktioniert, aber in Chrome Canary 121, Safari 17.1 und Firefox 119 funktioniert es einwandfrei.
Die Lösung besteht darin, das Satzzeichen hinzuzufügen.
.card {
& * {
/* styles here */
}
}Verwendung vorzeichenloser Datenattribute
In diesem Fall führt die Auswahl eines Datenattributs ohne Häkchen nicht zum erwarteten Ergebnis.
.card {
[data-type="featured"] {
/* styles here */
}
}Mir ist aufgefallen, dass es in Chrome Stable nicht funktioniert, aber in Chrome Canary 121, Safari 17.1 und Firefox 119 einwandfrei funktioniert.
Um das zu beheben, müssen wir ein Komma hinzufügen:
.card {
&[data-type="featured"] {
/* styles here */
}
}Beide Fehler wurden mit der Einführung der gelockerten CSS-Verschachtelung in Chrome Canary behoben.
Identifizieren der CSS-Verschachtelungsunterstützung
Mit @supports lässt sich prüfen, ob CSS-Verschachtelung unterstützt wird. In unserem Fall möchten wir prüfen, ob der Browser das kaufmännische Und-Zeichen (&) erkennt.
@supports selector(&) {
.post-content {
& h2 {
/* styles here. */
}
}
}Weitere Möglichkeiten zur Identifizierung von Unterstützung in diesem Codepen von Bramus finden Sie hier.
Ich werde heute das PostCSS-Nesting-Plugin verwenden, das verschachteltes CSS in reguläres CSS kompiliert. Ich werde das Plugin entfernen, sobald es sicher zu verwenden ist.
DevTools-Benutzererfahrung für CSS-Verschachtelung
Ich bin kein großer Fan der aktuellen Benutzerführung für die CSS-Verschachtelung in den Browser-Entwicklertools.
Ich habe an einem separaten Artikel gearbeitet, in dem ich einige Vorschläge zur Gestaltung der CSS-Verschachtelung in den Entwicklertools vorgestellt habe.
Ergebnis
Die CSS-Verschachtelung ist eine wichtige Funktion, die die Art und Weise, wie CSS geschrieben wird, verbessert. Aktuell ist die Verwendung von Verschachtelung zwar möglich, jedoch ist Vorsicht im Hinblick auf die Zielgruppe geboten, da die Unterstützung noch relativ neu ist.
























