ABEM. Eine weitere nützliche Anpassung des BEM.

0
302

BEM (Block, Element, Modifier) ist ein populäres CSS-Klasse Namenskonvention, dass macht CSS einfacher zu pflegen. Dieser Artikel setzt Voraus, dass Sie bereits vertraut sind mit der Namenskonvention. Wenn nicht, können Sie lernen, mehr über ihn zu getbem.com um sich über die Grundlagen.

Die standard-syntax für die BEM ist:

block-name – __ – element-name – – Modifikator-Namen

Ich persönlich bin eine massive fan von der Methodik, die hinter der Namensgebung. Trennen Sie Ihre Stile in kleine Komponenten ist weitaus einfacher zu pflegen, als ein Meer von hohen Spezifität Ausbreitung in deiner stylesheet. Es gibt jedoch ein paar Probleme habe ich mit der syntax, die Probleme verursachen können in der Produktion als auch zu Verwirrung führen für die Entwickler. Ich bevorzuge eine leicht geänderte version der syntax statt. Ich nenne es ABEM (Atomic-Block, Element, Modifier):

[a/m/o]-blockName__elementName-modifierName

Ein Atomic-Design-Präfix

Die a/m/o ist ein Atomic-Design-Präfix. Nicht zu verwechseln mit Atomic CSS-das ist eine ganz andere Sache. Atomic design ist eine Methodik für die Organisation Ihrer Komponenten maximiert die Wiederverwendung von code. Es teilt die Komponenten in drei Ordnern: Atome, Moleküle und Organismen. Atome sind super einfachen Komponenten bestehen in der Regel aus einem einzelnen element (z.B. ein button-Komponente). Moleküle sind kleine Gruppen von Elementen und/oder Komponenten (z.B. ein einzelnes Formularfeld zeigt ein label und ein input-Feld). Organismen sind große, komplexe Komponenten, die aus vielen Molekül-und atom-Komponenten (z.B. eine vollständige Anmeldung).

Die Schwierigkeit, mit atomic design mit klassischen BEM ist, dass es keinen Indikator zu sagen, welche Art von Komponente ein block ist. Dies kann es schwierig machen, zu wissen, wo der code für die Komponente, da Sie möglicherweise suchen in 3 separaten Ordner, um es zu finden. Hinzufügen der atomic-Präfix für den start macht es sofort klar, in welchem Ordner der Komponente gespeichert ist.

camelCase

Es ermöglicht die benutzerdefinierte Gruppierung

Classic BEM trennt jedes einzelne Wort innerhalb eines Abschnitts mit einem einzigen Strich. Beachten Sie, dass die atomic-Präfix im Beispiel oben ist auch getrennt vom rest der Klasse Namen durch einen Bindestrich. Werfen Sie einen Blick auf das, was jetzt passiert, wenn Sie hinzufügen, eine Atomare Präfix BEM klassischen camelCase vs:

/* classic + atomic Präfix */
.o-subscribe-form__field-item {}

/* camelCase – + atomic-Präfix */
.o-subscribeForm__fieldItem {}

Auf einen Blick der name der Komponente, wenn das Lesen der klassischen Methode sieht wie es heißt “o-subscribe-form”. Die Bedeutung des “o” ist komplett verloren. Wenn Sie den “o -“, um die camelCase-version, obwohl, es ist klar, dass es war absichtlich geschrieben, um ein einzelnes Stück von Informationen, um den Namen der Komponente.

Jetzt konnte Sie die atomic-Präfix zu klassischen BEM durch Großschreibung des “o” wie folgt:

/* classic + aktivierte Atomare Präfix */
.O-subscribe-form__field-item {}

Das würde das Problem auch lösen, der das “o” verloren gegangen unter dem rest der Klasse Namen aber es löst nicht das Kern zugrunde liegende Problem in der klassischen BEM-syntax. Durch die Trennung von Wörtern mit Bindestrichen, der Bindestrich ist nicht mehr verfügbar für Sie zu nutzen, als eine Gruppierung Mechanismus. Durch die Verwendung von camelCase, es setzt Sie frei, verwenden Sie den Bindestrich für zusätzliche Gruppierung, auch wenn diese Gruppierung ist nur das hinzufügen einer Zahl an das Ende der name einer Klasse.

Dein Geist wird Prozess der Gruppierungen schneller

camelCase hat auch den zusätzlichen Vorteil, dass die Gruppierung der Klasse Namen leichter mental zu verarbeiten. Mit camelCase, jede Lücke, die Sie sehen in den Namen der Klasse repräsentiert eine Gruppierung von einigen Sortieren. In der klassischen BEM, jede Lücke kann entweder eine Gruppierung oder ein Leerzeichen zwischen zwei Wörter in der gleichen Gruppe.

