ABEM. Een meer nuttige aanpassing van de BEM.

0
104

BEM (Blok Element Fonetisch) is een populaire CSS-klasse naam conventie die maakt CSS makkelijker te onderhouden. In dit artikel wordt ervan uitgegaan dat u al bekend bent met de naamgeving. Als je niet meer kunt leren over het op getbem.com catch up op de basis.

De standaard syntax voor BEM is:

blokkeren-naam – __ – element-naam: modifier-naam

Ik ben persoonlijk een enorme fan van de methodologie achter de naamgeving. Het scheiden van uw stijlen in kleine onderdelen is veel makkelijker te onderhouden dan een zee van hoge specificiteit verspreid in je stylesheet. Echter, er zijn een paar problemen die ik heb met de syntaxis die kunnen leiden tot problemen in de productie en leiden tot verwarring voor ontwikkelaars. Ik geef de voorkeur aan een iets gewijzigde versie van de syntaxis in de plaats. Ik noem het ABEM (Atomic Block Element Fonetisch):

[a/m/o]-blockName__elementName -modifierName

Een Atomaire Ontwerp Voorvoegsel

De a/m/o is een Atomaire Ontwerp voorvoegsel. Niet te verwarren met Atomic CSS is een heel ander ding. Atomic design is een methode voor het organiseren van uw componenten die maximaliseert de mogelijkheden tot hergebruik van code. Het splitst uw onderdelen in drie mappen: atomen, moleculen, organismen. Atomen zijn super eenvoudig onderdelen die over het algemeen bestaan uit slechts een enkel element (bijvoorbeeld een knop-component). Moleculen zijn in kleine groepen van elementen en/of onderdelen (bijv. een enkel formulier velden met een label en een input-veld). Organismen zijn grote complexe onderdelen opgebouwd uit vele molecuul en atoom onderdelen (bijv. een volledige registratie-formulier).

De moeilijkheid van het gebruik van atomaire design met klassieke BEM is dat er geen indicator te zeggen wat voor soort van onderdeel van een blok is. Dit kan het moeilijk maken om te weten waar de code voor dat onderdeel is, omdat je kan hebben om te zoeken in 3 afzonderlijke mappen om het te vinden. Het toevoegen van de atomaire voorvoegsel aan het begin meteen al duidelijk maakt welke map het onderdeel is opgeslagen in.

camelCase

Het zorgt voor aangepaste groepering

Klassieke BEM scheidt elk woord binnen een sectie met één streepje. Merk op dat de atomaire prefix in het bovenstaande voorbeeld is ook gescheiden van de rest van de naam van de klasse door een streepje. Neem een kijkje op wat er nu gebeurt als je een atomaire voorvoegsel BEM klassieke vs camelCase:

/* classic + atomic voorvoegsel */
.o-abonneren-formulier__field-item {}

/* camelCase + atomic voorvoegsel */
.o-subscribeForm__fieldItem {}

In een oogopslag de naam van de component bij het lezen van de klassieke methode lijkt het heet “o aanmeldformulier”. De betekenis van de “o” is volledig verloren gegaan. Wanneer u de toepassing de “o-” aan de camelCase versie al, het is duidelijk dat het opzettelijk geschreven om een apart stuk van de informatie de naam van het onderdeel.

Nu kon u van toepassing van de atomaire voorvoegsel klassieke BEM door in te spelen op de “o” als deze:

/* classic + gekapitaliseerde atomic voorvoegsel */
.O-abonneren-formulier__field-item {}

Dat zou op te lossen het probleem van de “o” aan de verloren tussen de rest van de naam van de klasse echter niet het oplossen van de kern onderliggende probleem in de klassieke BEM-syntaxis. Door het scheiden van de woorden met koppeltekens, de streep is niet meer beschikbaar voor u om te gebruiken als een groepering mechanisme. Door het gebruik van camelCase, het bevrijdt je om gebruik te maken van de streep voor extra groeperen, zelfs als dat samenwerkingsverband is gewoon het toevoegen van een nummer aan het einde van de naam van een klasse.

Uw geest zal het verwerken van de groepen sneller

camelCase heeft ook het extra voordeel van het maken van de groepering van de namen van de klassen gemakkelijker om mentaal proces. Met camelCase, elke kloof zie je in de naam van de klasse vertegenwoordigt een groep van een soort. In de klassieke BEM, ieder gat kan een groepering of een spatie tussen de twee woorden in dezelfde groep.

