paint-brush
Wir schreiben das Jahr 2023, aber wir müssen immer noch über verschachtelte Stile in CSS sprechenvon@lastcallofsummer
3,720 Lesungen
3,720 Lesungen

Wir schreiben das Jahr 2023, aber wir müssen immer noch über verschachtelte Stile in CSS sprechen

von Olga Stogova8m2023/07/17
Read on Terminal Reader
Read this story w/o Javascript

Zu lang; Lesen

Tief verschachtelte Stile führen oft zu Stilkonflikten, insbesondere wenn Sie ein großes Projekt haben. Dies kann zu unerwarteten visuellen Inkonsistenzen und viel Zeitverschwendung führen. Das Konzept der Spezifität (oder des „Gewichts“ von Stilen) in CSS ist entscheidend für das Verständnis, warum tiefe Verschachtelung problematisch sein kann.
featured image - Wir schreiben das Jahr 2023, aber wir müssen immer noch über verschachtelte Stile in CSS sprechen
Olga Stogova HackerNoon profile picture
0-item

Sogar ein zufälliges Bild für die Anfrage „CSS-Stile“ enthält verschachtelte Stile.


Als Frontend-Entwickler mit fast 15 Jahren Erfahrung habe ich die Entwicklung der Webentwicklung aus erster Hand miterlebt. Für mich ist es ein langer Weg von den Tagen des Hochladens geänderter Dateien per FTP (ja, GitHub wurde vor 15 Jahren gestartet, aber ich habe es erst 2011 entdeckt) bis zur modernen Ära responsiver Schnittstellen, UI-Bibliotheken und direkt daraus generierten Websites Figma.


Dennoch stoße ich immer noch auf Projekte, die verschachtelte Stile verwenden, wie zum Beispiel:


 .some-class ul li div a { /* some style */ }


oder,


 #nav .nav-link svg { /* some style */ }


Es mag schockierend erscheinen, aber solche Codierungspraktiken durchdringen alles, von schnell wachsenden Multimillionen-Dollar-Projekten bis hin zu bescheidenen Startups.


Lassen Sie uns untersuchen, warum dieser Ansatz Probleme bereiten kann.

Der Konflikt verschachtelter Stile

Tief verschachtelte Stile führen oft zu Stilkonflikten, insbesondere wenn Sie ein großes Projekt haben. Als kaskadierendes Stylesheet wird CSS kaskadiert und je nach Spezifität auf Elemente angewendet. Tief verschachtelte Stile können aufgrund ihrer Spezifität andere Stile unbeabsichtigt überschreiben.


Betrachten Sie dieses Beispiel:


 .some-class ul li div a { color: red; } ... .some-class a { color: blue; }


Sie könnten erwarten, dass alle Links in .some-class blau sind. Aufgrund der größeren Spezifität der ersten Regel ist jedoch jeder Link, der in einem ul > li > div verschachtelt ist, rot und nicht blau. Dies kann zu unerwarteten visuellen Inkonsistenzen und viel Zeitverschwendung beim Debuggen führen.

Die Komplexität der Spezifität

Das Verständnis des Konzepts der Spezifität (oder des „Gewichts“ von Stilen) in CSS ist entscheidend, um zu verstehen, warum tiefe Verschachtelung problematisch sein kann. Die Spezifität bestimmt, welche CSS-Regel gilt, wenn mehrere Regeln um ein einzelnes Element konkurrieren. Sie wird basierend auf der Art und Anzahl der Selektoren berechnet.


Die Spezifität wird basierend auf einem Gewichtungssystem mit vier Kategorien berechnet:


  1. Inline-Stile
  2. Ausweise
  3. Klassen, Attribute und Pseudoklassen
  4. Elemente und Pseudoelemente


Beachten Sie hier die Regel:


 body #content .data img:hover { /* some style */ }