Werfen Sie einen Blick auf diese silhouette eines klassischen BEM-Klasse (plus atomic Präfix) und versuchen herauszufinden, wo die Präfix -, block -, element-und modifier-Abschnitte beginnen und enden:

Ok, jetzt versuchen Sie diese ein. Es ist genau die gleiche Klasse wie die oben, außer dieser Zeit ist es mit camelCase zu trennen, jedes Wort anstelle von Bindestrichen:

Das war viel einfacher, nicht wahr? Diese Silhouetten sind im Grunde das, was dein Geist sieht, wenn es scannt durch den code. Nachdem alle diese zusätzlichen Bindestriche in den Namen der Klasse machen die Gruppierungen deutlich weniger. Wie Sie Lesen durch den code, Ihr Gehirn zu verarbeiten versucht, das Wetter der Lücken, auf die es trifft, sind neue Gruppierungen, oder einfach nur neue Wörter. Dieser Mangel an Klarheit bewirkt die kognitive Last zu Wiegen, die auf Ihrem Geist, während Sie arbeiten.

classic BEM + atomic Präfix

camelCase BEM + atomic Präfix

Verwenden Sie multi-class-Selektoren (verantwortungsvoll)

Eine der Goldenen Regeln im BEM ist, dass jeder Selektor ist nur enthalten soll, eine einzelne Klasse. Die Idee ist, dass es hält, CSS wartbar durch die Beibehaltung der Spezifität von Selektoren gering und überschaubar. Auf der einen Seite Stimme ich zu, dass niedrige Spezifität vorzuziehen ist, die über die Spezifität grassierenden ausgeführt. Auf der anderen, ich Stimme völlig zu, dass eine strikte eine Klasse pro Selektor Regel ist das beste für Projekte. Mit einigen multi-class-Selektoren, die in Ihrem Stile können tatsächlich verbessern die Wartbarkeit eher zu-als abnehmen.

“Aber es führt zu einer höheren Spezifität! Weißt du nicht, dass die Spezifität ist von Natur aus böse?!?”

Spezifität != schlecht.

Unkontrollierte Besonderheit, dass losgebrochen = schlecht.

Einige höhere Spezifität Erklärungen nicht sofort bedeuten, dass dein CSS ist schwieriger zu pflegen. Wenn in der richtigen Weise, indem Sie bestimmte Regeln höhere Spezifität kann eigentlich machen CSS einfacher zu pflegen. Der Schlüssel zum schreiben wartbar CSS mit unebenen Besonderheit ist das hinzufügen Spezifität gezielt und nicht nur, weil ein Listenelement ist in einem element in der Liste.

Außerdem haben wir nicht wirklich wollen, dass unsere modifier Stile haben mehr macht über die Elemente als die Standard-Formate? Bücken nach hinten zu halten modifier Stile auf die gleiche Spezifität Ebene als die normalen styles scheint dumm zu mir. Wenn Sie tatsächlich wollen, dass Ihre regelmäßigen Standard-styles zu überschreiben, Ihren besonders bestimmten modifier-Formate?

Die Trennung der Modifikator führt zu saubereren HTML

Dies ist die größte Veränderung der syntax, ABEM führt. Statt der Anbindung des Modifikators an die element-Klasse, die Sie anwenden, es als eine separate Klasse.

Eines der Dinge, die praktisch jeder beschwert sich über, wenn Sie zuerst anfangen zu lernen BEM ist, wie hässlich es ist. Es ist besonders schlecht, wenn es um Modifikatoren. Werfen Sie einen Blick auf diese Gräueltat. Es hat nur drei Modifikatoren angewendet wurden, und noch sieht es aus wie ein Zug Wrack:

B__E–M:
<button class=”block-name__element-name block-name__element-name-small-block-name__element-name-grünen block-name__element-name–active”>
Senden
</button>

Blick auf alle, dass die Wiederholung! Die Wiederholung macht es ziemlich schwierig zu Lesen, was es eigentlich zu tun versuchen. Nun nehmen Sie einen Blick auf diese ABEM Beispiel, dass alle die gleichen Modifikatoren wie im vorherigen Beispiel:

A-B__E -M:
<button class=”a-blockName__elementName-small-green-active”>
Senden
</button>

Viel sauberer ist es nicht? Es ist viel einfacher zu sehen, was die modifier-Klassen sind versucht zu sagen, ohne sich wiederholende Zeug immer in den Weg.

Wenn die Prüfung von einem element mit der browser-DevTools, die Sie noch sehen, die volle Herrschaft in der styling-panel, so behält es die Verbindung zu der ursprünglichen Komponente in dieser Art:

.a-blockName__elementName.-green {
hintergrund: grün;
Farbe: weiß;
}

