html {
font-family: Roboto, sans-serif;
}
Mit Ausnahme einiger Formular-Elemente haben Sie gerade eine Schriftart für jeden Text auf einer Website festgelegt! Gut gemacht! Wahrscheinlich war das, was Sie beabsichtigt hatten, denn bei wahrscheinlich Hunderten von Elementen auf Ihrer gesamten Website wäre es mühsam und fehleranfällig, jedes Mal diese font-family festzulegen.
CSS ist von Natur aus global. Mit Absicht!
Ich mag, wie David Khourshid es formuliert hat
Haben Sie jemals darüber nachgedacht, *warum* CSS einen globalen Geltungsbereich hat? Vielleicht möchten wir konsistente Typografie, Farben, Größen, Abstände, Layouts, Übergänge usw. verwenden und möchten, dass unsere Websites und Apps wie eine zusammenhängende Einheit wirken?
Liebe die Kaskade, die Kaskade ist dein Freund.
Und doch. Die globale Natur von CSS ist vielleicht die am häufigsten kritisierte „Nicht-Funktion“ von CSS. Manche Leute mögen es wirklich nicht. Wir alle wissen, wie einfach es ist, eine einzelne CSS-Regel zu schreiben, die Auswirkungen auf der gesamten Website hat und Dinge bricht, die man wirklich nicht brechen wollte.
Zwei CSS-Eigenschaften gehen in eine Bar.
Ein Barhocker in einer völlig anderen Bar fällt um.
— Thomas Fuchs 🎄🕹💾 (@thomasfuchs) 28. Juli 2014
Es gibt ganz neue Kategorien von Tests, die bei diesen Problemen helfen.
Geltungsbereiche-definierte Stile sind nicht der *einzige* Grund für das große Interesse und die Akzeptanz von CSS-in-JS, aber sie sind ein wichtiger Faktor. Es gibt viele Websites, die gar keine CSS-Dateien direkt authorn – nicht einmal vorverarbeitete Stile – und stattdessen eine JavaScript-Bibliothek verwenden, bei der Stile buchstäblich in JavaScript geschrieben werden. Es gibt ein interaktives Beispiel, das die Syntax der verschiedenen Optionen demonstriert. Hier ist, wie styled-components funktioniert.
import React from 'react';
import styled from 'styled-components';
const Container = styled.main`
display: flex;
flex-direction: column;
min-height: 100%;
width: 100%;
background-color: #f6f9fc;
`;
export default function Login() {
return (
<Container>
... Some stuff ....
</Container>
);
}
Es gibt buchstäblich Dutzende von Optionen, die jeweils Dinge ein wenig anders handhaben und leicht unterschiedliche Syntaxen und Funktionen bieten. Vue bietet sogar Scoped CSS direkt in .vue-Dateien an.
<style scoped>
.example {
color: red;
}
</style>
<template>
<div class="example">hi</div>
</template>
Leider hat <style scoped> nie ganz als native Webplattformfunktion Fuß gefasst. Es gibt jedoch Shadow DOM, wo ein Stilblock in eine Vorlage eingefügt werden kann und diese Stile vom Rest der Seite isoliert werden.
let myElement = document.querySelector('.my-element');
let shadow = myElement.attachShadow({
mode: 'closed'
});
shadow.innerHTML = `
<style>
p {
color: red;
}
</style>
<p>Element with Shadow DOM</p>
`;
Keine Stile werden diese Shadow DOM-Grenze durchdringen oder daraus austreten. Das ist ziemlich cool für Leute, die diese Art von Isolation suchen, aber es könnte knifflig sein. Sie müssten das CSS wahrscheinlich so gestalten, dass es bestimmte globale Stile hat, die mit der mit Shadow DOM versehenen Webkomponente importiert werden können, damit sie eine gewisse Styling-Kohäsion auf Ihrer Website erzielen. Persönlich wünschte ich mir, es wäre möglich, das Shadow DOM Einweg-durchlässig zu machen: Stile können hineingelangen, aber Stile, die darin definiert sind, können nicht hinausgelangen.
CSS-in-JS-Dinge sind nur eine Möglichkeit, Stile zu isolieren. Es gibt tatsächlich zwei Seiten des Spektrums. Man könnte CSS-in-JS als totale Isolation bezeichnen, während man CSS direkt mit totaler Abstraktion authorn könnte.
Totale Abstraktion könnte von einem Projekt wie Tachyons kommen, das Ihnen eine feste Menge von Klassennamen zum Stylen gibt (Tailwind ist wie eine konfigurierbare Version davon), oder ein programmatisches Werkzeug (wie Atomizer), das speziell benannte HTML-Klassenattribute in ein Stylesheet mit genau dem umwandelt, was es benötigt.
Selbst die vollständige Einhaltung von BEM über Ihre gesamte Website hinweg könnte als totale CSS-Isolation betrachtet werden und die Probleme lösen, die der globale Geltungsbereich mit sich bringen kann.
Persönlich würde ich gerne sehen, dass wir uns in diese Zukunft bewegen.
Wenn wir Stile schreiben, werden wir immer eine Wahl treffen. Sind das globale Stile? Lecke ich absichtlich diesen Stil über die gesamte Website? Oder schreibe ich CSS, das spezifisch für diese Komponente ist? CSS wird zwischen diesen beiden geteilt. Komponentenspezifische Stile werden gekapselt und mit der Komponente gebündelt und bei Bedarf verwendet.
Das Beste aus beiden Welten, sozusagen.
Wie auch immer, es ist knifflig.
Das Problem ist nicht CSS in JS.
Es ist der globale Geltungsbereich von CSS.
Lösen Sie den globalen Geltungsbereich, und CSS in JS wird folgen.
(Ich weiß nicht, ob „folgen“ bedeutet verschwinden, vollständig akzeptiert werden oder eine große Überarbeitung erfahren.)
(Was das angeht, weiß ich nicht, was „den globalen Geltungsbereich lösen“ bedeutet.)
— ppk 🇪🇺 (@ppk) 28. November 2018
Vielleicht wird dies 2019 das heißeste CSS-Thema sein.
Ein weiser Mann sagte mir einst, nachdem ich mich darüber beschwert hatte, dass CSS Dinge beeinträchtigte, die ich nicht wollte: „Das Problem ist nicht das CSS, das Problem ist, dass Sie schlecht in CSS sind.“ Er hatte Recht. Ich kann keine CSS-Probleme finden, die nicht durch sorgfältige Benennung und Abstraktion gelöst werden können.
Haben Sie ein Problem mit dem globalen Geltungsbereich von CSS? Dann wenden Sie einen nicht-globalen Geltungsbereich an,duh. Möchten Sie nur Schriftarten in Tabellen beeinflussen? Verwenden Sie den Selektor ‚table‘. Möchten Sie nur die Höhe von Tabellenüberschriften und nicht die Zeilen von Tabellenkörpern beeinflussen? ‚table>thead>tr‘. Möchten Sie die Größe einzelner Divs kontrollieren, ohne alle Divs und die Divs in Ihren Divs zu beeinflussen? Verwenden Sie Klassen.
Jeder, der sich über den globalen Geltungsbereich von CSS beschwert, tut dies nur, weil er nicht weiß, was er tut…
Genau das. Ich muss etwas verpassen, weil ich nicht verstehe, worum der ganze Aufwand geht. Vererbung, Leute. Es gibt sogar einen praktischen * Selektor.
Ja. Ich habe mich einmal mit einem bekannten Twitter-Nutzer gestritten, der behauptete, „die Kaskade sei der kaputte Teil von CSS“. Ich frage mich immer noch, was er mit dem „C“ in CSS meint.
In dem Moment, in dem Sie denken, CSS-in-JS sei die Lösung für ein Problem, habe ich schlechte Nachrichten für Sie. Die Frontend-Community sollte aufhören, alles zu überkomplizieren und nach Lösungen in Tools/JavaScript für Probleme zu suchen, die nicht existieren.
CSS-in-JS ist eines der dümmsten Dinge, die ich in den letzten Jahren gesehen habe. Das Problem ist nicht CSS, das Problem liegt zwischen Monitor und Stuhl!
Ich finde, es lohnt sich, die letzten drei Kommentare oben anzuschauen und zu sehen, wie extrem abweisend und flüchtig Menschen dieser Idee gegenüber sein können. Das ist für mich so merkwürdig. Ich habe kein einziges Projekt, das CSS-in-JS verwendet, aber das hindert mich nicht daran, Leuten zuzuhören, warum sie diesen Ansatz mögen. Aus dem Stegreif...
Wie gesagt, meine Perspektive ist begrenzt, da ich keine CSS-in-JS-Bibliotheken auf den von mir bearbeiteten Websites aktiv nutze, aber ich kann die möglichen Vorteile trotzdem verstehen. Warum der Hass? Ist es eine Art Gebietsverteidigung?
Zu Chris
Sie haben Recht, dass es keine Rechtfertigung für Hass gibt und dass dies wirklich zum neuen Religionskrieg des Webs geworden ist (ich glaube, Sie haben einen ganzen Artikel über Dogmatismus geschrieben ;)).
Dennoch gibt es zwei Gründe, warum CSS-Leute wegen CSS-in-JS panisch werden
1) CSS ist extrem mächtig und ermöglicht es, sehr elegant über große Teile von Dingen auf einmal zu sprechen. Manche Leute plädieren für CSS-in-JS einfach, weil sie diese Macht nicht kontrollieren wollen oder weil die Syntax vertrauter ist.
2) CSS ist rein deklarativ. Dies ist eine seiner größten Stärken; es gibt keinen Zustand, was es im großen Maßstab weitaus weniger fragil macht, wenn man weiß, wie man es einsetzt. Turing-vollständige Sprachen haben viel mehr, das in ihnen schiefgehen kann, daher ist die Fähigkeit, einen beträchtlichen Teil der Attribute Ihrer Anwendung zu beschreiben, ohne eine zu haben, ein großer Vorteil.
Zusätzlich könnten einige der (echten) Vorteile, nach denen Leute in CSS-in-JS suchen, zu CSS selbst hinzugefügt werden. Zum Beispiel reine Funktionen. Wir haben jetzt zumindest grundlegende Ausdrücke mit calc(), aber ich sehe keinen Grund, zustandslose Funktionen nicht in die Sprache selbst einzuführen. Es wird auch immer Fälle geben, in denen Sie Daten von JS übergeben müssen, aber CSS-benutzerdefinierte Eigenschaften haben es viel einfacher gemacht, von Ihrem JS-Code aus „feuern und vergessen“.
Wenn genügend Leute für CSS-in-JS plädieren, verlagert sich die aktive Innovation dorthin und wird von CSS selbst weggezogen, was schade ist. Es ist immer noch kein Grund, unfreundlich zu seinen Mitentwicklern zu sein, aber ich denke, das ist der Grund, warum Präferenz zu Abwehrhaltung wird.
In jeder Sprache/Umgebung, in der ich je entwickelt habe, gab es immer einen erheblichen Anteil von Entwicklern, die entweder die einfache Lösung, die in der Sprache/Umgebung integriert ist, nicht lernen, oder sie finden sie nicht „herausfordernd“ genug, sodass sie sie neu erfinden, indem sie ein von ihnen bevorzugtes Paradigma verwenden (normalerweise eines, das sie aus einer völlig anderen Sprache/Umgebung mitbringen). Und ich denke, das ist großartig – die Leute, die tatsächlich neu erfinden, lernen enorm viel dabei. Sie sind jedoch oft diejenigen, die ihre Ergebnisse veröffentlichen möchten, und oft folgen riesige Teile der Entwicklungsgemeinschaft ihnen wie Lemminge in Richtung wachsender Komplexität.
Ich denke, das Problem ist, dass einfache Lösungen oft ziemlich lange dauern, um sie zu finden und zu lernen, wie man sie verfeinert, während jeder mit genügend Zeit einfach etwas aufbauen kann, das den Bedarf erfüllt, aber nicht so robust und wartbar ist. Und das Webentwicklungs-Ökosystem ist heutzutage voller Leute, die nie das Gefühl haben, genug Zeit zu haben, etwas auf dieses Niveau zu lernen. Sobald Sie sich in einem „Geschmacksmonat“ wohlfühlen, laufen Ihre Fähigkeiten Gefahr, hoffnungslos veraltet zu sein, da sein Kopf abgehackt wird und es durch 5 neue Frameworks/Bibliotheken ersetzt wird, von denen jede komplexer zu lernen ist als die letzte. Leseempfehlung: Ape and Essence von Aldous Huxley
Absolut Ihrer Meinung.
Ich stimme Chris vollkommen zu. Es macht Sinn für mich, einige globale Stile und einige isolierte zu haben.
Ich war schon immer jemand, der sich mit CSS auskennt und hatte nie *wirklich* Probleme mit der globalen Natur von CSS. Ich benutze normalerweise ECSS (da ich früher mit Ben Frain gearbeitet habe) und es hat mir einfach geholfen. Aber… und vielleicht ist das Ben's Meinungsverschiedenheit, ich habe vielleicht auch einige globale Klassennamen, die einem anderen Namensstandard entsprechen, damit sie von isolierten Komponenten-Klassennamen unterschieden werden können. Ich erstelle diese normalerweise, um Textelemente zu stylen.
Es ist alles ziemlich einfach. Ich weiß nicht, was der ganze Aufwand ist.
Ich bin kein aktiver Nutzer von CSS-in-JS-Bibliotheken auf meinen Websites, aber ich glaube trotzdem, dass dies uns Vorteile bringen wird. Dies könnte die Lösung für viele Probleme sein.
Ich habe es schon einmal gesagt und werde es wiederholen
CSS hat keinen globalen Geltungsbereich.
Zu sagen, CSS-Regeln hätten einen globalen Geltungsbereich, ist so, als würde man ein ganzes Programm in einer einzigen Funktion schreiben und sich dann darüber beschweren, dass alle Variablen darin „global“ sind. Wenn Ihr CSS global ist, liegt das daran, dass Sie sich weigern, die Werkzeuge zu verwenden, die Ihnen die Sprache zur Verfügung stellt. Jeder „Scoped CSS“-Vorschlag ist nur ein redundanter Meta-Mechanismus darauf.
Wenn Sie denken, der „globale Geltungsbereich“ von CSS sei ein Problem, verstehen Sie CSS einfach nicht sehr gut. Was kein Problem ist, lassen Sie einfach jemanden, der CSS versteht, es machen. Versuchen Sie nicht, „Lösungen“ für ein Problem zu finden, das nicht existiert, und machen Sie CSS viel komplizierter, als es sein muss.
CSS in JS ist für Entwickler, die kein CSS lernen wollen und sich sicherlich nicht mit Webdesign-Geschichte auskennen. Wir hatten diesen All-in-One-Dateien-Brei bereits in den 90ern. Es gibt einen Grund, warum Trennung der Belange ein so wichtiges Konzept ist.
Das Niveau der Herablassung in den Kommentaren ist frustrierend. Diese Haltung, die Leute an den Tag legen, ist anstrengend.
Als Webentwickler mit über 20 Jahren Erfahrung habe ich fast jedes Werkzeug und jede Technik im Zusammenhang mit CSS verwendet. Ich hatte eine Liste von Dingen, bei denen ich in meinen Überlegungen zu CSS und JS in den letzten Jahrzehnten falsch lag. Es ist wichtig, seine Voreingenommenheit zu überprüfen.
Was ich in den Kommentaren sehe, ist ein Gefühl des Elitismus; das „Treten Sie zur Seite, Anfänger, und lassen Sie einen Profi es Ihnen zeigen“. Der Erfolg des Webs liegt in seiner Zugänglichkeit für alle. HTML, CSS und JS werden weithin genutzt, gerade weil sie einfach zu autorisieren sind, auch wenn sie nicht unbedingt einfach zu meistern sind. Wenn man anfängt, Leuten zu sagen, dass sie CSS jemandem überlassen sollten, der es bereits versteht, dann lenkt man viele Leute ab, die die nächste Generation von Experten werden könnten.
In einem Unternehmen müssen Sie ein Gleichgewicht finden. Sie werden Autoren haben, die CSS-Experten sind, und Sie werden solche haben, die es nicht sind; Praktikanten, Zeitarbeitskräfte, Geschäftsbenutzer usw. Vanilla CSS ist großartig, weil es so einfach ist, eine ganze Website mit einer kleinen Änderung zu beeinflussen, was auch einer seiner größten Reibungspunkte ist. Was wir lernen müssen, ist zu trennen, was eine globale Auswirkung haben soll und was nicht.
In Vanilla CSS machen wir das mit Namespaces, aber selbst das ist nicht perfekt und erfordert Schulung und Aufsicht, um es richtig zu machen und langfristig zu pflegen. Dinge wie OOCSS, BEM und jetzt CSS-in-JS sind nur Pflaster auf einem grundlegenden Problem von CSS; Wir brauchen eine einfachere Möglichkeit, CSS zu isolieren. Darüber hinaus brauchen wir einfachere Möglichkeiten, CSS dynamisch und browserübergreifend kompatibel zu machen. Das ist ein Bereich, in dem CSS-in-JS meiner Meinung nach hilft; ich kann Themen dynamisch wechseln, konsistenter auf Bildschirmgröße und Ausrichtungsänderungen reagieren, CSS-Eigenschaften je nach Browser anpassen und sogar Themen/Marken für Komponenten innerhalb derselben Seite mischen. Sicherlich ist dies mit Vanilla CSS und den Bibliotheken und Mustern, die Entwickler und Designer im Laufe der Jahre entwickelt haben, möglich, aber der Aufwand und das Wissensniveau sind höher als in CSS-in-JS.
Was in diesen Gesprächen fehlt, ist die Anerkennung, dass unsere Websprachen für eine breite Palette von Autoren zugänglich bleiben müssen. Sie sollten für Experten robust und für Anfänger verzeihlich sein. Das ist die Gratwanderung.
Meiner Ansicht nach sollte CSS nicht nur „CSS-Experten“ überlassen werden, sondern jeder sollte lernen, CSS richtig zu nutzen.
Ich kann Ihnen gar nicht sagen, wie viele ansonsten brillante Programmierer ich getroffen habe, die entschieden haben, dass sie CSS einfach nicht mögen und es nicht lernen wollen, also zucken sie nur mit den Schultern und basteln daran herum, wann immer sie damit konfrontiert werden. Es ist zu einem regelrechten Klischee für Programmierer geworden, CSS zu hassen, ohne guten Grund. Aber CSS ist großartig (https://css-tricks.de/css-is-awesome/), wenn man ihm eine Chance gibt. Die meisten Programmierer weigern sich einfach.
Es ist kein Elitismus; jeder Programmierer kann lernen, CSS richtig zu verwenden. Sie müssen sich nur ein wenig anstrengen, anstatt zu versuchen, es nach unten zu ziehen, um ihren Komfortbereich zu treffen. Bedenken Sie, dass die Leute, die für CSS-in-JS plädieren, keine Amateure sind, die herumfuschen; es bleibt für einfache Anwendungsfälle zugänglich. Dies sind Profis, die an dem Punkt sind, an dem sie Skalierungsprobleme haben. Sie können es sich leisten, Zeit für die Erweiterung ihrer Fähigkeiten aufzuwenden.
Die BEM-Namenskonvention mit dem ITCSS-Modell deckt dieses Problem ab. Ich bin auch absolut gegen CSS in JS. Fühlt sich wie eine der schlimmsten Ideen der letzten Jahre im Frontend an. Zu Chris' Punkt, unnötiges CSS zu eliminieren: Dies kann mit einem Post-Prozessor in normalem CSS oder Sass erreicht werden.
Ich habe einige zusätzliche Gedanken dazu: https://css-tricks.de/heres-the-thing-about-unused-css-tools/
Ich stimme Chris zu. Rich Hickey (Schöpfer von Clojure) sagte einmal über Tests, Typensysteme und andere Code-Analyse-Tools:
„Ich denke, wir leben in dieser Welt, die ich Guard Rail Programming nennen möchte… ‚Ich kann Änderungen vornehmen, weil ich Tests habe!‘ Wer macht das? Wer fährt sein Auto herum und schlägt gegen die Leitplanken? Helfen die Leitplanken Ihnen, dorthin zu gelangen, wo Sie hinwollen?“
Der Programmierer muss entscheiden, „wohin“ er sein CSS „bewegen“ möchte. Das wird manchmal von den Regeln abweichen, die ein Werkzeug für nutzlos hält. Diese Werkzeuge sind nichts, dem Sie das Steuer übergeben können, sie dienen dazu, Ihre eigenen Entscheidungen zu informieren.
In unserem Studio verwenden wir keinen Prozessor für ungenutztes CSS, da die Vorteile im Vergleich zu möglichen Problemen, wie in Chris' anderem Artikel beschrieben, extrem gering sind. Ich dachte jedoch, es sei erwähnenswert, dass diese Funktion existiert.
Der Hauptpunkt ist jedoch, dass Sie CSS leicht aus CSS selbst heraus durch Namenskonventionen und eine geeignete CSS-Struktur isolieren können.
Es ist keine Schwarz-Weiß-Lösung und ich verstehe, dass manche Designs stark isolierte Module, Objekte usw. erfordern. Mein Gefühl ist jedoch, dass Designs meistens eher dem globalen Geltungsbereich zuzuordnen sind und der Geltungsbereich dann von dort aus eingeschränkt werden kann.
Selbst Facebook selbst hatte Probleme mit React im Zusammenhang mit ihrem globalen Blau. Sie hatten Hunderte von Variationen in ihrem Code, wahrscheinlich aufgrund der übermäßig isolierten Natur von React, wo tatsächlich ein globaleres CSS-Setup besser funktioniert hätte. Mein Gefühl ist hier, dass für extrem große Anwendungen wie Facebook, die schnell entwickelt und iterativ sind, möglicherweise die isolierte CSS-in-JS-Scoping der richtige Weg ist, um katastrophale Styling-Fehler zu vermeiden. Aber für uns Sterbliche, wie 95 % von uns, funktioniert globales CSS mit den richtigen Namenskonventionen und der richtigen Struktur einwandfrei.
In gewisser Weise ist die Lösung für den globalen Geltungsbereich in CSS trivial: Fügen Sie Ihrem Element eine Klasse hinzu (stellen Sie sicher, dass sie eindeutig ist) und erstellen Sie dann eine Regel, die sich auf diese Klasse bezieht und alle Deklarationen (und Überschreibungen) enthält, die Sie dort haben möchten.
Jeder Entwickler weiß das.
Das Problem ist, wenn Entwickler sowohl den globalen Geltungsbereich verachten als auch ihn nutzen wollen, meist aufgrund eines fehlgeleiteten Wunsches nach „Wiederverwendbarkeit“.
Nach meiner Erfahrung wird Wiederverwendbarkeit in CSS stark überschätzt. Ich sage nicht, dass wir nie danach streben sollten, aber wir sollten sehr vorsichtig damit sein. Zum Beispiel sollten wir eine separate „wiederverwendbare“ Komponente nur dann aus einer anderen Komponente extrahieren, wenn wir feststellen, dass wir sie tatsächlich woanders wiederverwenden. Im Wesentlichen glaube ich, dass wir voreilige Wiederverwendbarkeit vermeiden sollten, auf die gleiche Weise, wie wir voreilige Optimierung vermeiden.
Ein großartiger Artikel, Chris, und einige sehr interessante Punkte, die in den Kommentaren angesprochen wurden.
Ich kann verstehen, warum es viel Widerstand gegen CSS-in-JS gibt, und ich sympathisiere damit. Ich habe ein paar Bedenken – es fügt eine zusätzliche Komplexitätsebene hinzu, wie die Website erstellt und gewartet wird. Ich mag auch die Möglichkeit, CSS im Browser zu bearbeiten, und frage mich, ob diese Leistung etwas nachlässt, wenn man zu CSS-in-JS wechselt? Vielleicht liege ich falsch und lasse mich gerne korrigieren.
Es scheint (meiner Meinung nach zu Unrecht), dass CSS nur von Leuten behandelt wird, die aus einem „Design“-Hintergrund kommen, und dass „Programmierer“ CSS nicht mögen und versuchen, Techniken darauf anzuwenden, wogegen „CSS/UI-Ingenieure“ allergisch sind, weil sie JavaScript lernen müssen, womit nicht jeder vertraut ist.
Ich neige dazu, in diese Kategorie „CSS/UI-Ingenieur“ zu fallen – CSS zu kennen und auf dem Laufenden zu bleiben, wie Browser dies interpretieren, rendern und Ihnen beim Debuggen helfen, ist ein eigener Beruf.
Es wird interessant sein zu sehen, wie sich das 2019 und darüber hinaus entwickelt!
Das ist eines meiner Lieblingsdinge an der Art und Weise, wie Vue es macht. Ich habe isolierte, komponenten-spezifische Stile und Importe für globale CSS-Dateien für Dinge wie Layout und globale Stile. Funktioniert hervorragend.