Neem een kijkje op deze silhouet van een klassieke BEM klasse (plus atomic voorvoegsel) en proberen te achterhalen waar de prefix, blok, element en modifier secties start en einde:

Ok, nu probeer dit eens. Het is precies dezelfde klasse als hierboven, behalve deze keer is het met camelCase van elkaar te scheiden en word in plaats van streepjes:

Dat was veel makkelijker niet? Deze silhouetten zijn in wezen wat je geest ziet als het scannen via uw code. Om al die extra streepjes in de naam van de klasse maken de groepen veel minder duidelijk. Als u lezen via uw code, je hersenen verwerken probeert weer de hiaten aangetroffen zijn nieuwe groeperingen of gewoon nieuwe woorden. Deze onduidelijkheid veroorzaakt cognitieve belasting te wegen op je hoofd als je werk.

klassieke BEM + atomic voorvoegsel

camelCase BEM + atomic voorvoegsel

Gebruik multi-class selectors (verantwoord)

Een van de gouden regels in de BEM is dat elke kiezer alleen zou moeten bevatten van een enkele klasse. Het idee is dat het blijft CSS beheersbaar te houden door de specificiteit van kiezers laag en beheersbaar. Aan de ene kant ben ik het eens dat de lage specificiteit is te verkiezen boven het hebben specificiteit lopen ongebreideld. Aan de andere, die ik volstrekt niet mee eens dat een strikte één klas per selector regel is het beste voor de projecten. Met behulp van enkele multi-class selectors in uw stijlen kunnen daadwerkelijk verbeteren van de onderhoudbaarheid plaats van verminderen.

“Maar het leidt tot een hogere specificiteit! Weet u niet dat de specificiteit is inherent kwaad?!?”

Specificiteit != slecht.

Ongecontroleerde specificiteit die is uitgevoerd wild = slecht.

Met een hogere specificiteit verklaringen niet direct te betekenen dat je je CSS is moeilijker te onderhouden. Als het gebruikt wordt op de juiste manier, het geven van bepaalde regels hogere specificiteit kan in feite maken CSS makkelijker te onderhouden. De sleutel tot het schrijven van onderhoudbaar CSS met ongelijke specificiteit toe te voegen specificiteit doelgericht en niet alleen omdat een item in de lijst gebeurt binnen een element in de lijst.

Daarnaast hoeven we het eigenlijk niet willen dat onze modifier stijlen hebben een grotere macht over de elementen dan de standaard stijlen? Buigen achterover te houden modifier stijlen op dezelfde specificiteit niveau als normaal stijlen lijkt dom om mij. Wanneer wil je eigenlijk je gewone standaard stijlen voor het overschrijven van uw specifiek aangewezen modifier stijlen?

Het scheiden van de modifier leidt tot schonere HTML

Dit is de grootste verandering in de syntaxis die ABEM introduceert. In plaats van het aansluiten van de modifier element klasse, past u het als een aparte klasse.

Een van de dingen die bijna iedereen klaagt over toen ze voor het eerst beginnen met het leren van BEM is hoe lelijk het is. Het is vooral slecht als het gaat om modifiers. Neem een kijkje op deze gruweldaad. Het heeft slechts drie parameters toegepast en toch ziet het eruit als een trein wrak:

B__E–M:
<button class=”block-name__element-naam blokkeren-naam – __ – element-naam–kleine blok-naam – __ – element-naam–groene blok-naam – __ – element-naam–active”>
Verzenden
</button>

Kijk naar al die herhaling! Die herhaling maakt het vrij moeilijk om te lezen wat het eigenlijk probeert te doen. Neem nu een kijkje op deze ABEM voorbeeld dat heeft dezelfde genen als in het vorige voorbeeld:

A-B__E -M:
<button class=”een-blockName__elementName -small -groen -active”>
Verzenden
</button>

Veel schoner, niet? Het is veel makkelijker om te zien wat deze modifier klassen probeert te zeggen zonder dat herhaalde smurrie in de weg zitten.

Bij een inspectie van een element met browser DevTools, zie je nog steeds de volledige regel in de styling paneel, zodat het behoud van de verbinding met de oorspronkelijke component op die manier:

.a-blockName__elementName.-groen {
achtergrond: groen;
kleur: wit;
}

Het is niet veel verschillend van de BEM-equivalent

.blokkeren-naam – __ – element-naam–groen {
achtergrond: groen;
kleur: wit;
}

Het beheren van state wordt eenvoudig

Een groot voordeel dat ABEM heeft over klassieke BEM is dat het wordt enorm eenvoudiger te beheren, de toestand van een component. Laten we gebruik maken van een basic accordeon als een voorbeeld. Wanneer een gedeelte van deze accordeon is geopend, laten we zeggen dat we willen deze wijzigingen toepassen om de styling:

  • Het wijzigen van de achtergrond kleur van de sectie omschrijving
  • De weergave van de inhoud gebied
  • Een pijl-omhoog

Wij zijn gaan houden van de klassieke B__E–M syntax voor dit voorbeeld en zich strikt te houden aan de één klas per css selector regel. Dit is wat we eindigen met (let op, dat omwille van de beknoptheid, deze accordeon is niet toegankelijk):

Zie de Pen Accordeon 1 – Pure BEM door Daniel Tonon (@daniel-tonon) op CodePen.

De SCSS ziet er redelijk schoon, maar neem een kijkje op de extra lessen die we moeten toevoegen aan de HTML-code voor een enkele wijziging in staat!

HTML terwijl een segment wordt gesloten met BEM:
<div class=”openbaarder accordeon__section”>
<div class=”openbaarder__trigger”>
<h2 class=”openbaarder__rubriek”>Drie</h2>
<div class=”openbaarder__icon”></div>
</div>
<div class=”openbaarder__content”>
Lorem ipsum dolor sit amet…
</div>
</div>
HTML terwijl een segment is het open met behulp van BEM:
<div class=”openbaarder accordeon__section”>
<div class=”openbaarder__trigger revealer__trigger–open”>
<h2 class=”openbaarder__rubriek”>Een</h2>
<div class=”openbaarder__pictogram revealer__pictogram–open”></div>
</div>
<div class=”openbaarder__inhoud revealer__content–open”>
Lorem ipsum dolor sit amet…
</div>
</div>

Laten we nu eens kijken wat er gebeurt wanneer we overschakelen naar het gebruik van dit mooie nieuwe A-B__E -M methode:

Zie de Pen Accordeon 2 – ABEM alternatief door Daniel Tonon (@daniel-tonon) op CodePen.

Een enkele klasse nu regelt de state-specifieke styling voor de gehele component wordt nu in plaats van het toepassen van een aparte klasse voor elk element afzonderlijk.

HTML terwijl een segment is het open met behulp van ABEM:
<div class=”m-revealer o-accordeon__sectie -open”>
<div class=”m-revealer__trigger”>
<h2 class=”m-revealer__rubriek”>Een</h2>
<div class=”m-revealer__icon”></div>
</div>
<div class=”m-revealer__content”>
Lorem ipsum dolor sit amet…
</div>
</div>

Ook, neem een kijkje op hoe veel eenvoudiger de javascript is geworden. Ik schreef de JavaScript-code en netjes als ik maar kon en dit was het resultaat:

JavaScript bij het gebruik van pure BEM:
klasse revealer {
constructor(el){
– Object.toewijzen(dit, {
$wrapper: el,
doelen: [‘trigger’, ‘icon’, ‘inhoud’],
isOpen: false,
});
deze.gather_elements();
.$trigger.onclick = ()=> dit.toggle();
}

gather_elements(){
const toetsen = dit.doelen.kaart(selector => `$${selector}`);
const elementen = dit.doelen.kaart(selector => {
retourneren.$wrapper.querySelector(`.revealer__${selector}`);
});
laat elObject = {};
toetsen.forEach((sleutel, i) => {
elObject[key] = elementen[i];
});
– Object.toewijzen(dit elObject);
}

toggle(){
als dit.isOpen) {
deze.sluiten();
} else {
deze.open();
}
}

open(){
deze.doelen.forEach(doel => {
deze[`$${target}`].classList.add(`openbaarder__${target}–open`);
})
deze.isOpen = true;
}

close(){
deze.doelen.forEach(doel => {
deze[`$${target}`].classList.verwijderen(`openbaarder__${target}–open`);
})
deze.isOpen = false;
}
}