Es ist nicht viel anders wie der BEM-äquivalent

.block-name – __ – element-name-grün {
hintergrund: grün;
Farbe: weiß;
}

Die Verwaltung wird vereinfacht

Ein großer Vorteil, dass ABEM verfügt über klassische BEM ist, wird es ungemein einfacher zu verwalten den Zustand einer Komponente. Wir verwenden ein basic Akkordeon als ein Beispiel. Wenn ein Abschnitt dieses Akkordeon ist offen, lasst uns sagen, dass wir wollen, um diese änderungen zu übernehmen, um das styling:

  • Ändern Sie die Hintergrundfarbe der überschrift
  • Anzeige der content-Bereich
  • Machen Sie einen Pfeil nach unten zeigen nach oben

Wir halten die Klassiker der B__E–M-syntax für dieses Beispiel und halten Sie sich strikt an eine Klasse per css-selector-Regel. Dies ist, was wir am Ende mit (bitte beachten Sie, dass für die der Kürze halber, dieses Akkordeon ist nicht zugänglich):

Finden Sie die Stift-Accordion-1 – Pure BEM von Daniel Tonon (@daniel-tonon) auf CodePen.

Die SCSS sieht ziemlich sauber, aber nehmen Sie einen Blick auf all die zusätzlichen Klassen, die wir hinzufügen, um den HTML-Code für nur eine einzige änderung in den Staat!

HTML-während ein segment geschlossen ist, mit BEM:
<div class=”offenbarer Akkordeon__section”>
<div class=”offenbarer__trigger”>
<h2 class=”offenbarer__heading”>Drei</h2>
<div class=”offenbarer__icon”></div>
</div>
<div class=”offenbarer__content”>
Lorem ipsum dolor sit amet…
</div>
</div>
HTML-während ein segment öffnen, mit BEM:
<div class=”offenbarer Akkordeon__section”>
<div class=”offenbarer__ – trigger-revealer__ – trigger-offen”>
<h2 class=”offenbarer__überschrift”>Eine</h2>
<div class=”offenbarer__Symbol revealer__icon-open”></div>
</div>
<div class=”offenbarer__Inhalt revealer__Inhalt-offen”>
Lorem ipsum dolor sit amet…
</div>
</div>

Jetzt lassen Sie uns nehmen einen Blick an, was passiert, wenn wir wechseln über die Verwendung dieser schicke neue A-B__E -M-Methode:

Finden Sie die Stift-Akkordeon 2 – ABEM-alternative von Daniel Tonon (@daniel-tonon) auf CodePen.

Eine einzelne Klasse, jetzt steuert der Staat-spezifische styling für das gesamte Bauteil nun anstatt separate Klasse für jedes element einzeln.

HTML-während ein segment öffnen, ABEM:
<div class=”m-revealer o-Akkordeon__Abschnitt -open”>
<div class=”m-revealer__trigger”>
<h2 class=”m-revealer__überschrift”>Eine</h2>
<div class=”m-revealer__icon”></div>
</div>
<div class=”m-revealer__content”>
Lorem ipsum dolor sit amet…
</div>
</div>

Werfen Sie auch einen Blick auf, wie viel einfacher das javascript geworden ist. Ich schrieb das JavaScript so sauber, wie ich konnte, und das war das Ergebnis:

JavaScript bei Verwendung von reinem BEM:
Klasse revealer {
Konstruktor(el){
Objekt.assign(this, {
$wrapper: el,
Ziele: [‘trigger’, ‘icon’, ‘content’],
isOpen: false,
});
diese.gather_elements();
.$trigger.onclick = ()=> this.toggle();
}

gather_elements(){
const-Schlüssel=.Ziele.Karte(selector => `$${Selektor}`);
const elements = this.Ziele.Karte(selector => {
return this.$wrapper.querySelector(`.revealer__${Selektor}`);
});
lassen Sie elObject = {};
Schlüssel.forEach((key, i) => {
elObject[key] = Elemente[i];
});
Objekt.zuweisen(diese, elObject);
}

toggle(){
if (dies.isOpen) {
diese.close();
} else {
diese.open();
}
}

open(){
diese.Ziele.forEach(Ziel => {
dieser[`$${target}`].classList.add(`revealer__${target}–open`);
})
diese.isOpen = true;
}

close(){
diese.Ziele.forEach(Ziel => {
dieser[`$${target}`].classList.entfernen(`revealer__${target}–open`);
})
diese.isOpen = false;
}
}