Die Spezifität beträgt 0 1 2 2 . Das sind eine ID ( #content ), zwei Klassen ( .data und :hover ) und zwei Elemente ( body und img ).


Betrachten Sie nun die Regel:


 #nav .nav-link svg { /* some style */ }


Die Spezifität beträgt hier 0 1 1 1 . Das ist eine ID ( #nav ), eine Klasse ( .nav-link ) und ein Element ( svg ).


Spezifität basiert nicht auf einem „Übertrag“-System wie herkömmliche Dezimalzahlen. Beispielsweise ist ein Selektor mit einer Spezifität von 0 1 0 11 nicht gleich einer Spezifität von 0 1 1 1, obwohl in einem Dezimalsystem 11 und 1+1 gleichwertig wären.


Schließlich haben der universelle Selektor ( * ), die Kombinatoren ( + , > , ~ , ' ') und die Negationspseudoklasse ( :not() ) keinen Einfluss auf die Spezifität. Innerhalb des :not() Arguments werden die Selektoren jedoch wie gewohnt gezählt.


Für visuelle Lerner empfehle ich dieses Video über CSS-Spezifität.


Wenn Sie die CSS-Spezifität und deren Berechnung verstehen, können Sie besseres, vorhersehbareres CSS schreiben und Probleme beheben, wenn Stile nicht wie erwartet angewendet werden.

Die !important Regel und Besonderheit

Manchmal greifen Entwickler auf die !important Regel zurück, wenn sie Schwierigkeiten mit CSS-Spezifitätskonflikten haben. Diese Regel macht eine CSS-Eigenschaft äußerst spezifisch, was bedeutet, dass sie fast jede andere Deklaration überschreibt.


Zum Beispiel:


 #nav .nav-link svg { color: blue; } .nav-link svg { color: red !important; }


Obwohl die erste Regel aufgrund des ID-Selektors eine höhere Spezifität aufweist, wäre die Farbe des svg aufgrund des !important in der zweiten Regel rot.

Die Risiken einer übermäßigen Verwendung von !important

Auch wenn !important eine schnelle Lösung sein kann, wenn Sie mit Spezifitätsproblemen zu kämpfen haben, ist es nicht empfehlenswert, es ausgiebig zu verwenden. Übermäßiger Gebrauch kann die Wartbarkeit, Vorhersagbarkeit und Leistung beeinträchtigen. In größeren Projekten deutet die übermäßige Verwendung von !important häufig auf Schwierigkeiten bei der Verwaltung der CSS-Spezifität hin. Anstatt auf !important zurückzugreifen, ist es oft besser, Zeit in die Umgestaltung Ihres CSS zu investieren und die Verwendung übermäßig spezifischer Selektoren zu reduzieren.


Sie können Ihr Produkt jetzt überprüfen 🙂. Ich habe meines überprüft:


111 Ergebnisse in 55 Dateien, nicht schlecht für ein großes Produkt!


Während !important eine verlockende schnelle Lösung sein könnte; Es ist, als würde man mit einem Vorschlaghammer eine Nuss knacken. Ein wartbarerer Ansatz besteht darin, Ihre Selektoren so einfach und flach wie möglich zu halten, damit Ihr CSS in Zukunft leichter zu verstehen, zu verwalten und zu erweitern ist. Und denken Sie daran: Der beste Weg, einen !important Krieg zu gewinnen, besteht darin, ihn gar nicht erst zu beginnen.

Durchqueren des CSS-Baums

Ein weiteres Problem bei tief verschachtelten Stilen ist die Auswirkung auf die Leistung beim Browser-Rendering. Wenn ein Browser Stile auf ein Element anwendet, durchläuft er das DOM von rechts nach links, beginnend mit der Tastenauswahl (in unseren Beispielen a und svg ) und durchläuft die Vorfahren, bis er eine Übereinstimmung findet oder die Spitze erreicht. Je verschachtelter der Stil ist, desto länger dauert dieser Durchlauf, was möglicherweise die Leistung beeinträchtigt und die Seitenladezeiten bei großen Projekten verlangsamt.


Wenn Sie eine CSS-Regel angeben, wie zum Beispiel:


 .some-class ul li a { /* some style */ }


Sie können sich diese Regel vorstellen, beginnend am unteren Ende des Baums (vom a Tag) und sich durch den Baum nach oben arbeitend (über li , ul und .some-class ).



nur ein kleiner Teil des CSS-Objektmodells



Der Browser sucht zunächst nach allen (ich meine ALLE) a Elementen und prüft dann, ob sich diese a Tags in li Elementen befinden. Danach wird geprüft, ob sich diese li Elemente in ul befinden. Und schließlich wird geprüft, ob sich diese ul in einem Element mit der Klasse .some-class befinden.


Dies ist die Art und Weise, wie Browser CSS-Selektoren lesen und der Grund, warum komplexe Selektoren zu einer langsameren Seitenwiedergabe führen können. Der Browser muss für jedes Element mehrere Prüfungen durchführen, um festzustellen, ob es der angegebenen Regel entspricht. Je tiefer die Regel, desto mehr Prüfungen muss der Browser durchführen, was sich auf die Leistung auswirken kann.

Bessere Praktiken für die CSS-Verwaltung in größeren Projekten

CSS-Module

Mit CSS-Modulen können Sie CSS in einzelnen Modulen schreiben, die lokal auf die Komponente beschränkt sind, an der Sie arbeiten. Das bedeutet, dass Stile in einem CSS-Modul nur auf dieses spezifische Modul anwendbar sind und nicht nach außen dringen oder andere Elemente auf der Seite beeinträchtigen.


Lassen Sie uns untersuchen, wie CSS-Module gehashte Klassennamen verwenden, um die Stilkapselung sicherzustellen. Wenn Sie CSS-Module verwenden, werden die Klassennamen, die Sie in Ihrer CSS-Datei definieren, zur Kompilierungszeit gehasht. Dieser Hash erstellt einen eindeutigen Klassennamen, der Ihrer Komponente entspricht. Schauen wir uns ein Beispiel an:


Angenommen, Sie haben ein CSS-Modul wie folgt definiert:


 /* Button.module.css */ .button { color: white; background-color: blue; }


Und Sie verwenden es in Ihrer Komponente wie folgt (ich bevorzuge den Import des Styles-Objekts als s statt als styles – ein kurzer Tipp, der Tippzeit spart und die Codierungseffizienz steigert):


 import React from 'react'; import s from './Button.module.css'; const Button = () => { return ( <button className={s.button}>Click me</button> ); }; export default Button;


Wenn Ihre Anwendung kompiliert ist, könnte Ihr gerenderter HTML-Code etwa so aussehen:


 <button class="Button_button__3FQ9Z">Click me</button>


In diesem Fall ist Button_button__3FQ9Z der gehashte Klassenname, der von Ihrem CSS-Modul generiert wurde. Beachten Sie, dass die genaue Struktur und Länge des Hashs je nach Projektkonfiguration variieren kann.


Dieser eindeutige Klassenname stellt sicher, dass die Stile, die Sie in Button.module.css definiert haben, nur für diese Schaltfläche gelten und keine Auswirkungen auf andere Elemente in Ihrer Anwendung haben. Es stellt außerdem sicher, dass keine anderen Stile diese Schaltfläche beeinflussen können, es sei denn, sie zielen explizit auf den gehashten Klassennamen ab. Diese Kapselung von Stilen ist einer der Hauptvorteile von CSS-Modulen.

CSS-in-JS-Bibliotheken

Eine weitere beliebte Möglichkeit, mit CSS umzugehen, ist die Verwendung von CSS-in-JS-Bibliotheken wie styled-components oder emotions . Mit diesen Bibliotheken können Sie Ihr CSS direkt in Ihrem JavaScript schreiben, was mehrere Vorteile hat:


  1. Bereichsbezogene Stile : Ähnlich wie CSS-Module sind Stile auf die Komponente beschränkt, in der sie definiert sind.
  2. Dynamische Stile : Es ist einfach, dynamische Stile basierend auf Requisiten oder Status in Ihrer Komponente zu erstellen.
  3. Verbesserte Entwicklererfahrung : Sie können JavaScript-Logik direkt in Ihren Stilen verwenden und alles, was mit einer Komponente zu tun hat, befindet sich an einem Ort, was das Verständnis und die Arbeit mit Ihrem Code erleichtert.


Hier ist ein Beispiel dafür, wie Sie styled-components in einer React-Anwendung verwenden können:


 import React from 'react'; import styled from 'styled-components'; const Button = styled.button` color: white; background-color: ${(props) => props.primary ? 'blue' : 'gray'}; `; const App = () => { return ( <div> <Button primary>Primary Button</Button> <Button>Secondary Button</Button> </div> ); }; export default App;


In diesem Beispiel verfügt die Button Komponente über dynamische Stile, die sich je nach ihrer primary Requisite ändern.

BEM-Methodik

Wenn Sie nicht mit einem JavaScript-Framework arbeiten, das CSS-Module oder ähnliches unterstützt, können Sie Ihr CSS dennoch effektiv verwalten, indem Sie Benennungsmethoden wie BEM (Block, Element, Modifier) verwenden.


BEM steht für „Block Element Modifier“ und ist eine Methode, die Ihnen hilft, wiederverwendbare Komponenten und Code-Sharing in CSS zu erstellen. So können Sie Ihr CSS mit BEM strukturieren:


 /* Block */ .top-menu { } /* Element */ .top-menu__item { } /* Modifier */ .top-menu__item_active { }


In BEM ist der „Block“ die eigenständige Einheit, die für sich genommen eine Bedeutung hat, das „Element“ ist ein Teil des Blocks, der keine eigenständige Bedeutung hat und semantisch an seinen Block gebunden ist, und der „Modifikator“ ist ein aktiviertes Flag ein Block oder Element, das zum Ändern des Aussehens oder Verhaltens verwendet wird.


Die Verwendung einer konsistenten Methodik wie BEM kann Ihr CSS leichter verständlich und pflegeleicht machen, insbesondere bei größeren Projekten.

Abschließend

Es gibt verschiedene Möglichkeiten, CSS in größeren Projekten zu verwalten, von CSS-Modulen und CSS-in-JS-Bibliotheken bis hin zu Benennungsmethoden wie BEM. Der Schlüssel liegt darin, einen Ansatz zu finden, der gut zu Ihrem Team und Projekt passt, und ihn konsequent anzuwenden. Denken Sie daran, dass es beim Schreiben von CSS genauso darum geht, Code zu schreiben, der effizient und performant ist, wie auch darum, Code zu schreiben, der verständlich und wartbar ist.


Viel Spaß beim Codieren!