document.querySelectorAll(‘.revealer’).forEach(el => {
nieuwe openbaarder(el);
})
JavaScript bij het gebruik van ABEM:
klasse revealer {
constructor(el){
– Object.toewijzen(dit, {
$wrapper: el,
isOpen: false,
});
.$trigger=.$wrapper.querySelector(‘.m-revealer__trigger’);
.$trigger.onclick = ()=> dit.toggle();
}

toggle(){
als dit.isOpen) {
deze.sluiten();
} else {
deze.open();
}
}

open(){
.$wrapper.classList.add (`open`);
deze.isOpen = true;
}

close(){
.$wrapper.classList.verwijderen (`open`);
deze.isOpen = false;
}
}

document.querySelectorAll(‘.m-revealer’).forEach(el => {
nieuwe openbaarder(el);
})

Dit was gewoon een zeer eenvoudige accordeon voorbeeld. Denk na over wat er gebeurt als je het extrapoleren van deze uit naar iets als een kleverige koptekst die verandert als sticky. Een sticky kop zou moeten vertellen 5 verschillende componenten wanneer de kop is plakkerig. Dan is in elk van deze 5 componenten, 5 elementen nodig om te reageren op die kop te plakken. Dat is de 25-element.classList.toevoegen(“[componentnaam]__[elementName]–sticky”) de regels die we nodig zouden hebben om te schrijven in onze js om zich strikt te houden aan de BEM naamgeving. Wat is logischer? 25 unieke klassen die worden toegevoegd aan elk element dat wordt beïnvloed, of in één kleverige klasse toegevoegd aan de koptekst dat alle 5 elementen in 5 componenten zijn in staat om toegang te krijgen tot en lezen gemakkelijk?

De BEM “oplossing” is volledig onpraktisch. Het toepassen van modifier styling tot grote complexe onderdelen eindigt draaien in een beetje een grijs gebied. Een grijze zone die de verwarring veroorzaakt voor alle ontwikkelaars proberen om zich strikt te houden aan de BEM naming convention zo nauw mogelijk.

ABEM modifier problemen

Het scheiden van de modifier niet zonder zijn gebreken. Echter, er zijn een aantal eenvoudige manieren om te werken rond deze gebreken.

Probleem 1: Nesten

Dus hebben we onze accordeon en het is allemaal perfect werkt. Later langs de lijn, de klant wil nest een tweede accordeon in de eerste. Dus ga je gang en doen dat… gebeurt er dit:

Zie de Pen Accordeon 3 – ABEM nesten bug door Daniel Tonon (@daniel-tonon) op CodePen.

Het nesten van een tweede accordeon in de eerste zorgt voor een zeer problematisch bug. Het openen van de ouder accordeon geldt ook voor de open state styling aan alle van het kind accordeons in dat segment.

Dit is iets dat je natuurlijk niet willen dat er gebeurt. Er is een goede manier om te voorkomen dat deze al is.

Om het te verklaren, laten we een spelletje spelen. Ervan uitgaande dat beide van deze CSS-regels die actief zijn op hetzelfde element, welke kleur denk je dat element op de achtergrond zou worden?

.-groen > * > * > * > * > * > .element {
achtergrond: groen;
}

.element.-blauw {
achtergrond: blue;
}

Als je zei dat groen te wijten aan de eerste regel met een hogere specificiteit dan de tweede regel, je zou eigenlijk verkeerd. De achtergrond zou worden blauw.

Leuk weetje: * is de laagste specificiteit kiezen in CSS. Het betekent in feite “niets” in CSS. Het heeft eigenlijk geen specificy, wat betekent dat het niet toevoegen van specificiteit van een selector die u toevoegt aan. Dat betekent dat zelfs als u een regel, die bestond uit een enkele klasse en 5 sterren (.element > * > * > * > * > *) het kan ook nog eenvoudig worden overschreven door slechts een enkele klasse op de volgende regel van CSS!

We kunnen profiteren van deze kleine CSS gril te maken van een meer gerichte aanpak van de accordeon SCSS code. Dit zal ons toelaten om veilig nest onze accordeons.

Zie de Pen Accordeon 4 – ABEM nesten bug fix door Daniel Tonon (@daniel-tonon) op CodePen.

