Die Wartung eines groß angelegten CSS-Projekts ist schwierig. Im Laufe der Jahre haben wir verschiedene Ansätze zur Erleichterung des Schreibens von skalierbarem CSS beobachtet. Am Ende versuchen wir alle, die folgenden beiden Ziele zu erreichen
- Effizienz: Wir wollen die Zeit reduzieren, die wir damit verbringen, darüber nachzudenken, wie Dinge getan werden sollten, und die Zeit erhöhen, die wir damit verbringen, Dinge zu tun.
- Konsistenz: Wir wollen sicherstellen, dass alle Entwickler auf dem gleichen Stand sind.
Seit anderthalb Jahren arbeite ich an einer Komponentenbibliothek und einem Front-End-Framework namens CodyFrame. Wir haben derzeit über 220 Komponenten. Diese Komponenten sind keine isolierten Module: Sie sind wiederverwendbare Muster, die oft miteinander verschmolzen werden, um komplexe Vorlagen zu erstellen.
Die Herausforderungen dieses Projekts haben unser Team gezwungen, eine Methode zum Aufbau skalierbarer CSS-Architekturen zu entwickeln. Diese Methode stützt sich auf CSS-Globale, BEM und Utility-Klassen.
Ich teile sie gerne! 👇
CSS Globals in 30 Sekunden
Globals sind CSS-Dateien, die Regeln enthalten, die übergreifend für alle Komponenten gelten (z. B. Abstands-Skala, Typografie-Skala, Farben usw.). Globals verwenden Tokens, um das Design über alle Komponenten hinweg konsistent zu halten und die Größe ihrer CSS zu reduzieren.
Hier ist ein Beispiel für globale Typografieregeln
/* Typography | Global */
:root {
/* body font size */
--text-base-size: 1em;
/* type scale */
--text-scale-ratio: 1.2;
--text-xs: calc((--text-base-size / var(--text-scale-ratio)) / var(--text-scale-ratio));
--text-sm: calc(var(--text-xs) * var(--text-scale-ratio));
--text-md: calc(var(--text-sm) * var(--text-scale-ratio) * var(--text-scale-ratio));
--text-lg: calc(var(--text-md) * var(--text-scale-ratio));
--text-xl: calc(var(--text-lg) * var(--text-scale-ratio));
--text-xxl: calc(var(--text-xl) * var(--text-scale-ratio));
}
@media (min-width: 64rem) { /* responsive decision applied to all text elements */
:root {
--text-base-size: 1.25em;
--text-scale-ratio: 1.25;
}
}
h1, .text-xxl { font-size: var(--text-xxl, 2.074em); }
h2, .text-xl { font-size: var(--text-xl, 1.728em); }
h3, .text-lg { font-size: var(--text-lg, 1.44em); }
h4, .text-md { font-size: var(--text-md, 1.2em); }
.text-base { font-size: --text-base-size; }
small, .text-sm { font-size: var(--text-sm, 0.833em); }
.text-xs { font-size: var(--text-xs, 0.694em); }
BEM in 30 Sekunden
BEM (Blocks, Elements, Modifiers) ist eine Benennungsmethodik, die darauf abzielt, wiederverwendbare Komponenten zu erstellen.
Hier ist ein Beispiel:
<header class="header">
<a href="#0" class="header__logo"><!-- ... --></a>
<nav class="header__nav">
<ul>
<li><a href="#0" class="header__link header__link--active">Homepage</a></li>
<li><a href="#0" class="header__link">About</a></li>
<li><a href="#0" class="header__link">Contact</a></li>
</ul>
</nav>
</header>
- Ein Block ist eine wiederverwendbare Komponente
- Ein Element ist ein Kind des Blocks (z. B.
.block__element) - Ein Modifier ist eine Variation eines Blocks/Elements (z. B.
.block--modifier, .block__element--modifier).
Utility-Klassen in 30 Sekunden
Eine Utility-Klasse ist eine CSS-Klasse, die nur eine einzige Aufgabe hat. Zum Beispiel
<section class="padding-md">
<h1>Title</h1>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>
</section>
<style>
.padding-sm { padding: 0.75em; }
.padding-md { padding: 1.25em; }
.padding-lg { padding: 2em; }
</style>
Sie können potenziell ganze Komponenten aus Utility-Klassen aufbauen
<article class="padding-md bg radius-md shadow-md">
<h1 class="text-lg color-contrast-higher">Title</h1>
<p class="text-sm color-contrast-medium">Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>
</article>
Sie können Utility-Klassen mit CSS-Globals verbinden
/* Spacing | Global */
:root {
--space-unit: 1em;
--space-xs: calc(0.5 * var(--space-unit));
--space-sm: calc(0.75 * var(--space-unit));
--space-md: calc(1.25 * var(--space-unit));
--space-lg: calc(2 * var(--space-unit));
--space-xl: calc(3.25 * var(--space-unit));
}
/* responsive rule affecting all spacing variables */
@media (min-width: 64rem) {
:root {
--space-unit: 1.25em; /* 👇 this responsive decision affects all margins and paddings */
}
}
/* margin and padding util classes - apply spacing variables */
.margin-xs { margin: var(--space-xs); }
.margin-sm { margin: var(--space-sm); }
.margin-md { margin: var(--space-md); }
.margin-lg { margin: var(--space-lg); }
.margin-xl { margin: var(--space-xl); }
.padding-xs { padding: var(--space-xs); }
.padding-sm { padding: var(--space-sm); }
.padding-md { padding: var(--space-md); }
.padding-lg { padding: var(--space-lg); }
.padding-xl { padding: var(--space-xl); }
Ein reales Beispiel
Die Erklärung einer Methodik anhand einfacher Beispiele bringt nicht die wirklichen Probleme oder die Vorteile der Methode selbst hervor.
Lassen Sie uns gemeinsam etwas aufbauen!
Wir erstellen eine Galerie von Karten-Elementen. Zuerst tun wir dies nur mit dem BEM-Ansatz und weisen auf die Probleme hin, auf die Sie stoßen können, wenn Sie nur BEM verwenden. Als Nächstes sehen wir, wie Globals die Größe Ihres CSS reduzieren. Schließlich machen wir die Komponente anpassbar, indem wir Utility-Klassen hinzufügen.
Hier ist ein Blick auf das Endergebnis
Beginnen wir dieses Experiment mit der Erstellung der Galerie nur mit BEM
<div class="grid">
<article class="card">
<a class="card__link" href="#0">
<figure>
<img class="card__img" src="/image.jpg" alt="Image description">
</figure>
<div class="card__content">
<h1 class="card__title-wrapper"><span class="card__title">Title of the card</span></h1>
<p class="card__description">Lorem ipsum dolor sit amet consectetur adipisicing elit. Tempore, totam?</p>
</div>
<div class="card__icon-wrapper" aria-hidden="true">
<svg class="card__icon" viewBox="0 0 24 24"><!-- icon --></svg>
</div>
</a>
</article>
<article class="card"><!-- card --></article>
<article class="card"><!-- card --></article>
<article class="card"><!-- card --></article>
</div>
In diesem Beispiel haben wir zwei Komponenten: .grid und .card. Die erste wird verwendet, um das Galerie-Layout zu erstellen. Die zweite ist die Kartenkomponente.
Zunächst einmal möchte ich die Hauptvorteile der Verwendung von BEM hervorheben: geringe Spezifität und Scope.
/* without BEM */
.grid {}
.card {}
.card > a {}
.card img {}
.card-content {}
.card .title {}
.card .description {}
/* with BEM */
.grid {}
.card {}
.card__link {}
.card__img {}
.card__content {}
.card__title {}
.card__description {}
Wenn Sie BEM (oder eine ähnliche Benennungsmethode) nicht verwenden, erstellen Sie Vererbungsbeziehungen (.card > a).
/* without BEM */
.card > a.active {} /* high specificity */
/* without BEM, when things go really bad */
div.container main .card.is-featured > a.active {} /* good luck with that 😦 */
/* with BEM */
.card__link--active {} /* low specificity */
Der Umgang mit Vererbung und Spezifität in großen Projekten ist schmerzhaft. Dieses Gefühl, wenn Ihr CSS nicht zu funktionieren scheint, und Sie feststellen, dass es von einer anderen Klasse überschrieben wurde 😡! BEM hingegen schafft eine Art Scope für Ihre Komponenten und hält die Spezifität niedrig.
Aber... es gibt zwei Hauptnachteile der ausschließlichen Verwendung von BEM:
- Zu viele Dinge zu benennen ist frustrierend
- Kleinere Anpassungen sind nicht einfach vorzunehmen oder zu warten
In unserem Beispiel haben wir zur Stilisierung der Komponenten die folgenden Klassen erstellt
.grid {}
.card {}
.card__link {}
.card__img {}
.card__content {}
.card__title-wrapper {}
.card__title {}
.card__description {}
.card__icon-wrapper {}
.card__icon {}
Die Anzahl der Klassen ist nicht das Problem. Das Problem ist, sich so viele aussagekräftige Namen auszudenken (und dafür zu sorgen, dass alle Ihre Teamkollegen die gleichen Benennungskriterien verwenden).
Stellen Sie sich zum Beispiel vor, Sie müssen die Kartenkomponente um einen zusätzlichen, kleineren Absatz erweitern
<div class="card__content">
<h1 class="card__title-wrapper"><span class="card__title">Title of the card</span></h1>
<p class="card__description">Lorem ipsum dolor...</p>
<p class="card__description card__description--small">Lorem ipsum dolor...</p> <!-- 👈 -->
</div>
Wie nennen Sie ihn? Sie könnten ihn als Variation des .card__description-Elements betrachten und zu .card__description .card__description--small greifen. Oder Sie könnten ein neues Element erstellen, etwas wie .card__small, .card__small-p oder .card__tag. Sehen Sie, worauf ich hinauswill? Niemand möchte Zeit mit dem Nachdenken über Klassennamen verbringen. BEM ist großartig, solange man nicht zu viele Dinge benennen muss.
Das zweite Problem ist der Umgang mit kleineren Anpassungen. Stellen Sie sich zum Beispiel vor, Sie müssen eine Variation der Kartenkomponente erstellen, bei der der Text zentriert ausgerichtet ist.
Sie werden wahrscheinlich so etwas tun
<div class="card__content card__content--center"> <!-- 👈 -->
<h1 class="card__title-wrapper"><span class="card__title">Title of the card</span></h1>
<p class="card__description">Lorem ipsum dolor sit amet consectetur adipisicing elit. Tempore, totam?</p>
</div>
<style>
.card__content--center { text-align: center; }
</style>
Einer Ihrer Teamkollegen, der an einer anderen Komponente (.banner) arbeitet, steht vor demselben Problem. Er erstellt ebenfalls eine Variation für seine Komponente
<div class="banner banner--text-center"></div>
<style>
.banner--text-center { text-align: center; }
</style>
Stellen Sie sich nun vor, Sie müssen die Bannerkomponente in eine Seite einfügen. Sie benötigen die Variation, bei der der Text zentriert ausgerichtet ist. Ohne die CSS der Bannerkomponente zu überprüfen, könnten Sie instinktiv so etwas wie banner banner--center in Ihrem HTML schreiben, weil Sie immer --center verwenden, wenn Sie Variationen erstellen, bei denen der Text zentriert ausgerichtet ist. Funktioniert nicht! Ihre einzige Option ist, die CSS-Datei der Bannerkomponente zu öffnen, den Code zu inspizieren und herauszufinden, welche Klasse angewendet werden sollte, um den Text zu zentrieren.
Wie lange würde das dauern, 5 Minuten? Multiplizieren Sie 5 Minuten mit all den Zeiten, in denen dies am Tag passiert, für Sie und alle Ihre Teamkollegen, und Sie werden erkennen, wie viel Zeit verschwendet wird. Außerdem trägt das Hinzufügen neuer Klassen, die dasselbe tun, zur Aufblähung Ihres CSS bei.
CSS Globals und Utility-Klassen zur Rettung
Der erste Vorteil der Einrichtung globaler Stile ist, dass eine Reihe von CSS-Regeln vorhanden ist, die für alle Komponenten gelten.
Wenn wir beispielsweise responsive Regeln für die Abstands- und Typografieglobals festlegen, wirken sich diese Regeln auch auf die Grid- und Kartenkomponenten aus. In CodyFrame erhöhen wir die Schriftgröße des Körpers bei einem bestimmten Breakpoint; da wir für alle Ränder und Abstände "em"-Einheiten verwenden, wird das gesamte Abstandssystem auf einmal aktualisiert, was einen Kaskadeneffekt erzeugt.