Dokument.querySelectorAll(‘.revealer’).forEach(el => {
neue revealer(el);
})
JavaScript bei Verwendung von ABEM:
Klasse revealer {
Konstruktor(el){
Objekt.assign(this, {
$wrapper: el,
isOpen: false,
});
.$trigger = this.$wrapper.querySelector(‘.m-revealer__ “trigger”);
.$trigger.onclick = ()=> this.toggle();
}

toggle(){
if (dies.isOpen) {
diese.close();
} else {
diese.open();
}
}

open(){
.$wrapper.classList.add (`öffnen`);
diese.isOpen = true;
}

close(){
.$wrapper.classList.entfernen (`öffnen`);
diese.isOpen = false;
}
}

Dokument.querySelectorAll(‘.m-revealer’).forEach(el => {
neue revealer(el);
})

Dies war nur ein sehr einfaches Beispiel Akkordeon. Überlegen Sie, was passiert, wenn man das hochrechnet diese aus, um so etwas wie eine klebrige header, ändert sich, wenn sticky. Eine sticky-header brauchen könnte, um zu sagen 5 verschiedene Komponenten, wenn Sie die header-klebrig ist. Dann in jede dieser 5 Komponenten 5-Elemente müssen möglicherweise auf das reagieren, header sticky. Das ist 25-element.classList.add(“[Komponentenname]__[elementName]–sticky”) Regeln müssten wir schreiben in unserem js zu halten Sie sich strikt an die BEM-Namenskonvention. Was macht mehr Sinn? 25 einzigartigen Charakterklassen, die Hinzugefügt werden, um jedes element, das betroffen ist, oder nur ein sticky-Klasse Hinzugefügt, um die header, dass alle 5 Elemente in alle 5 Komponenten sind in der Lage, Zugriff auf und Lesen Sie einfach?

Die BEM “Lösung” ist völlig unpraktisch. Die Anwendung modifier styling zu großen, komplexen Komponenten endet drehen in ein wenig eine Grauzone. Eine Grauzone, die Verwirrung für alle Entwickler, die versuchen, halten Sie sich strikt an die BEM naming convention so nah wie möglich.

ABEM modifier Fragen

Die Trennung der Modifizierer ist nicht ohne seine Fehler. Jedoch gibt es einige einfache Möglichkeiten, um zu arbeiten, um diese Mängel.

Problem 1: Verschachtelung

So haben wir unseren Akkordeon-und es ist alles perfekt funktioniert. Später die Linie nach unten, der Kunde will zu brüten, ein zweites Akkordeon innerhalb der ersten. Also gehen Sie Voraus und machen Sie, dass… das passiert:

Finden Sie die Stift-Akkordeon 3 – ABEM nesting Fehler von Daniel Tonon (@daniel-tonon) auf CodePen.

Verschachtelung eine zweite Akkordeon-innerhalb der ersten Ursachen, die eine eher problematische Fehler. Öffnen des übergeordneten Akkordeon gilt auch für den Zustand “offen” – styling für alle Kind-Akkordeons in diesem segment.

Dies ist etwas, was Sie offensichtlich nicht wollen, zu geschehen. Es ist ein guter Weg, um dies zu vermeiden obwohl.

Um es zu erklären, spielen wir ein kleines Spiel. Unter der Annahme, dass diese beiden CSS-Regeln sind aktiv auf dem gleichen element, welche Farbe denken Sie, dass die element-hintergrund wäre?

.-grün > * > * > * > * > * > .element {
hintergrund: grün;
}

.element.-blue {
hintergrund: blau;
}

Wenn Sie sagte grünen aufgrund der ersten Regel mit einer höheren Spezifität als die zweite Regel, Sie wäre eigentlich falsch. Hintergrund wäre blau.

Fun fact: * ist die niedrigste Spezifität Selektor in CSS. Es bedeutet im Grunde “nichts” in CSS. Es hat eigentlich keinen specificy, was bedeutet, es doesn ‘ T fügen Sie keine Spezifität eines Selektors fügen Sie es hinzu. Das bedeutet, dass selbst wenn Sie eine Regel, die Bestand aus einer einzigen Klasse und 5-Sterne – (.element > * > * > * > * > *) es könnte noch leicht überschrieben werden, indem nur eine einzige Klasse auf der nächsten Zeile CSS!

Wir nutzen diese kleine CSS-spielerei, um einen zielgerichteten Ansatz, um die Akkordeon-SCSS-code. Dies wird es uns ermöglichen, sicher nest unsere Akkordeons.

Finden Sie die Stift-Akkordeon 4 – ABEM Verschachtelung bug-fix von Daniel Tonon (@daniel-tonon) auf CodePen.

Durch die Verwendung der .-modifierName > * > & Muster, können Sie als Ziel den direkten Nachkommen, die mehrere Ebenen tief ist, ohne dass Ihre Spezifität, außer Kontrolle zu geraten.