Met behulp van de .-modifierName > * > & patroon, je kunt richten op directe afstammelingen zijn van meerdere niveaus diep gaan zonder dat je specificiteit uit de hand.

Ik gebruik alleen deze directe targeting techniek als het nodig is wel. Standaard, als ik aan het schrijven ben ABEM, zal ik schrijven hoe ik het deed in die oorspronkelijke ABEM accordeon voorbeeld. De niet-gerichte methode is over het algemeen alles wat nodig is in de meeste gevallen. Het probleem met de gerichte aanpak is dat het toevoegen van een wrapper rond iets kan mogelijk breken het hele systeem. De niet-gerichte aanpak geen last van dit probleem. Het is veel soepeler en voorkomt dat de stijlen van het breken van als je ooit nodig hebt voor het wijzigen van de HTML later langs de lijn.

Probleem 2: naamconflicten

Een probleem dat u kunt uitvoeren in het gebruik van de niet-gerichte modifier techniek is de naamgeving van botsingen. Laten we zeggen dat je nodig hebt om een set tabbladen en elk tabblad heeft een accordeon in. Tijdens het schrijven van deze code, kunt u zowel de accordeon en de tabbladen reageren op de actieve klas. Dit leidt tot een naam botsing. Alle accordeons in de actieve tab zal hun active stijlen toegepast. Dit is omdat alle van de accordeons zijn de kinderen van de tab container elementen. Het is de tab container elementen die de werkelijke-actieve klasse zijn toegepast. (Noch de tabbladen noch de accordeon in het volgende voorbeeld zijn toegankelijk omwille van de beknoptheid.)

Zie de Pen Accordeon in tab 1 – gebroken door Daniel Tonon (@daniel-tonon) op CodePen.

Nu een manier voor het oplossen van dit conflict zou zijn om gewoon de accordeon te reageren op een -open klasse, in plaats van een actieve klasse. Eigenlijk zou ik adviseren aanpak. Omwille van een voorbeeld hoewel, laten we zeggen dat is geen optie. U kan gebruik maken van de directe targeting techniek hierboven vermeld, maar dat maakt uw stijlen zeer broos. In plaats daarvan wat je kunt doen is het toevoegen van de naam van het onderdeel tot aan de voorkant van de modifier zoals deze:

.o-componentnaam {
&__elementName {
.-componentnaam–modifierName & {
/* modificatietoets stijlen gaan hier */
}
}
}

Het streepje aan de voorkant van de naam nog steeds betekent dat het is een speciale klasse. De naam van de component voorkomt naamruimte botsingen met andere onderdelen die niet mogen worden aan getroffen. De double dash is vooral gewoon een knipoog naar de klassieke BEM modifier syntaxis dubbel versterken is een speciale klasse.

Hier is de accordeon en de tabbladen voorbeeld weer maar dit keer met de naamruimte correctie wordt toegepast:

Zie de Pen Accordeon in tabbladen 2 – vastgesteld door Daniel Tonon (@daniel-tonon) op CodePen.

Ik adviseer niet met behulp van deze techniek standaard maar vooral voor het belang van het houden van de HTML-schoon en ook om verwarring te voorkomen wanneer meerdere componenten nodig voor het delen van hetzelfde modifier.

De meerderheid van de tijd, is een speciale klasse wordt gebruikt om te duiden op een verandering in de toestand zoals op de accordeon voorbeeld hierboven. Wanneer een element verandert in, worden alle onderliggende elementen, ongeacht welke component waartoe ze behoren, moeten in staat zijn om te lezen, dat staat te veranderen en reageren snel. Wanneer een speciale klasse is bedoeld om invloed uit meerdere onderdelen tegelijk, verwarring kan ontstaan over welke onderdeel dat modifier specifiek behoort. In die gevallen, de naam van de ruimte tussen de modifier doet meer kwaad dan goed.

ABEM modifier techniek samenvatting

Dus om optimaal gebruik te maken van de ABEM modifier gebruiken .-modifierName & of &.-modifierName syntaxis standaard (hangt af van welk element is de klasse)

.o-componentnaam {
&.-modifierName {
/* componentnaam modifier stijlen gaan hier */
}

&__elementName {
.-modifierName & {
/* elementName modifier stijlen gaan hier */
}
}
}

