Robin Weser’s „The Shorthand-Longhand Problem in Atomic CSS“ ist eine interessante Reise durch ein kniffliges Problem. Der Punkt ist, dass, wenn man die Aufgabe übernimmt, etwas HTML- und CSS-ähnliches in tatsächliches HTML und CSS zu konvertieren, es Randfälle gibt, aus denen man sich selbst herausprogrammieren muss, wenn man es überhaupt kann. In diesem Fall wandelt Fela (das wir gerade erwähnt haben) CSS in „atomare“ Klassen um, aber wenn man Kurz- und Langschreibweisen mischt, können die resultierenden Klassen, vermischt mit der Kaskade, Fehler verursachen.
Ich finde diese ganze Idee von CSS-in-JS, das atomares CSS erzeugt, ziemlich interessant, also lassen Sie uns kurz einen Schritt zurücktreten und das betrachten.
Atomares CSS bedeutet eine Klasse = eine Aufgabe
So wie das
.mb-8 {
margin-bottom: 2rem;
}
Stellen Sie sich jetzt vor, wie es davon Tausende gibt, die verfügbar sind und fast alles tun können, was CSS kann.
Warum sollte man das tun?
Hier sind einige Gründe
- Wenn Sie diese Idee voll und ganz verfolgen, bedeutet das, dass Sie weniger CSS ausliefern, da es keine wiederholten Eigenschaft/Wert-Paare gibt und keine erfundene Klassennamen für Autorenzwecke. Ich würde schätzen, dass ein rein atomares Stylesheet (bereinigt für die Nutzung, worauf wir noch eingehen werden) ein Viertel der Größe eines handgeschriebenen Stylesheets oder kleiner ist. Weniger CSS auszuliefern ist signifikant, da CSS eine blockierende Ressource ist.
- Sie vermeiden es, Dinge zu benennen.
- Sie erhalten einen gewissen Grad an Designkonsistenz „kostenlos“, wenn Sie die verfügbaren Klassen einschränken.
- Manche Leute bevorzugen es einfach und sagen, es mache sie schneller.
Wie erhält man atomares CSS?
Nichts hindert Sie daran, es selbst zu tun. Das hat GitHub mit Primer und Facebook in FB5 gemacht (nicht dass Sie tun sollten, was Megakonzerne tun!). Sie entschieden sich für eine Reihe von Utility-Stilen und lieferten diese (weitgehend für sich selbst) als Paket aus.
Vielleicht war der Urheber der ganzen Idee Tachyons, das ist einfach ein großer, meinungsstarker Haufen von Klassen, die man einfach so übernehmen kann.
Aber größtenteils...
Tailwind ist der große Akteur.
Tailwind hat eine Reihe von netten Standardeinstellungen, aber es macht einige sehr clevere Dinge über eine Sammlung von atomaren Stilen hinaus.
- Es ist konfigurierbar. Sie sagen ihm, was all diese Klassen tun sollen.
- Es ermutigt Sie, die ungenutzten Klassen zu „purgen“. Sie müssen diesen Teil wirklich richtig machen, da Sie nicht wirklich den Vorteil von atomarem CSS erhalten, wenn Sie es nicht tun.
- Es hat eine UI-Bibliothek, damit Sie sofort loslegen können.
Waren wir nicht bei automatisch generiertem atomarem CSS?
Oh richtig.
Es ist erwähnenswert, dass Yahoo auch ein früher Mitspieler war. Ihre große Idee ist, dass Sie im Wesentlichen Funktionen als Klassennamen verwenden würden (z. B. class="P(20px)") und dies während eines Build-Schritts in eine Klasse (sowohl im HTML als auch im CSS) verarbeitet würde. Ich bin mir nicht sicher, wie populär das wirklich wurde, aber Sie können sehen, wie es sich nicht wesentlich von Tailwind + PurgeCSS unterscheidet.
Heutzutage müssen Sie atomares CSS nicht schreiben, um atomares CSS zu erhalten. Aus Robins Artikel
Es ermöglicht uns, unsere Stile auf eine vertraute „monolithische“ Weise zu schreiben, aber atomares CSS zu erhalten. Dies erhöht die Wiederverwendbarkeit und verringert die Größe des endgültigen CSS-Bundles. Jedes Eigenschaft-Wert-Paar wird nur einmal gerendert, nämlich bei seinem ersten Auftreten. Von da an können wir jedes Mal, wenn wir dieses bestimmte Paar wieder verwenden, denselben Klassennamen aus einem Cache wiederverwenden. Einige Bibliotheken, die das tun, sind
• Fela
• Styletron
• React Native Web
• Otion
• StyleSheetMeiner ehrlichen Meinung nach ist dies der einzig vernünftige Weg, atomares CSS tatsächlich zu nutzen, da es die Entwicklererfahrung beim Schreiben von Stilen nicht beeinträchtigt. Ich würde *nicht* empfehlen, atomares CSS von Hand zu schreiben.
Johan Holmerin schrieb hier auf CSS-Tricks auch über style9, das dasselbe tut.
Das finde ich raffiniert. Ich habe mehrmals versucht, atomares CSS direkt zu schreiben, und es gefällt mir einfach nicht. Wer weiß warum. Ich habe im Leben viele neue Dinge gelernt, und dieses hier passt einfach nicht zu mir. Aber ich mag definitiv die Idee, dass Computer alles tun, was sie tun müssen, um die Web-Performance in der Produktion zu steigern. Wenn ein Build-Schritt mein bearbeitetes CSS in atomares CSS umwandelt… hey, das ist cool. Es gibt fünf Bibliotheken oben, die das tun, also hat das Konzept definitiv Bestand.
Es macht Sinn, dass die Ansätze auf CSS-in-JS basieren, da sie sowohl das Markup als auch das CSS verarbeiten müssen – das ist also der Kontext, der am meisten Sinn ergibt.
Was denkt ihr?
In twind, einem Tailwind in JS Laufzeit, hatten wir dasselbe Problem. Um die CSS-Regel in einer deterministischen Reihenfolge einzufügen, berechnen wir eine Präzedenzzahl für jede CSS-Regel, die die Position im Stylesheet bestimmt (aufsteigend; z. B. niedrigere Zahlen zuerst). Die Idee stammt von otion und wir haben sie für Tailwind angepasst. Wir verwenden im Grunde die folgenden Regeln (einige Tailwind-spezifische Regeln habe ich weggelassen)
Dunkelmodus – um Hellmodus-Stile zu überschreiben
Media Queries – werden in einem Mobile-First-Ansatz nach dem
min-width-Wert sortiertandere at-Regeln – wie
prefers-reduced-motionPseudo-Klassen – sorgen für die richtige Reihenfolge; zum Beispiel überschreibt
activefocusundhover(siehe Wann gelten die Pseudo-Klassen :hover, :focus und :active?Anzahl der Deklarationen (absteigend) – dies ermöglicht es Einzeldeklarationsstilen, Mehrfachdeklarationsstile zu überschreiben
größte Präzedenz von Eigenschaften (ignoriert Vendor-Präfixe und benutzerdefinierte Eigenschaften) – Kurzschreibweise-Eigenschaften werden zuerst eingefügt, z. B. überschreiben Langschreibweise-Eigenschaften Kurzschreibweisen
Ich benutze derzeit Tailwind, Vuetify und Bulma. Ich habe Schwierigkeiten, den Mehrwert zu verstehen. Wie Stil = „Hintergrund: rot“ sich von Klasse = „rot“ unterscheidet. Ich finde, HTML wird wirklich überladen.
Wir machen das auch und es fühlt sich ziemlich gut an.
Ich stimme keiner Ihrer Begründungen zu, warum atomares CSS lohnenswert ist. Gehen wir sie einzeln durch
Sicher, Sie haben weniger CSS, aber Sie haben Hunderte/Tausende mehr Klassen in Ihrem HTML, was ebenfalls blockierend ist, also verlagern Sie die Last nur von einer Ressource auf eine andere.
Wenn Sie eine der Bibliotheken verwenden, dann ja. Aber das wäre auch bei traditionellen Präsentationsbibliotheken (Bootstrap / Foundation) der Fall. Sobald Sie sie erweitern wollen, müssen Sie wahrscheinlich mehr Dinge benennen als zuvor (wenn auch mit einfacheren Namen).
Theoretisch ja, da es eine Klasse für jeden CSS-Eigenschaftstyp gibt. Aber es gibt eine höhere Wahrscheinlichkeit, dass ein Entwickler einen Haufen inkonsistenter Klassen auf ein HTML-Element setzt? Die Inkonsistenz wird wieder einfach auf das HTML verschoben.
Nun, dem können wir nichts entgegensetzen.
Letztendlich sollten wir das verwenden, womit wir uns wohlfühlen (auch wenn wir uns durch wiederholte Nutzung wohlfühlen), was großartige Arbeit leistet (obwohl dies davon abhängt, wie gut wir das Werkzeug nutzen) und was praktikabel ist (abhängig von Budget/Umständen).
Wiederholte Wörter, wie Klassennamen, komprimieren sich gut, also ist es kein Problem.
Ja, manchmal möchten Sie eine „Komponente“ erstellen, d. h. einen wiederverwendbaren Satz von Stilen, aber wie Sie geschickt vorhergesagt haben, werden Sie wahrscheinlich weniger Probleme haben, sie zu benennen.
Ich denke, das Wort „Konsistenz“ bezieht sich auf Dinge wie Skalierung von Abständen, Farben usw. Beim Schreiben von CSS gibt es nichts, was Sie daran hindert, diese Regeln zu brechen, außer Code-Reviewern und bis zu einem gewissen Grad Linter-Tools. Im Utility-First-CSS ist dies nicht möglich, daher würde ich sagen, dass eine stärkere Konsistenz inhärent ist.
Utility-First-CSS sieht am Anfang definitiv schrecklich aus, daher erfordert es etwas emotionale Investition. Chris mochte es nicht, ich schon, weil ich keine Kombination von CSS-Best Practices erreichen konnte, die für mich funktionierte, daher hat Tailwinds Ansatz bei mir Anklang gefunden. Andere hassen es weiterhin, es kommt ganz auf die Motivation an.
Mein größtes Problem mit Tailwind ist, wenn ich anfange, ein HTML-Teil zu dekorieren, 15 Klassen hinzufüge, es dupliziere und dann etwas irgendwo in dieser langen Zeile (oder Liste) von Klassenattributen ändern muss.
Es ist einfach schwer zu verstehen.
Das macht die Lesbarkeit nicht einfacher, wenn viele Elemente so viele Klassen haben.
Und klar, man kann diese Liste von Klassennamen nehmen und eine eindeutige Klasse erstellen, und ich glaube, dieser Ansatz gefällt mir am besten, aber dann bin ich zu sehr an Bootstrap und ihre Sass-Utility-Klassen gewöhnt und mache es eben so.
Am Ende kann ich sehen, warum es ansprechend ist und die Leute es zu genießen scheinen.
In twind haben wir Gruppierung eingeführt, um die Größe der Klassenliste zu reduzieren. Ihr Beispiel könnte so geschrieben werden:
Zusätzlich unterstützen wir Aliase für diese Komponenten-ähnlichen Klassen.
Das, was mir nie Sinn gemacht hat, ist, dass es bei atomarem CSS praktisch immer mehr Arbeit kostet, kleine visuelle Änderungen vorzunehmen, da man einfach immer wieder dieselbe konzeptionelle Menge an Stilen repliziert. Anstatt also an einer Stelle zu sagen, wie jede (z. B.) Karte aussehen soll und dann von dort aus zu spezialisieren, sucht man stattdessen nach jeder Instanz von etwas, das wie eine Karte aussehen soll. Und das ist noch gar nicht zu reden davon, wie viel größer die Bundle-Größen bei atomarem CSS sind (aufgrund der Zunahme von HTML und CSS). Ehrlich gesagt scheint der einzige Vorteil darin zu liegen, dass es die Erstemwicklung erleichtert, was für Mockups in Ordnung ist… Aber warum dann nicht einfach Inline-Stile verwenden? Ehrlich gesagt nutze ich gerne eine Vielzahl von CSS-Lösungen, von gesperrtem CSS über Styled Components bis hin zu semantischem CSS… Und alle außer atomarem CSS erscheinen ziemlich sinnvoll.
Ich denke, atomares CSS eignet sich für komponentenbasiere Frameworks wie Vue, React oder Svelte. Ich benutze immer Tailwind in React- oder Svelte-Projekten, so mächtig, keine Wiederholungen, alle Stile werden von der Komponente wiederverwendet. Aber für natives HTML ist natives CSS meiner Meinung nach besser.
Ich arbeite an Compiled, einer Build-Zeit-atomaren CSS-in-JS-Bibliothek hier: https://github.com/atlassian-labs/compiled
Sie zielt darauf ab, Funktionsgleichheit mit anderen Bibliotheken zu haben und kann vollständig in ein statisches atomares Stylesheet extrahiert werden. Außerdem behält sie die DX von heute bei. Sie werden nicht einmal merken, dass es als atomares CSS ausgegeben wird!
Interessanterweise gibt es Vorteile von atomarem CSS neben Wiederverwendung und Konsistenz.
Es hat uns ermöglicht, Style-Komposition zu implementieren, die zur Laufzeit mit Build-Zeit-Stilen funktioniert.
Es ist super mächtig und ermöglicht wirklich ein größeres Ökosystempotential, da Sie Pakete an NPM versenden können und Stile immer noch resilient überschreiben können, ohne sich um die Kaskade kümmern zu müssen. Es funktioniert einfach.
Ich bin sehr gespannt, was als nächstes kommt!
Das Wichtigste, was in diesem Artikel fehlt (und was viele Kommentatoren ärgert), ist das Konzept der Extraktion von Komponenten. TailwindCSS erklärt das hier gut: https://tailwindcss.com/docs/extracting-components
Das ist meiner Meinung nach einer der größten Vorteile von Tailwind. Die Möglichkeit, immer noch Methodologien wie BEM zu verwenden, aber trotzdem einige der Vorteile eines atomaren Systems beizubehalten. Sie können Ihren eigenen „Best of both worlds“-Ansatz entwickeln.
Ich habe gerade angefangen, mich regelmäßig mit Tailwind zu beschäftigen und es in 11ty, Preact und WP-Vorlagen zu verwenden. Bisher gefällt mir die Flexibilität.
Wahre Geschichte
Vor 15 Jahren, als ich gerade als Entwickler anfing, entwickelte sich mein CSS in diese Richtung. Ich hatte w25 für
width: 25%und w50 fürwidth: 50%und zehn oder fünfzehn weitere für Breite, Höhe, Ränder, Abstände…Nach einigen Monaten erkannte ich, wie dumm ich war, HTML für mein CSS zu schreiben, anstatt umgekehrt. Ich hörte auf, begann echtes CSS zu schreiben und habe nie zurückgeblickt.
Jetzt, 10-15 Jahre später, sitze ich auf meiner Veranda und sehe, wie die jungen Leute dieselben dummen Fehler machen, die ich damals gemacht habe.
Nur dass die meisten den Fehler anscheinend nicht erkennen und es so lassen, wie ich es damals getan habe.
Das ist traurig.
Das war eine interessante Lektüre, ich kannte die Double-Selector-Lösung noch nicht.
Ich habe einen ziemlich ähnlichen, aber allgemeineren Beitrag über Atomic CSS-in-JS geschrieben
https://sebastienlorber.com/atomic-css-in-js
Diese Technik wurde auf der neuen Facebook-Website verwendet und das CSS ist jetzt viel kleiner, da es linear skaliert.
Vorgefertigte statische Seiten können sehr minimales Inline-CSS enthalten und schneller laden, auch wenn das HTML zunimmt.
Ein Problem bleibt für mich, da es auch den JSX-Code größer macht, was zu mehr JS-Code für das Framework-Hydration führt. Ich bin mir nicht sicher, wie das gelöst wird.
Was ist der Unterschied zwischen atomarem CSS und Inline-Stilen? Eine Abstraktionsebene, die in 99 % der Fälle nie als Abstraktion verwendet wird?
Das Styling in etwas Cachbareres verschieben.
Die FAQ auf acss.io beantwortet diese Frage.
Wie unterscheidet sich Atomic CSS von der Verwendung von Inline-Stilen?
Hallo Chris,
Sie sagen (über ACSS)
Bei diesem Artikel über „automatisch generiertes atomares CSS“ bin ich überrascht, dass Sie den enormen Vorteil von dynamischen Bibliotheken gegenüber statischen nicht erwähnen: Sie können jede beliebige Stilart erzeugen, die Autoren benötigen oder wünschen. Mit anderen Worten, Autoren müssen nicht aus einer endlichen Liste von Stilen in einem Stylesheet wählen, sie können Stile auf Knopfdruck erstellen!
Genau der Punkt, den die meisten Leute verpassen!
Ich hatte Schwierigkeiten, Tailwind/PurgeCSS dazu zu bringen, ungenutzte Stile basierend auf dem DIST-Ordner meiner statischen Website zu entfernen. Ich möchte atomare Klassen im Authoring verwenden können, sie bauen und dann die atomaren Klassen entfernen, die nicht verwendet werden, basierend auf dem, was meine Content-Autoren tatsächlich verwenden. Hat jemand schon einen Weg gefunden, das zu tun?
Was denke ich? Ich denke, die gesamte „atomare CSS“-Bewegung ist sehr fehlgeleitet und idiotisch. Als Benutzer, haben Sie jemals versucht, Elemente einer Seite, die atomares CSS verwendet, anzupassen (oder zu reparieren) – das können Sie nicht.
Im Grunde ist es nur eine faule Aufgabe der Verantwortung, die Seitenelemente zu gestalten und sie gut zu benennen.