Ich verwende nur diese direkte Ansprache-Technik wird es aber notwendig. Standardmäßig, wenn ich Schreibe, ABEM, ich Schreibe es wie ich in dass original ABEM Akkordeon-Beispiel. Die nicht zielgerichtete Methode ist in der Regel alles, was benötigt wird in den meisten Fällen. Das problem mit den gezielten Ansatz ist, dass das hinzufügen einer einzigen wrapper um etwas potenziell brechen das ganze system. Die nicht-zielgerichteten Ansatz nicht leiden unter diesem problem. Es ist viel mehr Nachsicht und verhindert, dass die Stile aus zu brechen wenn Sie jemals brauchen werden, zu ändern, den HTML-später auf der ganzen Linie.

Problem 2: Namenskonflikte

Ein Problem, das Sie ausführen können, in die nicht-gezielte modifier Technik ist der Namenskonflikte. Lassen Sie uns sagen, dass Sie benötigen, um erstellen Sie eine Reihe von Reitern und jeder Reiter hat ein Akkordeon. Beim schreiben dieses Codes, die Sie vorgenommen haben beide Akkordeon und tabs reagieren auf die aktiven-Klasse. Dies führt zu einem Namenskonflikt. Alle Akkordeons in die aktive Registerkarte wird Ihre aktive Stile angewendet. Dies ist, weil alle Akkordeons sind Kinder der Registerkarte container-Elemente. Es ist die tab-container-Elemente, die über den eigentlichen aktiven-Klasse angewendet. (Weder die tabs noch das Akkordeon im folgenden Beispiel sind zugänglich für die der Kürze halber.)

Finden Sie die Stift-Akkordeon-tabs 1 – gebrochen durch Daniel Tonon (@daniel-tonon) auf CodePen.

Nun eine Möglichkeit, diesen Konflikt zu lösen, wäre zu einfach ändern, das Akkordeon zu reagieren, um eine -offene-Klasse anstelle einer aktiven Klasse. Ich würde wirklich empfehlen, dass Ansatz. Aus Gründen der ein Beispiel, obwohl, zu sagen, dass eine option nicht. Sie konnte die direkte Ansprache eine Technik erwähnt, aber das macht Ihre Stile sehr spröde. Stattdessen, was Sie tun können, ist fügen Sie den Namen der Komponente an der Vorderseite des Modifikators, wie diese:

.o-componentName {
&__elementName {
.-componentName–modifierName & {
/* modifier-Stile gehen hier */
}
}
}

Der Strich an der Vorderseite der name immer noch bedeutet, dass es ist ein modifier-Klasse. Die Komponente name-namespace verhindert, dass Kollisionen mit anderen Komponenten, die nicht immer betroffen. Die double dash ist in Erster Linie einfach nur eine Anspielung auf den klassischen BEM modifier syntax zu verdoppeln, verstärken, es ist ein modifier-Klasse.

Hier ist der accordion-und tabs-Beispiel wieder, aber dieses mal mit dem namespace fix angewendet:

Finden Sie die Stift-Akkordeon-tabs 2 – Fix von Daniel Tonon (@daniel-tonon) auf CodePen.

Ich empfehle, nicht mit dieser Technik standardmäßig aber vor allem für den Willen halten Sie das HTML sauber und auch um zu verhindern, Verwirrung, wenn mehrere Komponenten teilen müssen die gleiche modifier.

Die Mehrheit der Zeit, eine modifier-Klasse wird verwendet, um bedeuten eine Veränderung im Staat wie in der Akkordeon-Beispiel oben. Wenn ein element seinen Zustand ändert, werden alle untergeordneten Elemente, egal, welche Komponente Sie gehören, sollten in der Lage sein zu Lesen, dass der Staat ändern, und Sie reagieren darauf leicht. Wenn eine modifier-Klasse ist so konzipiert, um Auswirkungen auf mehrere Komponenten auf einmal, kann Verwirrung entstehen rund um die was-Komponente, die modifier speziell gehört. In jenen Fällen, name-Abstand der Modifikator bringt mehr Schaden als nutzen.

ABEM modifier Technik Zusammenfassung

So machen Sie das beste aus den ABEM modifier verwenden .-modifierName & oder &.-modifierName syntax standardmäßig (hängt davon ab, welches element hat die Klasse drauf)

.o-componentName {
&.-modifierName {
/* componentName modifier Stile gehen hier */
}

&__elementName {
.-modifierName & {
/* elementName modifier Stile gehen hier */
}
}
}

Nutzen Sie direkte Ausrichtung, wenn das verschachteln einer Komponente in sich selbst ist zu einem Problem.

.o-componentName {
&__elementName {
.-nestedModifierName > * > & {
/* modifier-Stile gehen hier */
}
}
}