Gebruik directe aanvallen als het nesten van een component binnen zelf is de oorzaak van een probleem.

.o-componentnaam {
&__elementName {
.-nestedModifierName > * > & {
/* modificatietoets stijlen gaan hier */
}
}
}

Gebruik de naam van het onderdeel in de modifier als je in de gedeelde modifier naam botsingen. Doe dit alleen als je niet kunt denken aan een andere modifier naam die nog steeds zinvol is.

.o-componentnaam {
&__elementName {
.-componentnaam–sharedModifierName & {
/* modificatietoets stijlen gaan hier */
}
}
}

Context gevoelige stijlen

Een ander probleem met het strikt handhaven van de BEM één klas per selector methode is dat het u niet toe te schrijven context-gevoelige stijlen.

Context gevoelige stijlen zijn in principe “als dit element is binnen deze ouder, deze stijlen toepassen”.

Met context-gevoelige stijlen, er is een ouder deel en een kind component. De ouder component moet die van toepassing lay-out gerelateerde stijlen, zoals de marge-en de positie van het kind component (.ouder .child { margin: 20px }). Het kind onderdeel moet altijd standaard geen marge rond de buitenkant van de component. Dit kan de onderliggende onderdelen worden gebruikt in meer contexten, omdat het voor de ouders in de kosten van een eigen lay-out in plaats van haar kinderen.

Net als met echte opvoeding, de ouders zijn degenen die verantwoordelijk zou moeten zijn. Moet je niet laten hun ondeugende clueless kinderen het voor het zeggen hebben als het gaat om de ouders lay-out.

Verder te graven in dit concept, laten we doen alsof dat we bouwen aan een frisse nieuwe website en nu bouwen we het aanmeldformulier component voor de site.

Zie de Pen Context-gevoelige 1 – IE onvriendelijke door Daniel Tonon (@daniel-tonon) op CodePen.

Dit is de eerste keer dat we in moeten zetten om een formulier in op deze geweldige nieuwe site die we aan het bouwen zijn. We willen graag alle coole kids zodat we de gebruikte CSS grid om de lay-out. We zijn slim hoor. We weten dat de knop styling zal worden gebruikt in veel meer plaatsen op de website. Om dit voor te bereiden, scheiden we de knop abonneren stijlen in zijn eigen, afzonderlijke component als goede kleine ontwikkelaars.

Een tijdje later hebben we beginnen met cross-browser testen. We IE11 alleen om te zien dit lelijke ding staren ons in het gezicht:

IE11 geeft ondersteuning voor CSS grid, maar het biedt geen ondersteuning voor raster-gap of de automatische plaatsing. Na een louterend, vloeken en die mensen zouden een update van hun browsers, past u de stijlen om te kijken meer als dit:

Zie de Pen Context gevoelige 2 – wat niet te doen door Daniel Tonon (@daniel-tonon) op CodePen.

Nu ziet het er perfect in IE. Alles in de wereld. Wat kan er mis gaan?

Een paar uur later brengt u met deze knop een component in een ander onderdeel op de site. Deze andere component maakt ook gebruik van css-grid lay-out van de kinderen.

U schrijft de volgende code:

Zie de Pen Context-gevoelige 3 – de andere component van Daniel Tonon (@daniel-tonon) op CodePen.

Verwacht u een lay-out die lijkt dit zelfs in IE11:

Maar in plaats daarvan door de grid-kolom: 3; de code die je al eerder schreef, het eindigt als volgt:

Yikes! Dus wat doen we met dit rooster-kolom: 3; CSS schreven we eerder? Wij moeten beperken tot het bovenliggende onderdeel, maar hoe moeten we dat doen?

Ook de klassieke BEM methode van omgaan met deze is het toevoegen van een nieuwe ouder component-element-klasse op de knop, zoals deze:

Zie de Pen contextgevoelige 4 – klassieke BEM oplossing door Daniel Tonon (@daniel-tonon) op CodePen.

Op het oppervlak van deze oplossing ziet er best goed:

  • Het houdt specificiteit laag
  • De ouder component is het beheersen van haar eigen lay-out
  • De styling is niet waarschijnlijk dat bloeden in andere componenten, we willen het niet te bloeden in

Alles is geweldig en alles in de wereld… toch?

