In diesem Artikel tauchen wir in das Konzept von CSS-in-JS ein. Wenn Sie mit diesem Konzept bereits vertraut sind, werden Sie vielleicht trotzdem einen Spaziergang durch die Philosophie dieses Ansatzes genießen, und Sie werden vielleicht sogar noch mehr an dem nächsten Artikel interessiert sein.
Webentwicklung ist sehr interdisziplinär. Wir sind es gewohnt, eng mit mehreren Sprachen zusammenzuarbeiten. Und da die Entwicklung von Webanwendungen immer üblicher und nuancierter wird, suchen wir oft nach kreativen Wegen, um die Lücken zwischen diesen Sprachen zu überbrücken, um unsere Entwicklungsumgebungen und Arbeitsabläufe einfacher und effizienter zu gestalten.
Die häufigsten Beispiele sind typischerweise bei der Verwendung von Templating-Sprachen. Beispielsweise kann eine Sprache verwendet werden, um den Code einer umfangreicheren Sprache (oft HTML) zu generieren. Dies ist einer der Schlüsselaspekte von Front-End-Frameworks – wie sieht die Manipulation von HTML aus? Der jüngste Twist in diesem Bereich war JSX, weil es keine echte Templating-Sprache ist; es ist eine Syntaxerweiterung für JavaScript, und es macht die Arbeit mit HTML wirklich prägnant.
Webanwendungen durchlaufen viele Zustandsübergänge, und es ist oft schwierig, Inhalte allein zu verwalten. Deshalb fällt CSS manchmal durchs Raster – obwohl die Verwaltung von Stilen über verschiedene Zustände und Medienabfragen genauso wichtig und ebenso herausfordernd ist. In dieser zweiteiligen Serie möchte ich CSS ins Rampenlicht rücken und die Überbrückung der Lücke zwischen ihm und JavaScript untersuchen. Während dieser Serie gehe ich davon aus, dass Sie einen Modul-Bundler wie webpack verwenden. Daher werde ich in meinen Beispielen React verwenden, aber dieselben oder ähnliche Prinzipien sind auf andere JavaScript-Frameworks, einschließlich Vue, anwendbar.
Die CSS-Landschaft entwickelt sich in viele Richtungen, weil es viele Herausforderungen zu lösen gibt und es keinen „richtigen“ Weg gibt. Ich habe viel Mühe darauf verwendet, verschiedene Ansätze auszuprobieren, hauptsächlich in persönlichen Projekten, daher ist die Absicht hinter dieser Serie nur, zu **informieren**, nicht vorzuschreiben.
Herausforderungen von CSS
Bevor wir uns mit dem Code befassen, ist es erwähnenswert, die bemerkenswertesten Herausforderungen beim Stylen von Webanwendungen zu erläutern. Diejenigen, über die ich in dieser Serie sprechen werde, sind Scoping, bedingte und dynamische Stile sowie Wiederverwendbarkeit.
Scoping
Scoping ist eine bekannte CSS-Herausforderung, es ist die Idee, Stile zu schreiben, die nicht aus der Komponente herauslecken und somit unbeabsichtigte Nebenwirkungen vermeiden. Wir möchten dies idealerweise erreichen, ohne die Authoring-Erfahrung zu beeinträchtigen.
Bedingte und dynamische Stile
Während der Zustand in Front-End-Anwendungen immer fortschrittlicher wurde, war CSS immer noch statisch. Wir konnten nur Stile *bedingt* anwenden – wenn ein Button primär war, würden wir wahrscheinlich die Klasse „primary“ anwenden und seine Stile in einer separaten CSS-Datei definieren, um anzuwenden, wie er auf dem Bildschirm aussehen würde. Eine Handvoll vordefinierter Button-Variationen war überschaubar, aber was ist, wenn wir eine Vielzahl von Buttons haben möchten, wie z. B. spezielle für Twitter, Facebook, Pinterest und wer weiß was noch? Was wir wirklich tun wollen, ist einfach eine Farbe zu übergeben und Zustände mit CSS wie Hover, Fokus, deaktiviert usw. zu definieren. Dies nennt man *dynamisches* Styling, da wir nicht mehr zwischen vordefinierten Stilen wechseln – wir wissen nicht, was als Nächstes kommt. Inline-Stile könnten einem in den Sinn kommen, um dieses Problem zu lösen, aber sie unterstützen keine Pseudoklassen, Attributselektoren, Media Queries oder ähnliches.
Wiederverwendbarkeit
Die Wiederverwendung von Regelsätzen, Media Queries usw. ist ein Thema, das ich in letzter Zeit selten erwähnt sehe, da es von Präprozessoren wie Sass und Less gelöst wurde. Aber ich möchte es in dieser Serie immer noch aufgreifen.
Ich werde in beiden Teilen dieser Serie einige Techniken zur Bewältigung dieser Herausforderungen zusammen mit ihren Einschränkungen auflisten. Keine Technik ist den anderen überlegen und sie schließen sich nicht einmal gegenseitig aus; Sie können eine auswählen oder sie kombinieren, je nachdem, was Sie entscheiden, die Qualität Ihres Projekts verbessert.
Setup
Wir werden verschiedene Styling-Techniken anhand einer Beispielkomponente namens Photo demonstrieren. Wir werden ein responsives Bild rendern, das möglicherweise abgerundete Ecken hat und alternativen Text als Bildunterschrift anzeigt. Es wird wie folgt verwendet:
<Photo publicId="balloons" alt="Hot air balloons!" rounded />
Bevor wir die eigentliche Komponente erstellen, werden wir das Attribut srcSet abstrahieren, um den Beispielcode kurz zu halten. Erstellen wir also eine Datei utils.js mit zwei Hilfsprogrammen zur Generierung von Bildern unterschiedlicher Breite unter Verwendung von Cloudinary
Wir richten unsere Cloudinary-Instanz so ein, dass sie den Namen der Demo-Cloud von Cloudinary sowie ihre url-Methode verwendet, um URLs für die Bild-publicId gemäß den angegebenen Optionen zu generieren. Wir sind nur daran interessiert, die Breite in dieser Komponente zu ändern.
Wir werden diese Hilfsprogramme für die Attribute src bzw. srcset verwenden
Wenn Sie mit den Attributen srcset und sizes nicht vertraut sind, empfehle ich Ihnen, zuerst etwas über responsive Bilder zu lesen. Auf diese Weise wird es Ihnen leichter fallen, den Beispielen zu folgen.
CSS-in-JS
CSS-in-JS ist ein Styling-Ansatz, der das CSS-Modell auf die Komponentenebene abstrahiert, anstatt auf die Dokumentenebene. Die Idee ist, dass CSS auf eine bestimmte Komponente – und nur diese Komponente – so gescoped werden kann, dass diese spezifischen Stile nicht mit anderen Komponenten geteilt oder auf sie übertragen werden und weiter nur dann aufgerufen werden, wenn sie benötigt werden. CSS-in-JS-Bibliotheken erstellen Stile zur Laufzeit, indem sie <style>-Tags in den <head> einfügen.
Eine der ersten Bibliotheken, die dieses Konzept nutzte, ist JSS. Hier ist ein Beispiel, das seine Syntax verwendet
Auf den ersten Blick sieht das styles-Objekt wie CSS in Objektnotation mit zusätzlichen Funktionen aus, z. B. dem Übergeben einer Funktion, um den Wert basierend auf Props festzulegen. Die generierten Klassen sind eindeutig, sodass Sie sich nie Gedanken über Kollisionen mit anderen Stilen machen müssen. Mit anderen Worten, Sie erhalten Scoping kostenlos! So funktionieren die meisten CSS-in-JS-Bibliotheken – natürlich mit einigen Abweichungen bei Funktionen und Syntax, die wir im Laufe der Zeit behandeln werden.
Anhand der Attribute können Sie sehen, dass die Breite unseres gerenderten Bildes bei 200px beginnt, und wenn die Viewport-Breite mindestens 30rem beträgt, erhöht sich die Breite auf 400px. Wir haben zusätzliche 800 Quellen generiert, um auch höhere Bildschirmdichten abzudecken.
1x-Bildschirme verwenden 200 und 400
2x-Bildschirme verwenden 400 und 800
styled-components ist eine weitere CSS-in-JS-Bibliothek, aber mit einer viel vertrauteren Syntax, die clevere Tagged Template Literals anstelle von Objekten verwendet, um eher wie CSS auszusehen.
Wir erstellen oft semantisch neutrale Elemente wie <div> und <span> nur zu Styling-Zwecken. Diese Bibliothek und viele andere erlauben uns, diese in einem einzigen Schritt zu erstellen und zu stylen.
Mein liebster Vorteil dieser Syntax ist, dass sie wie normales CSS ist, abzüglich der Interpolationen. Das bedeutet, dass wir unseren CSS-Code leichter migrieren können und unsere vorhandene Muskelgedächtnis nutzen können, anstatt uns mit dem Schreiben von CSS in Objektnotation vertraut machen zu müssen.
Beachten Sie, dass wir fast alles in unsere Stile interpolieren können. Dieses spezielle Beispiel zeigt, wie wir die Media-Query in der Variable speichern und an mehreren Stellen wiederverwenden können. Responsive Bilder sind dafür ein hervorragendes Anwendungsbeispiel, da das sizes-Attribut im Grunde CSS enthält, sodass wir JavaScript verwenden können, um den Code DRYer zu machen.
Nehmen wir an, wir haben beschlossen, die Bildunterschrift visuell zu verstecken, sie aber dennoch für Screenreader zugänglich zu machen. Ich weiß, dass eine bessere Möglichkeit, dies zu erreichen, die Verwendung eines alt-Attributs wäre, aber lassen Sie uns zu diesem Beispiel einen anderen Weg gehen. Wir können eine Bibliothek von Style-Mixins namens polished verwenden – sie funktioniert hervorragend mit CSS-in-JS-Bibliotheken und ist daher großartig für unser Beispiel. Diese Bibliothek enthält einen Mixin namens hideVisually, der genau das tut, was wir wollen, und wir können ihn verwenden, indem wir seinen Rückgabewert interpolieren.
Auch wenn hideVisually ein Objekt ausgibt, weiß die styled-components-Bibliothek, wie sie es als Stile interpoliert.
CSS-in-JS-Bibliotheken verfügen über viele fortgeschrittene Funktionen wie Theming, Vendor-Prefixing und sogar das Inlining von kritischem CSS, was es einfach macht, auf das Schreiben von CSS-Dateien ganz zu verzichten. An diesem Punkt können Sie sehen, warum CSS-in-JS zu einem verlockenden Konzept wird.
Nachteile und Einschränkungen
Der offensichtliche Nachteil von CSS-in-JS ist, dass es eine Laufzeit einführt: Die Stile müssen über JavaScript geladen, analysiert und ausgeführt werden. Autoren von CSS-in-JS-Bibliotheken fügen alle möglichen intelligenten Optimierungen hinzu, wie z. B. Babel-Plugins, aber einige Laufzeitkosten werden trotzdem anfallen.
Es ist auch wichtig zu beachten, dass diese Bibliotheken nicht von PostCSS analysiert werden, da PostCSS nicht für die Laufzeit entwickelt wurde. Viele verwenden stattdessen stylis, da es viel schneller ist. Das bedeutet, dass wir leider keine PostCSS-Plugins verwenden können.
Der letzte Nachteil, den ich erwähnen werde, sind die Tools. CSS-in-JS entwickelt sich sehr schnell und Texteditor-Erweiterungen, Linter, Code-Formatierer usw. müssen mit neuen Funktionen Schritt halten, um auf dem neuesten Stand zu bleiben. Zum Beispiel verwenden Leute die VS Code-Erweiterung styled-components für ähnliche CSS-in-JS-Bibliotheken wie emotion, obwohl sie nicht alle dieselben Funktionen haben. Ich habe sogar API-Entscheidungen von vorgeschlagenen Funktionen gesehen, die von dem Ziel beeinflusst wurden, die Syntaxhervorhebung beizubehalten!
Die Zukunft
Es gibt zwei neue CSS-in-JS-Bibliotheken, Linaria und astroturf, die ohne Laufzeit auskommen, indem sie CSS in Dateien extrahieren. Ihre APIs sind ähnlich wie styled-components, aber sie unterscheiden sich in Funktionen und Zielen.
Das Ziel von Linaria ist es, die API von CSS-in-JS-Bibliotheken wie styled-components nachzuahmen, indem integrierte Funktionen wie Scoping, Nesting und Vendor-Prefixing vorhanden sind. Umgekehrt basiert astroturf auf CSS Modules, hat begrenzte Interpolationsmöglichkeiten und ermutigt zur Verwendung eines CSS-Ökosystems, anstatt auf JavaScript zurückzugreifen.
Ich habe Gatsby-Plugins für beide Bibliotheken erstellt, wenn Sie damit spielen möchten.
Zwei Dinge, die Sie bei der Verwendung dieser Bibliotheken beachten sollten
tatsächliche CSS-Dateien zu haben bedeutet, dass wir sie mit vertrauten Werkzeugen wie PostCSS verarbeiten können.
Linaria verwendet im Hintergrund benutzerdefinierte Eigenschaften (auch CSS-Variablen genannt). Berücksichtigen Sie unbedingt deren Browserunterstützung, bevor Sie diese Bibliothek verwenden.
Fazit
CSS-in-JS sind All-in-One-Styling-Lösungen zur Überbrückung der Lücke zwischen CSS und JavaScript. Sie sind einfach zu bedienen und enthalten nützliche integrierte Optimierungen – aber all das hat seinen Preis. Insbesondere durch die Verwendung von CSS-in-JS verlassen wir im Wesentlichen das CSS-Ökosystem und überlassen JavaScript die Lösung unserer Probleme.
Zero-Runtime-Lösungen mildern einige der Nachteile, indem sie die CSS-Werkzeuge zurückbringen, was die CSS-in-JS-Diskussion auf ein viel interessanteres Niveau hebt. Was sind die tatsächlichen Grenzen von Präprozessing-Tools im Vergleich zu CSS-in-JS? Dies wird im nächsten Teil dieser Serie behandelt.
At first glance, the styles object looks like CSS written in object notation with additional features, like passing a function to set the value based on props. The generated classes are unique, so you never need to worry about them clashing with other styles. In other words, you get scoping for free! This is how most CSS-in-JS libraries work — of course, with some twists in features and syntax that we’ll cover as we go.
You can see by the attributes that the width of our rendered image starts at 200px, then when the viewport width becomes at least 30rem, the width increases to 400px wide. We generated an extra 800 source to cover even larger screen densities:
1x screens will use 200 and 400
2x screens will use 400 and 800
styled-components is another CSS-in-JS library, but with a much more familiar syntax that cleverly uses tagged template literals instead of objects to look more like CSS:
We often create semantically-neutral elements like
and solely for styling purposes. This library, and many others, allow us to create and style them in a single motion.
My favorite benefit of this syntax is that it’s like regular CSS, minus interpolations. This means that we can migrate our CSS code more easily and we get to use our existing muscle memory instead of having to familiarize ourselves with writing CSS in the object syntax.
Notice that we can interpolate almost anything into our styles. This specific example demonstrates how we can save the media query in the variable and reuse it in multiple places. Responsive images are an excellent use case for this because the sizes attribute contains basically CSS, so we can use JavaScript to make the code more DRY.
Let’s say that we decided we want to visually hide the caption, but still make it accessible for screen readers. I know that a better way of achieving this would be to use an alt attribute instead, but let’s use a different way for the sake of this example. We can use a library of style mixins called polished — it works great with CSS-in-JS libraries making it great for our example. This library includes a mixin called hideVisually which does exactly what we want and we can use it by interpolating its return value:
Even though hideVisually outputs an object, the styled-components library knows how to interpolate it as styles.
CSS-in-JS libraries have many advanced features like theming, vendor prefixing and even inlining critical CSS, which makes it easy to stop writing CSS files entirely. At this point, you can start to see why CSS-in-JS becomes an enticing concept.
Downsides and limitations
The obvious downside to CSS-in-JS is that it introduces a runtime: the styles need to be loaded, parsed and executed via JavaScript. Authors of CSS-in-JS libraries are adding all kinds of smart optimizations, like Babel plugins, but some runtime costs will nevertheless exist.
It’s also important to note that these libraries aren’t being parsed by PostCSS because PostCSS wasn’t designed to be brought into the runtime. Many use stylis instead as a result because it’s much faster. This means that we unfortunately can’t use PostCSS plugins.
The last downside I’ll mention is the tooling. CSS-in-JS is evolving at a really fast rate and text editor extension, linters, code-formatters etc. need to play catch-up with new features to stay on par. For example, people are using the VS Code extension styled-components for similar CSS-in-JS libraries like emotion, even though they don’t all have the same features. I’ve even seen API choices of proposed features being influenced by the goal of retaining syntax highlighting!
The future
There are two new CSS-in-JS libraries, Linaria and astroturf, that have managed zero runtime by extracting CSS into files. Their APIs are similar to styled-components, but they vary in features and goals.
The goal of Linaria is to mimic the API of CSS-in-JS libraries like styled-components by having built-in features like scoping, nesting and vendor prefixing. Conversely, astroturf is built upon CSS Modules, has limited interpolation capabilities, and encourages using a CSS ecosystem instead of deferring to JavaScript.
I built Gatsby plugins for both libraries if you want to play with them:
Two things to have in mind when using these libraries:
having actual CSS files means that we can process them with familiar tools like PostCSS
Linaria uses custom properties (a.k.a. CSS variables) under the hood, be sure to take their browser support into consideration before using this library
Conclusion
CSS-in-JS are all-in-one styling solutions for bridging the gap between CSS and JavaScript. They are easy to use and they contain useful built-in optimizations — but all of that comes at a cost. Most notably, by using CSS-in-JS, we’re essentially ejecting from the CSS ecosystem and deferring to JavaScript to solve our problems.
Zero-runtime solutions mitigate some of the downsides by bringing back the CSS tools, which ascends the CSS-in-JS discussion to a much more interesting level. What are the actual limitations of preprocessing tools compared to CSS-in-JS? This will be covered in the next part of this series.
Wenn Sie ein Meta-Tag wie folgt verwenden: http-equiv=”Content-Security-Policy” content=”default-src ‘self'” um XSS-Angriffe zu verhindern, wird das Einfügen von Inline-Stilen dadurch nicht verhindert, wenn Sie dieses System verwenden? Umgekehrt schaffen Sie nicht eine Schwachstelle, indem Sie Inline-Stile einfügen?
Danke für die Antwort, Matija. Als Beispiel wird dieses Meta-Tag: auf dieser Seite verwendet: http://www.nown.org.au/ um XSS-Angriffe – die Einschleusung von bösartigem Code – zu vermeiden. Die Details/Gründe finden Sie unter diesem Link: https://developers.google.com/web/fundamentals/security/csp/ Die Content Security Policy auf diese Weise zu verwenden, verhindert meines Wissens, dass ein Browser Code verwendet, der nicht vom Server stammt, auf dem das HTML gespeichert ist. Als Konsequenz erkennt oder führt der Browser jedoch keinen Inline-JS-Code (z. B. onclick=”myFunction()”) und auch keine Inline-CSS (z. B. style =”color:black;”) aus. Und Style-Tags im Head-Bereich sind ebenfalls unwirksam; sie funktionieren überhaupt nicht. Ihr gesamtes JS und CSS (und JQuery) muss aus separaten Dateien stammen, die auf demselben Server wie die Seite gespeichert sind; d. h. „self“. Meine Frage war also: Ist die Einschleusung von z. B. Style-Tags durch CSS-inJS mit der Verwendung einer strengen Content-Security-Policy wie „self“ vereinbar? Wenn ja, schafft das eine Schwachstelle? Oder habe ich das sowieso alles falsch verstanden?
Entschuldigung für die späte Antwort, ich habe dies in meinem Posteingang behalten, da ich es mir ansehen wollte. Tatsächlich verhindert es das Einfügen von Stilen, ich habe es gerade ausprobiert! Es scheint, dass man es mit Nonce umgehen kann. Ich weiß nicht, wie groß dieses Problem ist, da Sicherheit nicht meine Stärke ist. Aber styled-components hat Informationen dazu.
Ich bin tief gegen CSS-in-JS, hauptsächlich wegen der Trennung von Belangen. Die Probleme, die CSS-in-JS zu lösen versucht, sind größtenteils auf mangelndes Wissen und Erfahrung mit CSS von Seiten der Entwickler zurückzuführen. Ein Stil „leckt“ nicht. Das C in CSS steht für „Cascading“ (Kaskadierend), das bedeutet, dass der gesamte Geist von CSS darin besteht, nach unten zu „lecken“. Es ist ein Merkmal, keine Schwäche, man muss nur lernen, wie man es benutzt. Es gibt Techniken, Methoden dafür, und sie skalieren perfekt.
Ein Symbol dafür? Ihr Import von „hideVisually“. Sie importieren ein JS-Objekt, das dazu dient, eine vorgefertigte Klasse in Ihre Komponente einzufügen und sie vom Rest der Seite zu isolieren. Glauben Sie nicht, dass dies der genaue Verwendungszweck von CSS wäre? Diese Klasse als Standard-CSS-Klasse für die gesamte Seite verfügbar zu haben, die auf den Komponenten aufgerufen wird, die sie benötigen? Sie wäre geteilt, keine Verarbeitungszeit, nur plain old CSS.
Die genauen Vorteile von CSS-in-JS werden besser anderswo im Web veranschaulicht, sie würden nicht in einen Artikel passen. Dies ist eher ein Überblick und eine Vorbereitung für den 2. Teil.
Beide Teile dieser Serie sind eng miteinander verbunden, Ihnen könnte der 2. Teil besser gefallen. ;)
Wenn also die Entwicklung von CSS in JS darin besteht, es zur Kompilierzeit zu extrahieren (und ich stimme zu), warum nicht einfach SASS verwenden? Kombiniert mit CSS Modules auf Komponentenebene erhalten Sie alles, was Sie von CSS in JS erhalten, aber ohne den ganzen zusätzlichen Boilerplate/Syntax, Performance-Overhead und eine Million Implementierungen. Sie haben auch ein erstklassiges Kaskadensystem zur Verfügung, wenn Sie es brauchen, denn nun ja… Sie entwerfen ein Theme, das ein einzigartiges Branding für etwas bieten soll.
Ich bin mir sicher, das klingt mürrisch (und ja, ich habe die Memes von cleveren Hipstern gesehen), aber von all den Front-End-Änderungen begeistern mich die meisten, aber hier fühle ich mich frustriert bis zu dem Punkt, dass ich manchmal frage, wie lange ich mich weiterhin mit Front-End-Entwicklung beschäftigen möchte. Ich hasse es absolut, in ein Projekt mit CSS in JS einzusteigen. Es verwandelt Komponenten in Spaghetti, die ohne Trennung von Belangen oder die Möglichkeit, 20 Jahre Community-CSS schnell zu iterieren und wiederzuverwenden, viel schwerer zu durchschauen sind. Ganz zu schweigen von all den verschiedenen Architekturen davon. Es verlangsamt mich enorm und macht keinen Spaß. Und ich bin ein Full-Stack-Entwickler, der guten Code liebt.
Das Hauptproblem ist, dass CSS Modules spät zur Party kamen, viele Leute es aber nicht bemerkten. CSS Modules bewies, dass das Argument bezüglich der Kapselung unehrlich ist und keinen Platz mehr als Argument haben sollte. SASS, LESS, haben alles, was Sie in Bezug auf Flexibilität brauchen. Vieles von dem, was sie tun, ist zur Laufzeit unnötig. Mit CSS in JS liefern Sie sowohl viel zusätzlichen Ballast als auch mehr Verarbeitung als mit einfachen Metadaten für Stile.
Ich fühle Ihre Frustration. Als Styling-Enthusiast suchte ich verzweifelt nach Best Practices, und so sehr ich die Flexibilität von CSS-in-JS genoss, konnte ich nicht Schritt halten. Das brachte mich zum 2. Teil dieser Serie, ich empfehle Ihnen, ihn sich anzusehen. ;)
Ernsthafte Frage: Was ist der Anwendungsfall für CSS-in-JS gegenüber dem einfachen Austauschen einer oder zwei Klassen oder der Verwendung eines Build-Tools, um dasselbe zu erreichen? Vielleicht sind die Apps, an denen ich arbeite, nicht groß genug, um einen Vorteil zu sehen, aber ich bin einfach nicht überzeugt, dass dies eine gute Idee ist.
Ich bin ein etwas altmodischer Entwickler. Ich erinnere mich an Tage, an denen wir harte Kämpfe hatten, um HTML, CSS und JS zu trennen, und es war ein großer Sieg in der Webentwicklung, als die Leute begannen, HTML, JS und CSS getrennt zu speichern. Heutzutage ist die neue Generation von Webentwicklern auf der Bühne erschienen und alles ist wieder da, wo wir vor etwa 15 Jahren angefangen haben. Entschuldigen Sie, aber für mich ist die Idee von CSS-in-JS inakzeptabel. Ich habe bereits gesehen, wohin das führen kann.
CSS-in-JS könnte für viele Leute sehr hilfreich sein. Und einige Implementierungen könnten einwandfrei funktionieren… WENN und nur WENN sie auf intelligente Weise implementiert sind. Die Art und Weise, wie CSS-in-JS implementiert wird, insbesondere wie sie hier oben beschrieben wird, wo Sie Werte aus „props“ (als JS-Variablen) einfügen können, könnte ein direkter Angriff auf die Leistung des Render-Zyklus unserer geliebten Browser sein!
Das liegt daran, dass leider nicht alle Entwickler die inneren Abläufe des Browsers kennen. Die meisten werden sich nach dem Lesen dieses Artikels nicht einmal mehr an die genannten Nachteile erinnern. Bis also eine Standardisierung (wie das W3C) eine geeignete Lösung gefunden hat, befürworten Sie bitte nicht die Verwendung von CSS-in-JS. Dieser Artikel hat das Potenzial, „das Internet“ schlechter statt besser zu machen. Denken Sie an die Zufriedenheit der Benutzer, nicht an die Zufriedenheit der Entwickler!
Es gibt viele Dinge zu bedenken. Beispielsweise macht das Inlining von kritischem CSS auch die Benutzer glücklich, aber es ist schwer zu tun, daher tun es viele Entwickler nicht. CSS-in-JS liefert es Ihnen kostenlos. :)
Beachten Sie, dass Autoren von CSS-in-JS-Bibliotheken diese optimiert haben, bis hin zur vollständigen Entfernung der Laufzeit! Es ist wichtig zu untersuchen, woraus CSS-in-JS tatsächlich kompiliert wird.
Matija Marohnić, Sie können die Laufzeit nicht vollständig eliminieren, das würde das Ganze wieder auf plain old CSS zurückführen. Es *gibt* einen Performance-Treffer bei CSS-in-JS, der immer vorhanden sein wird.
Ashley, die meisten CSS-in-JS-Bibliotheken haben eine Laufzeit, ja, aber astroturf und Linaria haben keine, darauf habe ich mich bezogen. Überzeugen Sie sich selbst, sie kompilieren zu tatsächlichen CSS-Dateien. Ob das eine gute Idee ist, überlasse ich Ihnen. ;)
Ich versuche wirklich, den Punkt zu verstehen, aber ich denke immer: Wenn man weiß, was man mit CSS macht, ist CSS-„Leaking“ nie ein Problem. Das einzige Problem, das ich jemals mit Leaking hatte, sind Bibliotheken mit schlechtem CSS. Ich entferne diese Stile einfach und schreibe sie schnell neu, damit sie zum Projekt passen.
Wenn Ihnen das ganze Kaskadending wirklich nicht gefällt, warum verwenden Sie dann keine IDs? React besteht aus Modulen, geben Sie diesem Modul eine ID und stylen Sie von dort – voilà. Stile werden niemals lecken. Ich halte das für schlechte Praxis, aber es ist im Wesentlichen dasselbe wie die Modularisierung Ihres CSS? Was macht Modularisierung dann auch zu schlechter Praxis? Sie wollen immer noch (einige) globale Stile, oder?
Ich bin immer noch verwirrt über die Vorteile, die CSS-in-JS liefern sollte. Ich denke immer, dass mir der Punkt entgeht, und ich würde es wirklich gerne verstehen.
Die Vorteile gehen weit über die Modularisierung hinaus, dieser Twitter-Thread könnte helfen. Persönlich suche ich nach Alternativen, also schauen Sie sich den 2. Teil dieser Serie an. ;)
CSS innerhalb von JS-Komponenten wird immer beliebter, weil die Traditionalisten aus dem FED-Spiel gedrängt werden, da reine JS-Programmierer sie überholen, nicht weil es eine bessere Idee ist…was es nicht ist.
Es fühlt sich wie ein FAD und eine schlechte Idee an…weil es das ist.
CSS in JavaScript ist eine schreckliche Idee! Eine der wahren Stärken von Cascading Style Sheets ist das Cascading, dessen Macht die meisten modernen Entwickler nicht verstehen. Leute denken heute nicht mehr an CSS als "Haut" und HTML als "Gerüst". Die Trennung der Belange ermöglicht es den Entwicklern auch, parallel zu arbeiten, einer am Gerüst und der andere an der Haut. Erinnert sich jemand an http://www.csszengarden.com? Zeigt die wahre Macht von CSS! (Ich könnte einen ganzen Artikel zu diesem Thema schreiben, was ich vielleicht tun werde ;)
Ich habe CSS-in-JS nur einmal mit styled components verwendet, es war eine furchtbare frustrierende Erfahrung, viel komplizierter, aber mit weniger Wiederverwendbarkeit als die Verwendung von reinem alten Stylesheets. Wir haben 3 Bibliotheken verwendet, um eine kompliziertere Lösung zu erreichen, als nur CSS zu verwenden, es schien mir sehr überkonstruiert und widerspricht den alten Prinzipien der Trennung von Belangen.
Ich stimme anderen hier zu, der Grund, warum CSS in JS vorangetrieben wird, ist, dass viele Entwickler nicht lernen wollen, wie man CSS richtig macht, was bedauerlich ist, denn gutes CSS in Kombination mit anständigem HTML kann die elegantesten und einfachsten Lösungen mit dem geringsten Code erzeugen. Es scheint, dass die Entwicklererfahrung wichtiger wird als die Benutzererfahrung, d. h. Dinge werden zum Vorteil des Entwicklers und nicht des Benutzers getan.
Trotzdem schätze ich, ich rede gegen eine Wand.
Dieser Kommentarbereich ist geschlossen. Wenn Sie wichtige Informationen teilen möchten, kontaktieren Sie uns bitte.
Wenn Sie ein Meta-Tag wie folgt verwenden: http-equiv=”Content-Security-Policy” content=”default-src ‘self'” um XSS-Angriffe zu verhindern, wird das Einfügen von Inline-Stilen dadurch nicht verhindert, wenn Sie dieses System verwenden? Umgekehrt schaffen Sie nicht eine Schwachstelle, indem Sie Inline-Stile einfügen?
Interessant, erzählen Sie mir mehr! Beispiel? Außerdem injiziert CSS-in-JS keine Inline-Stile, meinten Sie
style-Tags?Danke für die Antwort, Matija. Als Beispiel wird dieses Meta-Tag: auf dieser Seite verwendet: http://www.nown.org.au/ um XSS-Angriffe – die Einschleusung von bösartigem Code – zu vermeiden. Die Details/Gründe finden Sie unter diesem Link: https://developers.google.com/web/fundamentals/security/csp/
Die Content Security Policy auf diese Weise zu verwenden, verhindert meines Wissens, dass ein Browser Code verwendet, der nicht vom Server stammt, auf dem das HTML gespeichert ist.
Als Konsequenz erkennt oder führt der Browser jedoch keinen Inline-JS-Code (z. B. onclick=”myFunction()”) und auch keine Inline-CSS (z. B. style =”color:black;”) aus. Und Style-Tags im Head-Bereich sind ebenfalls unwirksam; sie funktionieren überhaupt nicht.
Ihr gesamtes JS und CSS (und JQuery) muss aus separaten Dateien stammen, die auf demselben Server wie die Seite gespeichert sind; d. h. „self“.
Meine Frage war also: Ist die Einschleusung von z. B. Style-Tags durch CSS-inJS mit der Verwendung einer strengen Content-Security-Policy wie „self“ vereinbar?
Wenn ja, schafft das eine Schwachstelle?
Oder habe ich das sowieso alles falsch verstanden?
Entschuldigung für die späte Antwort, ich habe dies in meinem Posteingang behalten, da ich es mir ansehen wollte. Tatsächlich verhindert es das Einfügen von Stilen, ich habe es gerade ausprobiert! Es scheint, dass man es mit Nonce umgehen kann. Ich weiß nicht, wie groß dieses Problem ist, da Sicherheit nicht meine Stärke ist. Aber styled-components hat Informationen dazu.
Ich bin tief gegen CSS-in-JS, hauptsächlich wegen der Trennung von Belangen.
Die Probleme, die CSS-in-JS zu lösen versucht, sind größtenteils auf mangelndes Wissen und Erfahrung mit CSS von Seiten der Entwickler zurückzuführen. Ein Stil „leckt“ nicht. Das C in CSS steht für „Cascading“ (Kaskadierend), das bedeutet, dass der gesamte Geist von CSS darin besteht, nach unten zu „lecken“. Es ist ein Merkmal, keine Schwäche, man muss nur lernen, wie man es benutzt. Es gibt Techniken, Methoden dafür, und sie skalieren perfekt.
Ein Symbol dafür? Ihr Import von „hideVisually“. Sie importieren ein JS-Objekt, das dazu dient, eine vorgefertigte Klasse in Ihre Komponente einzufügen und sie vom Rest der Seite zu isolieren. Glauben Sie nicht, dass dies der genaue Verwendungszweck von CSS wäre? Diese Klasse als Standard-CSS-Klasse für die gesamte Seite verfügbar zu haben, die auf den Komponenten aufgerufen wird, die sie benötigen? Sie wäre geteilt, keine Verarbeitungszeit, nur plain old CSS.
Die genauen Vorteile von CSS-in-JS werden besser anderswo im Web veranschaulicht, sie würden nicht in einen Artikel passen. Dies ist eher ein Überblick und eine Vorbereitung für den 2. Teil.
Beide Teile dieser Serie sind eng miteinander verbunden, Ihnen könnte der 2. Teil besser gefallen. ;)
Wenn also die Entwicklung von CSS in JS darin besteht, es zur Kompilierzeit zu extrahieren (und ich stimme zu), warum nicht einfach SASS verwenden? Kombiniert mit CSS Modules auf Komponentenebene erhalten Sie alles, was Sie von CSS in JS erhalten, aber ohne den ganzen zusätzlichen Boilerplate/Syntax, Performance-Overhead und eine Million Implementierungen. Sie haben auch ein erstklassiges Kaskadensystem zur Verfügung, wenn Sie es brauchen, denn nun ja… Sie entwerfen ein Theme, das ein einzigartiges Branding für etwas bieten soll.
Ich bin mir sicher, das klingt mürrisch (und ja, ich habe die Memes von cleveren Hipstern gesehen), aber von all den Front-End-Änderungen begeistern mich die meisten, aber hier fühle ich mich frustriert bis zu dem Punkt, dass ich manchmal frage, wie lange ich mich weiterhin mit Front-End-Entwicklung beschäftigen möchte. Ich hasse es absolut, in ein Projekt mit CSS in JS einzusteigen. Es verwandelt Komponenten in Spaghetti, die ohne Trennung von Belangen oder die Möglichkeit, 20 Jahre Community-CSS schnell zu iterieren und wiederzuverwenden, viel schwerer zu durchschauen sind. Ganz zu schweigen von all den verschiedenen Architekturen davon. Es verlangsamt mich enorm und macht keinen Spaß. Und ich bin ein Full-Stack-Entwickler, der guten Code liebt.
Das Hauptproblem ist, dass CSS Modules spät zur Party kamen, viele Leute es aber nicht bemerkten. CSS Modules bewies, dass das Argument bezüglich der Kapselung unehrlich ist und keinen Platz mehr als Argument haben sollte. SASS, LESS, haben alles, was Sie in Bezug auf Flexibilität brauchen. Vieles von dem, was sie tun, ist zur Laufzeit unnötig. Mit CSS in JS liefern Sie sowohl viel zusätzlichen Ballast als auch mehr Verarbeitung als mit einfachen Metadaten für Stile.
Ich fühle Ihre Frustration. Als Styling-Enthusiast suchte ich verzweifelt nach Best Practices, und so sehr ich die Flexibilität von CSS-in-JS genoss, konnte ich nicht Schritt halten. Das brachte mich zum 2. Teil dieser Serie, ich empfehle Ihnen, ihn sich anzusehen. ;)
Ernsthafte Frage: Was ist der Anwendungsfall für CSS-in-JS gegenüber dem einfachen Austauschen einer oder zwei Klassen oder der Verwendung eines Build-Tools, um dasselbe zu erreichen? Vielleicht sind die Apps, an denen ich arbeite, nicht groß genug, um einen Vorteil zu sehen, aber ich bin einfach nicht überzeugt, dass dies eine gute Idee ist.
Dieser Twitter-Thread könnte hilfreich sein.
Ich bin ein etwas altmodischer Entwickler. Ich erinnere mich an Tage, an denen wir harte Kämpfe hatten, um HTML, CSS und JS zu trennen, und es war ein großer Sieg in der Webentwicklung, als die Leute begannen, HTML, JS und CSS getrennt zu speichern. Heutzutage ist die neue Generation von Webentwicklern auf der Bühne erschienen und alles ist wieder da, wo wir vor etwa 15 Jahren angefangen haben. Entschuldigen Sie, aber für mich ist die Idee von CSS-in-JS inakzeptabel. Ich habe bereits gesehen, wohin das führen kann.
CSS-in-JS ist nur ein Ansatz, der 2. Teil dieser Serie bietet einen modernen Ansatz für das altehrwürdige CSS. ;)
CSS-in-JS könnte für viele Leute sehr hilfreich sein. Und einige Implementierungen könnten einwandfrei funktionieren… WENN und nur WENN sie auf intelligente Weise implementiert sind.
Die Art und Weise, wie CSS-in-JS implementiert wird, insbesondere wie sie hier oben beschrieben wird, wo Sie Werte aus „props“ (als JS-Variablen) einfügen können, könnte ein direkter Angriff auf die Leistung des Render-Zyklus unserer geliebten Browser sein!
Das liegt daran, dass leider nicht alle Entwickler die inneren Abläufe des Browsers kennen. Die meisten werden sich nach dem Lesen dieses Artikels nicht einmal mehr an die genannten Nachteile erinnern. Bis also eine Standardisierung (wie das W3C) eine geeignete Lösung gefunden hat, befürworten Sie bitte nicht die Verwendung von CSS-in-JS.
Dieser Artikel hat das Potenzial, „das Internet“ schlechter statt besser zu machen.
Denken Sie an die Zufriedenheit der Benutzer, nicht an die Zufriedenheit der Entwickler!
Es gibt viele Dinge zu bedenken. Beispielsweise macht das Inlining von kritischem CSS auch die Benutzer glücklich, aber es ist schwer zu tun, daher tun es viele Entwickler nicht. CSS-in-JS liefert es Ihnen kostenlos. :)
Beachten Sie, dass Autoren von CSS-in-JS-Bibliotheken diese optimiert haben, bis hin zur vollständigen Entfernung der Laufzeit! Es ist wichtig zu untersuchen, woraus CSS-in-JS tatsächlich kompiliert wird.
Matija Marohnić, Sie können die Laufzeit nicht vollständig eliminieren, das würde das Ganze wieder auf plain old CSS zurückführen. Es *gibt* einen Performance-Treffer bei CSS-in-JS, der immer vorhanden sein wird.
Ashley, die meisten CSS-in-JS-Bibliotheken haben eine Laufzeit, ja, aber astroturf und Linaria haben keine, darauf habe ich mich bezogen. Überzeugen Sie sich selbst, sie kompilieren zu tatsächlichen CSS-Dateien. Ob das eine gute Idee ist, überlasse ich Ihnen. ;)
Ich versuche wirklich, den Punkt zu verstehen, aber ich denke immer: Wenn man weiß, was man mit CSS macht, ist CSS-„Leaking“ nie ein Problem. Das einzige Problem, das ich jemals mit Leaking hatte, sind Bibliotheken mit schlechtem CSS. Ich entferne diese Stile einfach und schreibe sie schnell neu, damit sie zum Projekt passen.
Wenn Ihnen das ganze Kaskadending wirklich nicht gefällt, warum verwenden Sie dann keine IDs? React besteht aus Modulen, geben Sie diesem Modul eine ID und stylen Sie von dort – voilà. Stile werden niemals lecken. Ich halte das für schlechte Praxis, aber es ist im Wesentlichen dasselbe wie die Modularisierung Ihres CSS? Was macht Modularisierung dann auch zu schlechter Praxis? Sie wollen immer noch (einige) globale Stile, oder?
Ich bin immer noch verwirrt über die Vorteile, die CSS-in-JS liefern sollte. Ich denke immer, dass mir der Punkt entgeht, und ich würde es wirklich gerne verstehen.
Die Vorteile gehen weit über die Modularisierung hinaus, dieser Twitter-Thread könnte helfen. Persönlich suche ich nach Alternativen, also schauen Sie sich den 2. Teil dieser Serie an. ;)
CSS innerhalb von JS-Komponenten wird immer beliebter, weil die Traditionalisten aus dem FED-Spiel gedrängt werden, da reine JS-Programmierer sie überholen, nicht weil es eine bessere Idee ist…was es nicht ist.
Es fühlt sich wie ein FAD und eine schlechte Idee an…weil es das ist.
CSS in JavaScript ist eine schreckliche Idee! Eine der wahren Stärken von Cascading Style Sheets ist das Cascading, dessen Macht die meisten modernen Entwickler nicht verstehen. Leute denken heute nicht mehr an CSS als "Haut" und HTML als "Gerüst". Die Trennung der Belange ermöglicht es den Entwicklern auch, parallel zu arbeiten, einer am Gerüst und der andere an der Haut. Erinnert sich jemand an http://www.csszengarden.com? Zeigt die wahre Macht von CSS! (Ich könnte einen ganzen Artikel zu diesem Thema schreiben, was ich vielleicht tun werde ;)
Ich habe CSS-in-JS nur einmal mit styled components verwendet, es war eine furchtbare frustrierende Erfahrung, viel komplizierter, aber mit weniger Wiederverwendbarkeit als die Verwendung von reinem alten Stylesheets. Wir haben 3 Bibliotheken verwendet, um eine kompliziertere Lösung zu erreichen, als nur CSS zu verwenden, es schien mir sehr überkonstruiert und widerspricht den alten Prinzipien der Trennung von Belangen.
Ich stimme anderen hier zu, der Grund, warum CSS in JS vorangetrieben wird, ist, dass viele Entwickler nicht lernen wollen, wie man CSS richtig macht, was bedauerlich ist, denn gutes CSS in Kombination mit anständigem HTML kann die elegantesten und einfachsten Lösungen mit dem geringsten Code erzeugen. Es scheint, dass die Entwicklererfahrung wichtiger wird als die Benutzererfahrung, d. h. Dinge werden zum Vorteil des Entwicklers und nicht des Benutzers getan.
Trotzdem schätze ich, ich rede gegen eine Wand.