Verwenden Sie den Namen der Komponente in der Modifizierer, wenn Sie shared-Modifizierer-name Kollisionen. Tun Sie dies nur, wenn Sie nicht denken, eine andere Modifikator-Namen, der noch Sinn macht.

.o-componentName {
&__elementName {
.-componentName–sharedModifierName & {
/* modifier-Stile gehen hier */
}
}
}

Kontextsensitive Stile

Ein weiteres Problem mit strikter Einhaltung der BEM eine Klasse pro Selektor Methodik ist, dass es nicht erlauben, Sie zu schreiben, kontextsensitive Stile.

Kontextsensitive Stile sind im Grunde “, wenn das element innerhalb dieser übergeordneten, wenden Sie diese Formatvorlagen, um es”.

Mit Kontext-sensitiven Stilen, es ist eine übergeordnete Komponente und eine untergeordnete Komponente. Die parent-Komponente sein sollte, gilt die layout verwandten Stilen wie margin und position der untergeordneten Komponente (.Eltern .Kind { margin: 20px }). Die Kind-Komponente sollte immer standardmäßig nicht jedem Rand um die Außenseite der Komponente. Dies ermöglicht es dem Kind-Komponenten verwendet werden, die in mehr Kontexten, da es die Eltern verantwortlich, es ist ein eigenes layout, anstatt Ihre Kinder.

Genau wie mit real Erziehung, die Eltern sind diejenigen, wer sollte die Verantwortung übernehmen. Sie sollten nicht lassen Sie Ihre frechen ahnungslosen Kinder das sagen haben, wenn es um die Eltern-layout.

Zu Graben weiter in dieses Konzept, lassen Sie uns behaupten, dass wir eine frische neue website und jetzt bauen wir die subscribe-form-Komponente für die Website.

Finden Sie den Stift kontextsensitive 1 – IE unfreundlich von Daniel Tonon (@daniel-tonon) auf CodePen.

Dies ist das erste mal, dass wir mussten eine form auf dieses tolle neue Website, die wir bauen. Wollen wir sein wie all die coolen kids, so dass wir CSS-raster, um das layout. Wir sind smart obwohl. Wir wissen, dass die button-styling ist noch in viel mehr Orten auf der gesamten Website. Um Euch darauf vorzubereiten, trennen wir den abonnieren-button-Stilen in seine eigene separate Komponente wie wenig gute Entwickler.

Eine Weile später starten wir cross-browser-testing. Wir eröffnen IE11 nur um zu sehen, dieses hässliche Ding starrt uns ins Gesicht:

IE11 macht Art der Unterstützung, CSS-raster, aber es keine Unterstützung für grid-Lücke oder die automatische Platzierung. Nach einigen kathartische fluchen und wünschte, die Leute würden aktualisieren Sie Ihren Browser, passen Sie die Formatvorlagen für mehr wie folgt Aussehen:

Finden Sie den Stift Kontext-sensitive 2 – was Sie nicht tun von Daniel Tonon (@daniel-tonon) auf CodePen.

Jetzt sieht es perfekt im IE. Alles stimmt mit der Welt. Was könnte möglicherweise schief gehen?

Ein paar Stunden später werden Sie die Umsetzung dieser button-Komponente in eine andere Komponente auf der Website. Diese andere Komponente verwendet auch css-raster, um das layout Ihrer Kinder.

Schreiben Sie den folgenden code:

Finden Sie den Stift Kontext-sensitive 3 – die andere Komponente von Daniel Tonon (@daniel-tonon) auf CodePen.

Sie erwarten ein layout, das so aussieht auch im IE11:

Aber anstatt, wegen der grid-column: 3; code, den Sie früher schrieb, es endet auf der Suche wie diese:

Huch! Also, was tun wir über das grid-column: 3; CSS wir früher geschrieben? Wir müssen uns beschränken auf die übergeordnete Komponente wie aber sollen wir dies tun?

Auch die klassischen BEM-Methode, damit umzugehen ist, um eine neue übergeordnete Komponente element-Klasse, die button wie dieser:

Finden Sie den Stift Kontext-sensitive 4 – classic BEM Lösung von Daniel Tonon (@daniel-tonon) auf CodePen.

Auf der Oberfläche dieser Lösung sieht sehr gut aus:

  • Es hält die Spezifität niedrig
  • Die parent-Komponente wird die Kontrolle seiner eigenen layout
  • Das styling ist nicht wahrscheinlich zu Bluten in andere Komponenten, die wir nicht wollen, dass es zu einer Blutung in

Alles ist toll und alles ist richtig mit der Welt… richtig?