Folglich müssen Sie in den meisten Fällen keine Media Queries verwenden, um die Schriftgröße oder die Werte von Abständen und Rändern zu erhöhen!
/* without globals */
.card { padding: 1em; }
@media (min-width: 48rem) {
.card { padding: 2em; }
.card__content { font-size: 1.25em; }
}
/* with globals (responsive rules intrinsically applied) */
.card { padding: var(--space-md); }
Nicht nur das! Sie können die Globals verwenden, um Verhaltenskomponenten zu speichern, die mit allen anderen Komponenten kombiniert werden können. Zum Beispiel definieren wir in CodyFrame eine Klasse namens .text-component, die als "Text-Wrapper" verwendet wird. Sie kümmert sich um Zeilenhöhe, vertikale Abstände, Basisstile und andere Dinge.
Wenn wir zu unserem Kartenbeispiel zurückkehren, könnte das Element .card__content durch Folgendes ersetzt werden
<!-- without globals -->
<div class="card__content">
<h1 class="card__title-wrapper"><span class="card__title">Title of the card</span></h1>
<p class="card__description">Lorem ipsum dolor sit amet consectetur adipisicing elit. Tempore, totam?</p>
</div>
<!-- with globals -->
<div class="text-component">
<h1 class="text-lg"><span class="card__title">Title of the card</span></h1>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Tempore, totam?</p>
</div>
Die Textkomponente kümmert sich um die Textformatierung und macht sie über alle Textblöcke in Ihrem Projekt konsistent. Außerdem haben wir bereits ein paar BEM-Klassen eliminiert.
Schließlich führen wir die Utility-Klassen ein!
Utility-Klassen sind besonders nützlich, wenn Sie die Komponente später anpassen möchten, ohne deren CSS überprüfen zu müssen.
So ändert sich die Struktur der Kartenkomponente, wenn wir einige BEM-Klassen durch Utility-Klassen ersetzen
<article class="card radius-lg">
<a href="#0" class="block color-inherit text-decoration-none">
<figure>
<img class="block width-100%" src="image.jpg" alt="Image description">
</figure>
<div class="text-component padding-md">
<h1 class="text-lg"><span class="card__title">Title of the card</span></h1>
<p class="color-contrast-medium">Lorem ipsum dolor sit amet consectetur adipisicing elit. Tempore, totam?</p>
</div>
<div class="card__icon-wrapper" aria-hidden="true">
<svg class="icon icon--sm color-white" viewBox="0 0 24 24"><!-- icon --></svg>
</div>
</a>
</article>
Die Anzahl der BEM-(Komponenten-)Klassen ist von 9 auf 3 gesunken
.card {}
.card__title {}
.card__icon-wrapper {}
Das bedeutet, Sie werden sich nicht viel mit der Benennung von Dingen beschäftigen. Dennoch können wir das Benennungsproblem nicht vollständig vermeiden: Selbst wenn Sie Vue/React/SomeOtherFramework-Komponenten aus Utility-Klassen erstellen, müssen Sie die Komponenten immer noch benennen.
Alle anderen BEM-Klassen wurden durch Utility-Klassen ersetzt. Was ist, wenn Sie eine Kartenvariation mit einer größeren Überschrift erstellen müssen? Ersetzen Sie text-lg durch text-xl. Was ist, wenn Sie die Farbe des Symbols ändern möchten? Ersetzen Sie color-white durch color-primary. Wie wäre es mit der zentrierten Textausrichtung? Fügen Sie text-center zum text-component-Element hinzu. Weniger Zeit zum Nachdenken, mehr Zeit zum Tun!
Warum verwenden wir nicht einfach Utility-Klassen?
Utility-Klassen beschleunigen den Designprozess und erleichtern die Anpassung von Dingen. Warum also nicht BEM vergessen und nur Utility-Klassen verwenden? Zwei Hauptgründe
Durch die Verwendung von BEM zusammen mit Utility-Klassen ist das HTML einfacher zu lesen und anzupassen.
Verwenden Sie BEM für
- das Vermeiden von Redundanzen im HTML bei CSS, das Sie nicht anpassen möchten (z. B. verhaltensbezogenes CSS wie Übergänge, Positionierung, Hover/Fokus-Effekte),
- erweiterte Animationen/Effekte.
Verwenden Sie Utility-Klassen für
- die "häufig angepassten" Eigenschaften, die oft zur Erstellung von Komponentenvariationen verwendet werden (wie Abstände, Ränder, Textausrichtung usw.),
- Elemente, die schwer mit einem neuen, aussagekräftigen Klassennamen zu identifizieren sind (z. B. Sie benötigen ein übergeordnetes Element mit
position: relative→ erstellen Sie<div class="position-relative"><div class="my-component"></div></div>).
Beispiel:
<!-- use only Utility classes -->
<article class="position-relative overflow-hidden bg radius-lg transition-all duration-300 hover:shadow-md col-6@sm col-4@md">
<!-- card content -->
</article>
<!-- use BEM + Utility classes -->
<article class="card radius-lg col-6@sm col-4@md">
<!-- card content -->
</article>
Aus diesen Gründen empfehlen wir, die !important-Regel nicht zu Ihren Utility-Klassen hinzuzufügen. Die Verwendung von Utility-Klassen muss nicht wie ein Hammer sein. Glauben Sie, es wäre vorteilhaft, auf eine CSS-Eigenschaft im HTML zuzugreifen und sie zu ändern? Verwenden Sie eine Utility-Klasse. Benötigen Sie eine Reihe von Regeln, die nicht bearbeitet werden müssen? Schreiben Sie sie in Ihr CSS. Dieser Prozess muss nicht beim ersten Mal perfekt sein: Sie können die Komponente später bei Bedarf anpassen. Es mag mühsam klingen, "sich entscheiden zu müssen", aber es ist ziemlich einfach, wenn Sie es in die Praxis umsetzen.
Utility-Klassen sind nicht Ihr bester Verbündeter, wenn es um die Erstellung einzigartiger Effekte/Animationen geht.
Denken Sie an die Arbeit mit Pseudo-Elementen oder die Erstellung einzigartiger Bewegungseffekte, die benutzerdefinierte Bézier-Kurven erfordern. Dafür müssen Sie immer noch Ihre CSS-Datei öffnen.
Betrachten Sie zum Beispiel den animierten Hintergrundeffekt der von uns gestalteten Karte. Wie schwierig wäre es, einen solchen Effekt mit Utility-Klassen zu erstellen?
Dasselbe gilt für die Icon-Animation, die Animations-Keyframes benötigt, um zu funktionieren
.card:hover .card__title {
background-size: 100% 100%;
}
.card:hover .card__icon-wrapper .icon {
animation: card-icon-animation .3s;
}
.card__title {
background-image: linear-gradient(transparent 50%, alpha(var(--color-primary), 0.2) 50%);
background-repeat: no-repeat;
background-position: left center;
background-size: 0% 100%;
transition: background .3s;
}
.card__icon-wrapper {
position: absolute;
top: 0;
right: 0;
width: 3em;
height: 3em;
background-color: alpha(var(--color-black), 0.85);
border-bottom-left-radius: var(--radius-lg);
display: flex;
justify-content: center;
align-items: center;
}
@keyframes card-icon-animation {
0%, 100% {
opacity: 1;
transform: translateX(0%);
}
50% {
opacity: 0;
transform: translateX(100%);
}
51% {
opacity: 0;
transform: translateX(-100%);
}
}
Endergebnis
Hier ist die endgültige Version der Karten-Galerie. Sie enthält auch Grid-Utility-Klassen zur Anpassung des Layouts.
Dateistruktur
So würde die Struktur eines Projekts aussehen, das nach der in diesem Artikel beschriebenen Methode aufgebaut ist
project/
└── main/
├── assets/
│ ├── css/
│ │ ├── components/
│ │ │ ├── _card.scss
│ │ │ ├── _footer.scss
│ │ │ └── _header.scss
│ │ ├── globals/
│ │ │ ├── _accessibility.scss
│ │ │ ├── _breakpoints.scss
│ │ │ ├── _buttons.scss
│ │ │ ├── _colors.scss
│ │ │ ├── _forms.scss
│ │ │ ├── _grid-layout.scss
│ │ │ ├── _icons.scss
│ │ │ ├── _reset.scss
│ │ │ ├── _spacing.scss
│ │ │ ├── _typography.scss
│ │ │ ├── _util.scss
│ │ │ ├── _visibility.scss
│ │ │ └── _z-index.scss
│ │ ├── _globals.scss
│ │ ├── style.css
│ │ └── style.scss
│ └── js/
│ ├── components/
│ │ └── _header.js
│ └── util.js
└── index.html
Sie können das CSS (oder SCSS) jeder Komponente in einer separaten Datei speichern (und optional PostCSS-Plugins verwenden, um jede neue /component/componentName.css-Datei in style.css zu kompilieren). Organisieren Sie die Globals nach Belieben; Sie könnten auch eine einzige Datei globals.css erstellen und die Globals nicht in verschiedene Dateien aufteilen.
Fazit
Die Arbeit an groß angelegten Projekten erfordert eine solide Architektur, wenn Sie Ihre Dateien Monate später öffnen und sich nicht verlieren möchten. Es gibt viele Methoden, die dieses Problem angehen (CSS-in-JS, Utility-First, Atomic Design usw.).
Die Methode, die ich Ihnen heute vorgestellt habe, stützt sich auf übergreifende Regeln (Globals), die Verwendung von Utility-Klassen für schnelle Entwicklung und BEM für modulare (verhaltensbezogene) Klassen.
Sie können mehr über diese Methode auf CodyHouse erfahren. Jedes Feedback ist willkommen!
Ich unterstütze Utility-Klassen voll und ganz, seit ich Tailwind entdeckt habe. Ich denke, Ihre Einschätzung des "Was" und "Warum" ist großartig. Es ist nicht daran gedacht, mit BEM kombiniert zu werden, aber es ist ein interessanter Gedanke.
Danke, Doug!
Schöner Artikel, danke! Ich verwende diese Methodik seit einiger Zeit. Ich mische ABEM und Bootstrap 4 Utility-Klassen und habe festgestellt, dass es eine ziemlich gute Kombination ist :)
Danke! ABEM ist auch großartig
Gleichfalls! Und ich bin auf dieses Muster auf ähnliche Weise gestoßen wie der Autor, indem ich BEM benutzte und es leid war, Dinge mit demselben Modifier zu benennen und sie dann in eine Utility-Klasse auszulagern.
Ich neige dazu, Utility-Mixins zu verwenden, weil ich den Bootstrap-Höllen vermeiden möchte, um Dutzende von Klassen innerhalb eines Elements zu überprüfen, und trotzdem eine Art zentralen Kontrollpunkt beibehalten möchte.
Okay, das finale CSS ist etwas schwerer (nicht so sehr dank GZIP-Kompression), aber ich kann buchstäblich HTML stylen, ohne überhaupt zu wissen, wo es ist, auf diese Weise.
Interessant! Ich schätze, Sie verwenden Dinge wie .foo { @include radius; @include padding-top;} , um alles an einem separaten _mixins.scss-File zu steuern. Auch wenn ich diesen Ansatz noch nie verwendet habe, sehe ich viele Vorteile, diesen Weg einzuschlagen. Danke fürs Teilen
Ich mag diesen Ansatz
https://www.npmjs.com/package/@michu1234/goel?activeTab=readme
Ich verwende eine ähnliche Methodik: https://www.xfive.co/blog/itcss-scalable-maintainable-css-architecture/
Ich präsentiere jede Klasse mit ihrem Typ. Zum Beispiel c-card und g-radius-lg.
Das ist vorteilhaft aus 2 Gründen
1. Wenn jemand, der das Framework nicht kennt, eine Klasse card erstellt, wird sie Ihre c-card nicht überschreiben.
2. c-card g-radius-lg g-col-6@sm g-col-4@md -> es ist einfacher zu erkennen, was eine Komponente und was ein Global ist.
Das ist ungefähr die gleiche Schlussfolgerung, zu der ich gekommen bin! Zuerst habe ich Sachen mit Klassen und generischen Tag-Selektoren gestylt, Sie wissen schon, das Übliche
Aber dann, wenn Sie einen weiteren Absatz in dieser Karte haben, vermasseln diese ersten Regeln es, also nennen Sie es .card-text und so weiter.
Nachdem ich eine ganze Weile mit Bootstrap gearbeitet hatte und dann mehr lernen wollte, stieß ich auf BEM und begann, BEM immer mehr zu übernehmen. Leider habe ich am Anfang versucht, BEM so viel wie möglich zu verwenden, und hatte vielleicht 5-6 Utility-Klassen.
Aber später, als ich mehr Erfahrung sammelte, erkannte ich, dass BEM für mich nicht funktioniert, wenn ich mich ausschließlich darauf verlasse, und so beschloss ich, zu experimentieren, indem ich mehr Utility-Klassen hinzufügte.
Am Ende erkannte ich, dass die Verwendung von BEM für die meiste Arbeit und die Verwendung von Utility-Klassen für einige gängige Stile wie Typografie, Abstände, vielleicht Farben und ein paar andere Dinge es mir ermöglichten, schneller und effizienter zu arbeiten, insbesondere wenn ich eine neue Ansicht in einer Anwendung erstellen muss. Abstands-Utility-Klassen (Padding/Margin) helfen hier enorm für schnelles Prototyping und die Etablierung konsistenter Layouts.
Meine bevorzugte Methodik ist seit einiger Zeit BEM + Utility-Klassen. Zwar nicht auf diesem Niveau wie das Setup, das Sie hier mit all den Globals und allem haben, aber ich habe das Setup gefunden, das für mich funktioniert.
Leider machen Designer nicht immer alles super konsistent, und das ist ein Bereich, in dem Utility-Klassen mir sehr geholfen haben. Ich bin sicher, wir alle hatten schon eine Situation, in der ein Designer Sie einfach bittet, "diesen Rand hier zu entfernen" oder "dieser Text muss in der Primärfarbe hervorgehoben werden", und mit Utility-Klassen ist diese Änderung ein Kinderspiel.
Ich liebe einfach die Flexibilität, die mir dieser Ansatz gegeben hat.
Global gesehen ein ähnlicher Ansatz hier: BEM für alles, mit ein paar Utility-Klassen hier und da (das kleinste Beispiel, das ich mir vorstellen kann, ist in Can We). Für mich ist es der beste Ansatz, um die Wartbarkeit sowohl von HTML als auch von CSS zu gewährleisten.
Ich beginne, den BEM-Weg zu gehen, und benutze seit einiger Zeit Utility-Klassen. Ich frage mich, ob es eine gute Idee wäre, die BEM-Doppelbindestrich-Modifier-Konvention für Utility-Klassen beizubehalten? Also für etwas wie .color-attention oder .text-lg den Klassennamen .–color-attention oder .–text-lg geben?
Es sind im Wesentlichen Modifier, und das würde der BEM-Konvention entsprechen. Gedanken?
Was sind die Voraussetzungen für die Anwendung dieser Methode? Ich nehme an, man müsste eine Styleguide verwenden oder ein Systemdesign vorhanden haben.