Het nadeel van deze aanpak is voornamelijk te wijten aan het feit dat we hadden om een extra klasse aan het onderdeel knop. Sinds de subscribe-formulier__indienen klasse niet bestaan in de basis knop component, het betekent dat we moeten extra logica toevoegen aan wat we met onze template engine voor het ontvangen van de juiste stijlen.

Ik hou van het gebruik van Pug te genereren mijn pagina sjablonen. Ik zal je tonen wat ik bedoel met Pug mixins als een voorbeeld.

Ten eerste, hier is de originele IE onvriendelijke code opnieuw geschreven in mixin formaat:

Zie de Pen Context gevoelig 5 – IE onvriendelijke met mixins door Daniel Tonon (@daniel-tonon) op CodePen.

Nu kunt toevoegen dat IE 11 abonneer u-vorm__indienen klasse:

Zie de Pen Context-gevoelige 6 – IE veilig BEM oplossing met mixins door Daniel Tonon (@daniel-tonon) op CodePen.

Dat was niet zo moeilijk, dus wat ben ik dan om te klagen over? En laten we nu zeggen dat we soms willen deze module worden geplaatst in een zijbalk. Wanneer het is, we willen de e-ingang en de knop om te worden gestapeld op de top van elkaar. Vergeet niet dat om te strikt te houden aan BEM, wij zijn niet toegestaan gebruik te maken van iets hogere specificiteit dan één klasse in onze stijlen.

Zie de Pen Context-gevoelige 7 – IE veilig BEM met mixins in de zijbalk van Daniel Tonon (@daniel-tonon) op CodePen.

Dat Pug code is niet op zoek zo nu gemakkelijk is het? Er zijn een paar dingen bij te dragen aan deze puinhoop.

  1. Container query ‘ s zou dit veel minder een probleem, maar ze hebben er nog niet native in elke browser
  2. De problemen rond de BEM modifier syntaxis zijn voor de opvoeding van hun lelijke koppen.

Laat nu doe je het weer, maar deze keer met behulp van context-gevoelige stijlen:

Zie de Pen Context-gevoelige 8 – IE veilige Context-Gevoelig met mixins in de zijbalk van Daniel Tonon (@daniel-tonon) op CodePen.

Kijken hoe veel eenvoudiger de Pug markup is geworden. Er is geen “als dit dan dat” logica zich zorgen te maken over de mopshond markup. Alle ouderlijke logica is doorgegeven uit aan de css die is veel beter in het begrijpen van wat elementen zijn de ouders van de andere elementen toch.

Je hebt misschien gemerkt dat ik met een selector die was drie klassen diep in dat laatste voorbeeld. Het werd gebruikt bij het toepassen van 100% breedte aan de knop. Ja een drie-class selector is ok als je het kan verantwoorden.

Ik wilde niet 100% breedte worden toegepast op de knop elke keer was het:

  • gebruikt op alle anywhere
  • aan de binnenkant van het aanmeldformulier
  • geplaatst in de side-bar

Ik wilde alleen maar 100% breedte te worden toegepast wanneer het was, zowel binnen het aanmeldformulier en in de sidebar. De beste manier om te verwerken dat was met een drie-class selector.

Ok, in werkelijkheid, ik zou waarschijnlijk gebruik maken van een ABEM stijl -verticalStack modifier les op de abonneren-form-element om de toepassing van de verticale stapel stijlen of misschien zelfs doen door middel van het element met behulp van query ‘ s EQCSS. Dit zou betekenen dat ik zou kunnen toepassen in de verticale stapel stijlen in meer situaties dan alleen wanneer het in de zijbalk. Omwille van een voorbeeld, maar ik heb het gedaan zoals context-gevoelige stijlen.

Nu we inzicht in de context gevoelige stijlen, laten we terug gaan naar die oorspronkelijke voorbeeld dat ik had en gebruik van een aantal context-gevoelige stijlen toe te passen dat de storende raster-kolom: 3 regel:

Zie de Pen Context-gevoelige 9 – context-gevoelige methode met mixins door Daniel Tonon (@daniel-tonon) op CodePen.

Context gevoelige stijlen leiden tot eenvoudiger HTML en templates logica met behoud van de mogelijkheid tot hergebruik van de onderliggende componenten. BEM één klas per selector filosofie niet toestaan dat dit gebeurt al.