Der Nachteil dieses Ansatzes ist vor allem aufgrund der Tatsache, dass wir hatten eine extra Klasse für die button-Komponente. Da die subscribe-Formular__submit-Klasse nicht vorhanden in der base button-Komponente, es bedeutet, dass wir brauchen, um zusätzliche Logik auf das, was wir als unsere Template-engine, dass Sie erhalten die richtigen styles.

Ich Liebe mit Mops für die Erstellung meiner Seite Vorlagen. Ich werde Ihnen zeigen, was ich meine, mit Mops Mixins in Verbindung als Beispiel.

Zuerst, hier ist das original IE-unfreundlich-code neu geschrieben in mixin-format:

Finden Sie den Stift kontextsensitive 5 – ALSO unfreundlich mit Mixins in Verbindung von Daniel Tonon (@daniel-tonon) auf CodePen.

Jetzt können wir hinzufügen, dass der IE 11 abonnieren-Formular__submit class:

Finden Sie den Stift kontextsensitive 6 – IE sicherer BEM-Lösung mit Mixins in Verbindung von Daniel Tonon (@daniel-tonon) auf CodePen.

Das war nicht so schwer, so was bin ich zu beschweren? Nun lassen Sie uns sagen, dass wir manchmal wollen Sie dieses Modul, um in einer Seitenleiste. Wenn es soweit ist, wollen wir die E-Mail-Eingang und die Schaltfläche gestapelt übereinander. Denken Sie daran, dass, um zu halten Sie sich strikt an BEM, wir sind nicht erlaubt die Verwendung von etwas höheren Spezifität als eine einzige Klasse in unserem Stile.

Finden Sie den Stift kontextsensitive 7 – IE sicherer BEM mit Mixins in Verbindung in der Seitenleiste von Daniel Tonon (@daniel-tonon) auf CodePen.

Das Mops-code nicht auf der Suche ist so einfach, jetzt ist es? Es gibt ein paar Dinge, die Ihren Beitrag zu diesem Chaos.

  1. Container Abfragen, würde dies weit weniger ein problem, aber Sie weiß es noch nicht nativ in jedem browser
  2. Die Probleme rund um die BEM-modifier syntax Aufzucht sind Ihre hässlichen Köpfe.

Jetzt probieren wir es wieder tun, aber diesmal mit Kontext-sensitiven Arten:

Finden Sie den Stift Kontext-Sensitiv 8 – IE sicher kontextsensitive mit Mixins in Verbindung in der Seitenleiste von Daniel Tonon (@daniel-tonon) auf CodePen.

Schauen Sie, wie viel einfacher das Mops-markup geworden. Es gibt kein “wenn dies, dann das” – Logik zu kümmern, in der Mops-markup. Alle, die elterliche Logik weitergereicht zu den css, die ist viel besser zu verstehen, was Elemente sind, die Eltern der anderen Elemente sowieso.

Sie haben vielleicht bemerkt, dass ich eine Auswahl, die drei Klassen tiefer in dieses Letzte Beispiel. Es wurde verwendet, um 100% der Breite auf die Schaltfläche. Ja, eine drei-Klassen-Selektor ist ok, wenn Sie kann es zu rechtfertigen.

Ich wollte nicht, dass 100% der Breite angewandt werden, um die Taste, jedes mal war es:

  • überhaupt überall
  • innerhalb der subscribe-Formular
  • im Innern der side-bar

Ich wollte nur 100% Breite angewendet werden, wenn es war, sowohl innerhalb der abonnieren form und innerhalb der sidebar. Der beste Weg, zu behandeln, wurde mit einer drei-Klassen-Selektor.

Ok, in der Realität, ich würde eher die Verwendung einer ABEM Stil -verticalStack modifier-Klasse auf den abonnieren-Formular-element, das für den vertikalen stack-Stile oder vielleicht sogar machen es durch element Abfragen mit EQCSS. Dies würde bedeuten, dass ich anwenden könnte die vertikale Stapel Stile in mehr Situationen als nur dann, wenn es in der Seitenleiste. Aus Gründen der ein Beispiel obwohl, ich habe es getan, als kontextsensitive Stile.

Jetzt, da wir verstehen, Kontext-sensitive Stile, gehen wir wieder zurück zum ursprünglichen Beispiel, das ich hatte und verwenden Sie eine kontextsensitive Stilen, lästig grid-column: 3-Regel:

Finden Sie den Stift kontextsensitive 9 – Kontext-sensitive Methode mit Mixins in Verbindung von Daniel Tonon (@daniel-tonon) auf CodePen.

Kontextsensitive Stile führen zu einfacher HTML-und Template-Logik, während noch die Beibehaltung der Wiederverwendbarkeit von Kind-Komponenten. BEM ist eine Klasse pro Selektor Philosophie nicht zulässt, dass dies passiert.

