CSS scheitert in der Regel nicht sofort. Es scheitert ein Jahr später, wenn das System im realen Gebrauch ist und es sich riskant anfühlt, etwas zu ändern. Sie öffnen DevTools, springen durch die Regeln und versuchen zu verstehen, warum etwas so funktioniert, wie es ist. Bad CSS ist nicht nur hässlich, es ist teuer.Es ist der Grund, warum einfache UI-Updates drei Tage anstelle von drei Minuten dauern. Der Code macht . zu viel Zu viele Entscheidungen, die früh getroffen wurden, die zu schwierig und zu teuer sind, um sie zu widerrufen. Nicht durch Tricks oder Tools, sondern durch ein paar Gewohnheiten, die CSS einfach, lesbar und billig zu ändern, wie ein Projekt wächst. Das sind die Dinge, die ich gerne früher gelernt habe. 1. Mit CSS zu beginnen ist der erste Fehler Ich weiß, dass der Artikel über CSS geht, aber einer der häufigsten Fehler, die ich sehe, dass Junioren machen, ist, in eine Aufgabe zu springen und alles auf einmal zu bauen. In der Regel beginnen sie mit dem kompliziertesten Teil oder mit dem lustigsten Teil. CSS ist verlockend, weil es greifbar ist. Sie sehen sofort Ergebnisse. Der bessere Ansatz ist, CSS beiseite zu stellen, zu pausen, zu verlangsamen und mit dem Markup zu beginnen. Wenn Sie eine ganze App bauen, beginnen Sie mit der Seite Schale. Landmarks, Überschrifthierarchie, Hauptabschnitte. Arbeiten Sie zuerst daran. Lesen Sie die Seite beginnen, um zu beenden. Hat es Sinn? Wenn Sie an einer kleineren Funktion arbeiten, gilt dieselbe Idee. Legen Sie zuerst die Markup heraus und sehen Sie, wie sie in den Rest der App passt. Beginnend mit Markup zwingen Sie, über die Absicht zu denken, nicht das Aussehen. Nicht das, was sie Mit einem HTML-First-Ansatz definieren Sie Struktur, Bedeutung und Beschränkungen, die das System einfach und vorhersehbar halten. sind Sehen Sie wie CSS should adapt to that, not the other way around. Wenn Sie in das Styling eilen, neigen Sie dazu, die Markup um visuelle Hinweise zu formen. zusätzliche Verpackungen. Falsche Tags. In der Regel enden Sie mit Dingen, die gut, sind aber semantisch falsch oder unmöglich zu skalieren. Sehen Sie Wenn Sie zuerst das Markup durchführen, werden Sie in einer soliden Grundlage gesperrt. Zugänglichkeit, Dokumentbeschreibung, Tastaturfluss und Inhaltshierarchie werden hauptsächlich im Voraus gelöst. Es verlangsamt Sie auch auf gute Weise. Sie fangen Randfälle früh. Sie sehen, wo Dinge nicht gehören. Sie können einige Designentscheidungen zurückdrücken. HTML-First macht alles andere sinnvoll. 2. Wenn CSS mehr tut, als Sie denken Ein weiterer häufiger Fehler, den ich in Code-Bewertungen sehe, sind Junioren Oft ohne es zu merken.Lassen Sie mich Ihnen ein paar einfache Beispiele zeigen. zu viel Angenommen, Sie möchten die Inhaltsspalte horizontal zentrieren: .entry-content { max-inline-size: 48rem; margin: 0 auto; /* ❌ Avoid this! */ } Sie setzen eine maximale Breite und zentrieren das Element mithilfe von Auto-Margen. Was Sie jedoch möglicherweise nicht bemerken, ist, dass Sie auch die oberen und unteren Margen auf null setzen. Meistens wird die Abkürzung verwendet, nur weil sie kürzer ist. .entry-content { max-inline-size: 48rem; margin-inline: auto; /* ✅ Do this */ } Das gleiche Ergebnis. keine Nebenwirkungen. mehr Absicht. Ein weiteres gemeinsames Beispiel: .button--secondary { background: var(--color--dark-gray); } Dies setzt die Hintergrundfarbe mit der Benutzerdefinierte Eigenschaften. Aber es stellt auch eine Reihe anderer hintergrundbezogener Eigenschaften wieder her. --color--dark-gray Tatsächlich sehr viel: Hintergrundbild → Keine Hintergrundposition → 0% 0% Hintergrundgröße Auto Hintergrund - Wiederholung Hintergrund-Origin → padding-box Hintergrund-Clip → Border-Box Hintergrundattachment → Scroll Dies kann leicht zu ärgerlichen Nebenwirkungen führen, mit denen Sie sich später auseinandersetzen müssen. Was Sie wahrscheinlich stattdessen wollen, ist dies. .button--secondary { background-color: var(--color--dark-gray); } Die gleiche Idee wie zuvor. Aber chirurgisch. Ändern Sie nur, was Sie wirklich ändern wollen. Das gleiche Prinzip gilt für andere kurzfristige Eigenschaften, wie , der , der , der , und andere. Seien Sie vorsichtig, wenn Sie sie als Abkürzungen verwenden. oder vermeiden Sie die Verwendung von Abkürzungen ganz. border transform transition font Ein weiteres häufiges Beispiel für zu viel zu tun, ist zu früh zu spezifisch zu sein. a { text-decoration: none; background-image:linear-gradient(to right, currentColor, currentColor); background-position:0%100%; background-repeat: no-repeat; background-size:100%2px; transition: background-size 0.3s; &:hover, &:focus-visible { background-position:100%100%; } } Dieser Snippet fügt einen animierten Untergrund zu den Links hinzu. Das Problem ist, dass nicht jeder Tag ist ein Textlink. Bilder können Links sein. Profil-Avatare können Links sein. Schaltflächen werden oft als Anker markiert. <a> Plötzlich fügt dieser "intelligente" globale Stil seltsame 2px-Linien unter Ihr Logo hinzu oder bricht die Hintergrundgradienten auf Ihren primären Tasten. Jetzt werden Sie den Rest des Projekts damit verbringen, die Kaskade zu bekämpfen und "undo" -Style für jeden nicht-textbasierten Link zu schreiben, an dem Sie arbeiten. visual debt Sie können dies auf mehrere Arten lösen.Eine Option besteht darin, Textlinks innerhalb des Inhalts zu targeten. .entry-content:is(h1, h2, h3, h4, h5, h6, p, li) > a { /* styles here */ } Aber selbst dies kann immer noch zu eng oder zu breit sein, abhängig von der Markup. Meine Lieblingsmethode ist die Utility Class. .has-animated-underline { /* styles here */ } Wenn Sie dies in eine Klasse verschieben, machen Sie das Verhalten Es ist explizit, vorsätzlich und – was am wichtigsten ist – es erfordert nicht, dass Sie Dinge reparieren, die nicht am Anfang gebrochen waren. opt-in rather than opt-out 3. Wenn Mobile ein Afterthought ist Dennoch sehe ich immer noch Designer, die den größten Teil ihrer Zeit damit verbringen, auf Desktop-Comps zu arbeiten und die Arbeit des Desktop-First zu präsentieren, wobei mobile als eine einfache "Stapel" -Version des Desktops behandelt werden. Das fühlt sich immer noch rückwärts an. Ob wir es lieben oder nicht, wir erleben das Internet zuerst über ein Telefon. Das kann sich wieder ändern, aber es ist die Realität heute. Die Art und Weise, wie wir für das Web bauen, sollte dies widerspiegeln. In der Praxis ist es so, wie ich jetzt mit dem Styling umgehe: Legen Sie das Markup aus (über es gesprochen 😉). Ändern Sie die Größe des Browsers auf etwa 400px und gestalten Sie die App oder die Funktion so, als gäbe es keinen Desktop. Sobald es auf mobilen Geräten funktioniert, ändern Sie die Größe des Browsers auf den Desktop und machen Sie einen zweiten Pass auf die Stile. Wenn Sie auf diese Weise arbeiten, erhalten Sie natürlich 80% (eine zufällige Zahl, die sich richtig anfühlt), wenn es darum geht, Ihr Projekt zugänglich und für kleine Bildschirme bereit zu machen. Dies führt uns organisch zur Mobile-First-Implementierung. Als ich mit der Webentwicklung begann, waren Medienabfragen kaum eine Sache.Wir surfen nicht im Internet auf Handys. Dann kam das iPhone heraus, und Medienabfragen wurden zum Hauptwerkzeug für responsive Layouts.Die Anzahl der webfähigen Geräte war begrenzt, so dass Sie mit einer starren Reihe von Breakpoints wegkommen konnten: /* phones */ @media (max-width: 480px) {} /* large phones and small tablets */ @media (max-width: 767px) {} /* tablets */ @media (min-width: 768px) and (max-width: 1024px) {} /* desktop */ @media (min-width: 1025px) {} Bitte beachten Sie, dass dies nicht einmal Mobile-First ist. Der Ansatz . min-width Heute ist die Realität anders.Es gibt zu viele Geräte und Bildschirmgrößen zum Entwerfen für die Verwendung von Bruchpunkten allein.Es ist oft klüger, sich auf Tools zu verlassen, die sich auf die gesamte Palette natürlich anpassen. Zum Beispiel: intrinsische Layouts mit Grid oder Flexbox Fluidwerte mit clamp() für Schriftgrößen, Spaziergänge und Dimensionen Container Wünsche Medienabfragen sind immer noch nützlich, aber sie sollten nicht das erste Werkzeug sein, das Sie erreichen. Wenn ein Layout nur aufgrund von Breakpoints funktioniert, ist es wahrscheinlich zu steif.Wenn es ohne sie funktioniert, werden Medienabfragen zu kleinen, vorsätzlichen Anpassungen an der responsiven Struktur, nicht an der Grundlage. 4. Die Cascade bekämpfen statt sie zu benutzen Dies ist ein weiterer Bereich, in dem ich oft junge Ingenieure kämpfen sehe. Viele CSS-Frameworks und -Lösungen gibt es, um ein Hauptmerkmal zu lösen: die Kaskade. Und ich weiß, warum. Wenn Sie ohne viel Erfahrung in CSS springen, kann es chaotisch sein. Du schreibst eine Regel und es funktioniert nichts. Du schaltest sie an und plötzlich bricht etwas anderes. Darüber hinaus macht das Stylesheet des Benutzeragenten seine eigene Sache im Hintergrund. Das ist frustrierend, weil CSS nichts ist wie die meisten anderen Sprachen.In JavaScript können Sie ein Modul erstellen und nichts läuft heraus. Sie können CSS nicht auf die gleiche Weise nähern. Wenn Sie es versuchen, wird es Sie wirklich hart ins Gesicht beißen. Jede CSS-Änderung lebt in zwei Bereichen gleichzeitig: das, was Sie stylen, und der Rest des Systems, in das es fließt. Zurück zum vorherigen Beispiel, können Sie nicht nur dies schreiben: a { text-decoration: none; background-image:linear-gradient(to right, currentColor, currentColor); background-position:0%100%; background-repeat: no-repeat; background-size:100%2px; transition: background-size 0.3s; &:hover, &:focus-visible { background-position:100%100%; } } Wenn Sie dies tun, werden hintergrundbezogene Eigenschaften auf jeden Anker auf der Seite angewendet, auch wenn dieser Anker kein Textlink ist. Die meiste Zeit, das ist nicht das, was Sie wollen. Einige Ingenieure lernen dies auf die harte Art und Weise und reagieren, indem sie die Kaskade ganz vermeiden, wie zum Beispiel einen heißen Ofen als Kind berühren und lernen, es nie wieder zu tun. Ich denke, das ist ein Fehler, weil es zu viel Wiederholung führt. Hier ein Beispiel aus einem Projekt, an dem ich kürzlich gearbeitet habe. @define-mixin focus-state { &:focus-visible { outline: var(--outline--color) var(--outline--style) var(--outline--width); outline-offset: var(--outline--offset); } } Es wurde dann über mehrere Komponenten hinweg eingebunden: .button { @mixin focus-state; } a { @mixin focus-state; } .pagination-link { @mixin focus-state; } ...und so weiter. Ich kann mir keinen guten Grund dafür vorstellen.Focus-Outlines sollten in einem Projekt mit sehr wenigen Ausnahmen konsistent aussehen. In dieser Einstellung erzeugt jeder Mixin-Anruf immer wieder dasselbe CSS. Ein eleganterer Ansatz besteht darin, sich auf die Kaskade zu stützen und dies global zu definieren: :focus-visible { outline-color:var(--outline--color); outline-offset:var(--outline--offset); outline-style:var(--outline--style); outline-width:var(--outline--width); } Nun erhält jedes Element, das einen sichtbaren Fokuszustand erhält, standardmäßig denselben Styling. Und in den seltenen Fällen, in denen etwas anders sein muss, können Sie es lokal überschreiben: .pagination-link { --outline--offset: -2px; } Das ist es. einfach, kompakt und vorhersehbar. Das gleiche gilt für Dinge wie , der und Margin Resets, , und andere Stile, die sich in der gesamten App konsistent verhalten sollten. box-sizing ::selection text-wrap Ein schneller gut-check hilft hier. wenn ein stil sieht aus Gleiches gilt für jede Komponente, mit Ausnahmen, es gehört wahrscheinlich zu euren globalen Stilen. exactly very few Ignorieren Sie die Kaskade nicht. Nutzen Sie sie zu Ihrem Vorteil. 5. Spezifität ist, wo Dinge weiterhin auseinanderfallen Dies ist normalerweise der Grund hinter "Ich habe meine CSS geschrieben, aber es funktioniert nicht." Ich werde nicht tief in das gehen, was Spezifität ist.MDN bereits Was hier zählt, ist, dass hohe Spezifität eine der Hauptquellen für Schmerzen ist, wenn man mit Bibliotheken von Drittanbietern oder dem Code von jemand anderem arbeitet. tut das wirklich gut Nehmen wir dieses Beispiel: .layout > :not(.alignleft):not(.alignright):not(.alignfull):not(.alignwide) { max-width: var(--content-width); margin-left: auto; margin-right: auto; } Hier konzentrieren wir uns auf die unmittelbaren Kinder von horizontal und eine maximale Breite anwenden – alle Kinder außer , der , der und . .layout alignleft alignright alignfull alignwide Es gibt zwei Hauptgründe, warum dieser Code riecht. Zuerst ist dies ein Muster auf der Schwarzen Liste.Wir gestalten alles Das Problem ist, dass sich "alles" im Laufe der Zeit immer ändert. Wenn das Projekt wächst, werden Sie fast sicher mehr Ausnahmen hinzufügen. Eines Tages werden Sie vergessen, es hinzuzufügen, und etwas wird brechen. Außer Zweitens erhöht jeder Selektor, den Sie hinzufügen, die Spezifität. Das bedeutet, dass es einen noch stärkeren Selektor erfordert, , der oder alles in sich umwickeln Mit anderen Worten, Sie beheben Komplexität mit mehr Komplexität. 0.5.0 !important @layer :where() WordPress ist ein gutes Beispiel dafür, ohne CSS-Architektur zu beginnen und mit Chaos zu enden. body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)) { max-width: var(--wp--style--global--content-size); margin-left: auto !important; margin-right: auto !important; } Ich bekomme hier gemischte Signale.Wir haben uns mit der Muster, erkannte, dass es eine schlechte Idee war, erholt mit Und dann... angewendet Ich bin mir sicher, dass es einen Grund dafür gab, aber der Mensch ... ist das nicht so frustrierend. :not() :where() !important Sie können sicherlich all das tun... ...oder du kannst absichtlicher sein und dir etwas Frieden kaufen: /* 0.1.0 */ .layout > * { max-width: var(--content-width); margin-left: auto; margin-right: auto; } /* 0.2.0 */ .layout > .alignleft, .layout > .alignright { --content-width: var(--content-width--narrow); } /* 0.2.0 */ .layout > .alignwide { --content-width: var(--content-width--wide); } /* 0.2.0 */ .layout > .alignfull { --content-width: var(--content-width--full); } Dies ist einfacher zu lesen und einfacher zu argumentieren.Die Grundregel ist Die Ausnahmen sind . 0.1.0 0.2.0 Vorhersehbar und vorsätzlich. Hier ist ein weiterer gemeinsamer Weg, wie Spezifität ohne guten Grund wächst: /* ❌ combine element with a class ❌ element nested inside the block ❌ modifier nested inside the block */ a.button { &.button__label {...} &.button--secondary {...} } In diesem Beispiel: Wenn es keinen Grund gibt, a und .button zu kombinieren, tun Sie dies nicht. Wenn es keinen Grund gibt, .button__label unter .button zu hängen, tun Sie dies nicht. Gleiches gilt für Modifierklassen. Wenn Sie eine neue Komponente versenden, ist dies in der Regel das, was Sie stattdessen wollen: /* ✅ no element + class combination ✅ elements and modifiers stay flat */ .button {...} .button__icon {...} .button--primary {...} Hier ist die Daumenregel, die ich folge: Bevorzugen Sie standardmäßig einen einzelnen Klasse-Selektor. Verwenden Sie Utility-Variationen anstelle von Stapel-Selektoren. Die Quellordnung hilft Ihnen hier. Halten Sie die Spezifität bei 0,1.0 oder 0,1.1. Gehen Sie nicht über 0,2.0 in Funktionen, die Sie versenden. Vermeiden Sie #id-Selektoren und Inline-Stile im App-Code. Sie spiken Spezifität und sind schmerzhaft, um zu übertreffen. Verwenden Sie höhere Spezifität nur, wenn Sie Drittanbieter- oder veralteten Code überwiegen, den Sie noch nicht reproduzieren können. Notiz ist , der und :where() @layer @scope Ich bin mir dieser Tools voll bewusst. Sie können die Spezifität auf Null reduzieren Isolieren Sie Stile mit , und Scope Selectors mit . :where() @layer @scope Sie sind mächtig und haben ihren Platz, aber sie reparieren keine schlechte Architektur. Die gleichen Regeln der Spezifität gelten immer noch innerhalb jeder Schicht und innerhalb jedes Umfangs. Halten Sie die Spezifität niedrig. Ihr zukünftiges Selbst wird Ihnen danken.