Sinds context-gevoelige stijlen zijn voornamelijk bezig met de lay-out, afhankelijk van de omstandigheden, moet u over het algemeen gebruik ze wanneer je te maken hebt met deze CSS-eigenschappen:

  • Iets CSS grid verwante dat wordt toegepast op de onderliggende element (raster-kolom -, raster-rij enz.)
  • Iets flexbox verwante dat wordt toegepast op de onderliggende element (flex-grow flex-krimpen, lijn-zelf etc.)
  • marge-waarden groter dan 0
  • positie van andere waarden dan in vergelijking (samen met de bovenkant, linkerkant, onderkant en rechterkant om de eigenschappen)
  • transformatie als het wordt gebruikt voor het plaatsen als translateY

U kunt ook wilt deze eigenschappen in de context-gevoelige stijlen, maar ze zijn niet zo vaak nodig in een context gevoelige manier.

  • breedte
  • hoogte
  • padding
  • grens

Absoluut wel duidelijk, context-gevoelige stijlen zijn geen nesten omwille van de nesten. Je moet hen te zien alsof je het schrijven van een instructie in JavaScript.

Dus voor een CSS-regel als deze:

.ouder .element {
/* context-gevoelige stijlen */
}

U moet denken als u het schrijven van dit soort logica:

als lid.element in .parent) {
.element { /* context-gevoelige stijlen */ }
}

Ook begrijpen dat het schrijven van een regel die drie niveaus diep, zoals deze:

.grootouder .ouder .element {
/* context-gevoelige stijlen */
}

Moet worden gedacht, zoals u schrijft, logica, zoals deze:

if (
(.element in .ouder) &&
(.element in .grootouder) &&
(.van de ouders in .grootouder)
) {
.element { /* context-gevoelige stijlen */ }
}

Dus met alle middelen, het schrijven van een css selector die drie niveaus diep gaan als je echt denkt dat je nodig hebt dat niveau van specificiteit. Gelieve te begrijpen dat de onderliggende logica van de css die je schrijft hoor. Gebruik alleen een niveau van specificiteit die zinvol is voor de bijzondere styling die u probeert te bereiken.

En nogmaals, nog een keer, gewoon super duidelijk, nest niet omwille van de nesten!

Samenvatting

De methodologie achter de BEM naamgeving is iets dat ik van harte onderschrijven. Het laat css opgedeeld te worden in kleine hanteerbare onderdelen in plaats van het verlaten van css in een lompe puinhoop van hoge specificiteit dat is moeilijk te handhaven. De officiële syntax voor BEM heeft veel te wensen over hoor.

De officiële BEM-syntaxis:

  • Geen ondersteuning voor Atomic Ontwerp
  • Niet kan worden verlengd gemakkelijk
  • Duurt het langer voor je geest voor het verwerken van de groepering van de class namen
  • Is verschrikkelijk incompetent als het gaat om het beheren van de staat op grote componenten
  • Probeert je te stimuleren om gebruik enkele class selectors als dubbele class selectors leiden tot betere onderhoudbaarheid
  • Probeert om de naam-ruimte alles, zelfs wanneer de naamruimte veroorzaakt meer problemen dan het oplost.
  • Maakt HTML extreem opgeblazen wanneer goed gedaan

Mijn officieuze ABEM aanpak:

  • Maakt het werken met Atomic Ontwerp makkelijker
  • Bevrijdt de streep als een extra methode die kan worden gebruikt voor het groeperen van
  • Laat je geest voor het verwerken van de groepering van de class namen sneller
  • Is uitstekend op de behandeling staat op een grote component ongeacht het aantal sub-onderdelen van het
  • Stimuleert gecontroleerd specificiteit plaats van gewoon ronduit lage specificiteit te beperken team verwarring en het verbeteren van website onderhoud
  • Vermijdt de naamruimte als het niet nodig is
  • Houdt HTML-heel schoon met een minimum aan extra klassen toegepast op modules met behoud van alle van BEM voordelen

Disclaimer

Ik was niet de uitvinder van de term (één streepje voor de naam van de modifier) idee. Ik ontdekte dat het in 2016 uit het lezen van een artikel. Ik kan me niet herinneren die oorspronkelijk bedacht het idee. Ik ben blij te crediteren als iedereen weet dat het artikel.