Da Kontext-Sensitiv Stile in Erster Linie um das layout, je nach den Umständen, sollten Sie in der Regel verwenden Sie Sie, Wann immer Sie sind den Umgang mit diesen CSS-Eigenschaften:

  • Etwas CSS-grid Verwandte, die angewendet wird, um die Kind-element (grid-column, grid-Zeile etc.)
  • Alles flexbox Verwandte, die angewendet wird, um die Kind-element (flex-grow, flex-shrink, align-self etc.)
  • margin-Werte, die größer als 0
  • position andere Werte als relative (zusammen mit dem oben, Links, unten und rechts-Eigenschaften)
  • transformieren wenn es ist verwendet für die Positionierung wie translateY

Vielleicht möchten Sie auch, diese Eigenschaften in einen Kontext-sensitive Stile, aber Sie sind nicht so oft benötigt in einem Kontext, in sensibler Weise.

  • Breite
  • Höhe
  • Polsterung
  • Grenze

Absolut klar, obwohl, Kontext-sensitive Stile sind nicht in Schachteln für den Willen der Verschachtelung. Sie müssen Bedenken, dass Sie, als ob Sie waren, schreiben Sie eine if-Anweisung in JavaScript.

Also für eine CSS-Regel wie diese:

.Eltern .element {
/* Kontext-sensitive styles */
}

Sie sollte denken Sie daran, wie Sie schreiben, diese Art von Logik:

if (.element in .parent) {
.element { /* Kontext-sensitive styles */ }
}

Auch verstehen, dass das schreiben eine Regel, die ist drei Ebenen tief ist wie diese:

.Großeltern .Eltern .element {
/* Kontext-sensitive styles */
}

Nachgedacht werden sollte, wie Sie schreiben, die Logik wie diese:

wenn (
(.element in .parent) &&
(.element in .Großeltern) &&
(.Eltern in .Großeltern)
) {
.element { /* Kontext-sensitive styles */ }
}

So mit allen Mitteln, schreiben einen css-Selektor, der ist drei Stufen tiefer, wenn Sie wirklich denken, Sie brauchen, dass die Ebene der Spezifität. Bitte verstehen Sie die zugrunde liegende Logik der css, Sie schreiben aber. Verwenden Sie nur eine Ebene der Besonderheit, dass macht Sinn für das Besondere styling, das Sie versuchen, zu erreichen.

Und wieder einmal mehr, einfach nur super klar, nicht nest zum Wohle der Verschachtelung!

Zusammenfassung

Die Methodik hinter der BEM Namenskonvention ist etwas, das ich von ganzem Herzen unterstützen. Es ermöglicht css zerlegt werden in kleine, leicht überschaubare Komponenten anstatt die css in einer sperrigen Durcheinander von hoher Spezifität, die nur schwer zu pflegen. Die offizielle syntax für die BEM hat eine Menge zu wünschen übrig, obwohl.

Die offiziellen BEM-syntax:

  • Nicht unterstützt Atomic Design
  • Nicht verlängert werden leicht
  • Dauert länger für Ihre Meinung zum Prozess der Gruppierung der Klasse Namen
  • Schrecklich inkompetent, wenn es um die Verwaltung auf große Bauteile
  • Versucht, Euch zu ermutigen, die Verwendung von single-class-Selektoren, wenn Doppel-class-Selektoren führen zu leichter Wartbarkeit
  • Versucht, Namen-Platz alles, auch wenn die Verwendung von Namensräumen verursacht mehr Probleme als es löst.
  • Macht HTML-extrem aufgebläht, wenn man es richtig

Meine inoffizielle ABEM Ansatz:

  • Macht das arbeiten mit Atomic Design einfacher
  • Macht der Bindestrich als eine zusätzliche Methode, die verwendet werden können für die Gruppierung
  • Erlaubt, Ihre Meinung zum Prozess der Vereinigung der Klassennamen schneller
  • Ausgezeichnete handling-Status auf jede Größe der Komponente keine Rolle, wie viele sub-Komponenten hat
  • Ermutigt gesteuert Spezifität, anstatt nur offener geringe Spezifität zu mildern Unklarheiten im team und verbessern die Wartbarkeit Website
  • Vermeidet die Verwendung von Namensräumen, wenn es nicht gebraucht wird
  • Hält HTML sehr sauber, mit minimalen zusätzlichen Klassen angewendet Module, während immer noch Beibehaltung aller der BEM-Vorteile

Haftungsausschluss

Ich habe nicht erfunden -modifier (single dash, bevor Sie den Modifikator-Namen) Idee. Ich entdeckte es im Jahr 2016 vom Lesen einen Artikel. Ich kann mich nicht erinnern, wer ursprünglich konzipiert die Idee. Ich bin froh, dass Kredit Sie wenn jemand weiß, der Artikel.