Styl, konwencje i metodologie CSS – część 2. Sass, BEM, rscss, SMACSS, WTF?

css-green

Poziom zaawansowany

Ciąg dalszy tematyki poruszanej w części I. Dziś przyjrzymy się kolejnym metodologiom pisania CSS, takim jak BEM, rscss, SMACSS. Należy dodać, że metodologie możemy łączyć (np. OOCSS + BEM). O ile oczywiście ma to dla nas sens. Do rzeczy.

Metodologie CSS: SMACSS

Zaczniemy od SMACSS, choć od razu powiem, że nie pracowałem z tym przy realnym projekcie. Nie chodzi o to, że SMACSS jest kiepski. Ta metodologia po prostu mi nie odpowiada; z pewnością jest nie bez zalet, jednak niektóre jej detale dla mnie są irytujące. ALE może oczywiście odpowiadać innym.

SMACSS (Scalable and Modular Architecture for CSS), którego autorem jest Jonathan Snook, to style guide dla kodu CSS, które organizuje kod CSS według kategorii (Base, Layout, Module, State, Theme). Przyjrzyjmy się im bliżej.

Base

Style bazowe, ogólne. Ta grupa stylów odpowiada za wartości domyślne; domyślny wygląd elementów strony (marginesy, inputy, fonty, przykład: normalize.scss).

Layout

Style layoutu definiują wygląd i rozmieszczenie typowych dla stron i aplikacji WWW elementów, takich jak header, footer, sidebar. W SMACSS (i nie tylko) przyjęło się używać dla nich prefixu „l-„.

Module

Moduły w SMACSS to niezależne, re-używalne bloki kodu (UI), takie jak menu, search box, listy pozycji, etc. Można powiedzieć że są czymś w rodzaju bloków w BEM. Moduły zwykle znajdują się w kontenerach, wewnątrz elementów layoutu.

Założenie jest takie, że każdy moduł powinien być niezależny od pozostałych modułów. Powinien on też działać tak samo w każdym kontenerze, w jakim go umieścimy. Nie należy zatem tworzyć stylów uzależnionych od kontenera nadrzędnego.

Przykładem może być moduł menu:

...

.menu {
  background: #00a;
}

.menu h1 {
  font-size: 20px;
}

.menu .menu-item {
  border: 1px solid #000;
}
...

State

Style stanu po prostu określają wygląd stanu, w którym element może się znajdować, zależnie od sytuacji (hidden, expanded, etc). Zwijamy lub rozwijamy listę, najeżdżamy kursorem na element, i inne takie sytuacje.

Taka sytuacja

Taka sytuacja

Przykład:

<div class="menu is-expanded">
  ...
</div>

Zaleca się takie stany logiczne definiować z prefixem „is-„, np. is-active.

Theme

Themes zwykle znajdziemy w większych projektach, gdzie występują warianty (np. daily, nightly, sexy, sunny, etc), które określają różny wygląd (look and feel) dla elementów modułów i layoutów projektu.

SMACSS – przykład 1:

// Layouts
.l-default {}

// Modules 
.m-accordion {}

// States, mostly with prefix like "is-"
.is-active {}
.is-hidden {}

SMACSS – przykład 2 – mediaqueries:

.m-navigation {
  &:after {
    @media screen and (min-width: 767px) {
      content: '';
      display: inline-block;
      width: 100%;
    }
  }

  li {
    display: block;

    @media screen and (min-width: 767px) {
      float: left;
    }
  }
}

Zobacz także

Ten autor stworzył własny style guide na bazie SMACSS i OOCSS:

https://github.com/timhartmann/Scss-Styleguide

Z kolei autor SMACSS’a prowadzi stronę (https://smacss.com), gdzie możemy kupić lub przeczytać za darmo on-line, książkę poświęconą tej metodologii:

https://smacss.com/book


Chodźmy poznać kolejne metodologie. Nie jest też niespodzianką, że znajdziemy podobieństwa między nimi.

Metodologie CSS: rscss

Kolejnym podejściem jest to prezentowane przez rscss. W zasadzie jest to całkiem prosta metodologia, mniejsza w porównaniu do innych. Myślę że szybko można zacząć jej używać w praktyce. Godna polecenia. A jak nie wiesz od jakiej metodyki zacząć swoją przygodę i eksperymenty, śmiało można zacząć właśnie od rscss.

RSCSS – Reasonable System for CSS Stylesheet Structure to CSS style guide z prostymi założeniami. W rscss każdy „building block” jest komponentem. Obok komponentów rozróżniamy również: elementy, warianty oraz helpery.

Component – pojedynczy „kawałek” UI, re-używalny bez problemu w wielu miejscach aplikacji. Zawiera elementy.

Element – tagi HTML wewnątrz komponentów.

Variants – wariacje domyślnego wyglądu (look and feel) elementu.

Helpers – utils, narzędzia ogólnego przeznaczenia.

Tworząc nieduży front-end z Bootstrap, rscss oraz Slim templates (http://slim-lang.com), nie podobał mi się prefix zalecany dla helperów „_”. Dziwnie wyglądał kod np.:


.clearfix
._divided10

Obecnie, niezależnie od metodologii, moje helpery mają prefix h-, np.:

.h-divided10

Prosty przykład:

// ----------------------------------------------------------------
// Search form component.
// ----------------------------------------------------------------

.search-box {
  > .label {
    font-weight: 500;
    color: $color-base-blue;
  }

  > .field {
    // ...
  }

  // > input ...

  > .button {
    // ...
  }

  // Variants.
  &.-basic {
    color: $color-base-red;
  }

  &.-extended {
    color: $color-base-blue;
  }

  &.-hidden {
    display: none;
  }

}

Zachęcam do przeczytania:

http://rscss.io

https://github.com/rishabhp/rscss

Wydawnictwo Strefa Kursów

Metodologie CSS: BEM

Wreszcie pora na BEM. Skrót pochodzi od Block Element Modifier. Metodologia stworzona przez developerów z Yandex. Jest to w zasadzie dość proste podejście do tworzenia modularnego, re-używalnego kodu CSS.

BEM uwalnia nas od kaskadowości – aplikujemy te style, które są faktycznie potrzebne; bloki stałe nie zależą od innych elementów na stronie. W ten sposób o wiele łatwiej nie tylko utrzymywać i modyfikować kod, ale również przenosić (bloki) w inne miejsca, a nawet do innego projektu.

W założeniach BEM ma być:

– prosty – podstawą jest używanie BEM’owskiej konwencji nazewniczej

– modularny – niezależne bloki i selektory CSS

– elastyczny – mamy spore pole manewru, aby uczynić BEM wygodnym – tak jak lubimy

Warto również dodać, że BEM powstał dla projektów, które muszą być wypuszczone szybko, ale utrzymywane w długiej (long-term) perspektywie.

W BEM nasz kod widzimy jako:

– bloki – na przykład prosty, stylizowany przycisk, menu lub rozbudowany formularz – myślimy o bloku jako o komponencie re-używalnym w naszym projekcie (przykłady: header, container, menu, checkbox, input)

– elementy – poszczególne elementy, np. przycisk składa się z odnośnika, z tekstem oraz obrazkiem, formularz posiada elementy typu input, itd… (przykłady: menu item, list item, checkbox caption, header title)

– modyfikatory – to po prostu dodatkowe klasy, które modyfikują wygląd bloku lub elementu zależnie od stanu, np. aktywna pozycja menu po najechaniu kursorem (przykłady: disabled, highlighted, checked, fixed, size big, color yellow)

Metodologia BEM daje prostą i zrozumiałą strukturę. Style tworzymy w oparciu o konwencje nazw.

BEM – konwencja nazewnicza

W BEM istnieje pewna konwencja nazewnictwa klas CSS:

.block – pierwsze słowo w nazwie oznacza, że klasa dotyczy danego bloku

__element – dwa podkreślenia oznaczają, że dana klasa dotyczy elementu

–modifier – dwa myślniki definiuje modyfikator

Przykład:

// Blok
.block {}

// Element powiązany z blokiem
.block__element {}

// Modyfikator bloku
.block--modifier {}

// Modyfikator elementu
.block__element--modifier {}

To wszystko w kwestii podstawowej konwencji nazw. Naszym zadaniem jest po prostu zastanowić się, jak zorganizować style, aby elegancko i wygodnie odwzorować wymagania naszego projektu.

Można również powiedzieć, że BEM skłania nas do pomyślenia dwa razy, zanim skomplikujemy rzeczy bez potrzeby. Przykłady poniżej.

Blok reprezentuje obiekt, np.:
– osoba
– menu
– formularz logowania
– search box

itp.

Element to część bloku, która wykonuje określoną funkcję w jego kontekście, np.:
– głowa (osoby)
– pozycja menu
– przycisk lub label (formularza logowania)
– pole input (formularza szukania)

itp.

Modyfikator określa sposób reprezentacji wariacji bloku lub elementu, np.:
– wysoka / niska osoba
– active – podświetlona pozycja menu
– expanded / collapsed input – nieużywany input formularza szukania jest „krótki” lub „schowany”, jednak rozszerza się znacząco, gdy chcemy coś wyszukać

itp.

Przykłady:

// Menu
.menu {}
.menu__item {}
.menu__item--is-active {}

// Osoba
.person {}
.person__head {}
.person__hand {}
.person--female {}
.person__hand--left {}

W ten sposób wiemy, że głowa lub ręka odnosi się do kontekstu osoby. Po dekapitacji moglibyśmy mieć osobne klasy, np.:

.head {}
.left-hand {}

Tyle tylko, że głowa może należeć do osoby, ale również do psa, kota, małpy, itd. I w każdym przypadku wyglądać będzie inaczej 🙂

W Sass, cechy tego pre-procesora wspomagają znacząco pisanie kodu zgodnego z BEM.

Przykład – mixin:

@mixin button {
  padding: 0.6em 0.7em;
  // style ...
}

.button {
  @include button;
  background-color: $color-red;
}

.button--secondary {
  @include button;
  background-color: $color-green;
}

BEM – dobre praktyki

W pośpiechu możemy szybko zacząć pisać dziwaczne, bądź niepotrzebnie skomplikowane style. Dla BEM jest garść zasad, zdefiniowanych przez używających go programistów, tak aby unikać pułapek.

A. Stosujmy unikalne nazwy dla bloków (klas CSS).

B. Nie stosujmy selektorów ID, ani selektorów tagów HTML i/lub opartych o kaskadowość (selektory potomka)

Czyż nie lepiej używać selektora w stylu

.score–in-progress

zamiast

#scoreboard > li > b + span

C. Prefixed namespace. Czy stosować jeszcze jakieś prefixy? Jak najbardziej można.

Np. dla modyfikatorów stosujemy ‚is-‚ lub ‚has-‚:

.is-active {}
.is-hover {}
.is-dragged {}

Dla selektorów do pracy z JavaScript, możemy dodać prefix ‚js-‚:

.js-sortable {}
.js-is-active {}
.js-drag-and-drop {}

Dla helperów ‚h-‚, dla layoutów ‚l-‚, itp.

bem-types-prefixes

D. Don’t chain BEM elements – czyli jeśli np. nasz klasa wygląda tak:

.form__row__input

coś nie gra – lepiej powiązać „elementy-wnuki” bezpośrednio z blokiem, lub stworzyć dla nich po prostu osobny blok.

W BEM tworzymy własną, wirtualną przestrzeń nazw (namespace) dla określonych elementów, a dzięki temu unikamy konfliktów (np.: .nav__item {} oraz .menu__item {}, a nie .item {}).

Ale…

E. Uwaga na nesting (zagnieżdżanie). Chodzi o rozsądne zagnieżdżanie stylów, przede wszystkim – NIE za głębokie.

Przykład – źle:

.person {}
.person__head {}
.person__head__face {}
.person__head__face__eye {}
.person__head__face__eye__pupil {}

Przykład – dobrze:

.person {}
.person__head {}
.person__face {}
.person__eye {}
.person__pupil {}

Jak by nie patrzeć, lepiej gdy podwójne podkreślenie pojawia się w nazwie selektora jeden raz. A zatem piszemy

Block__Element–Modifier

A NIE

Block__Element__Element–Modifier

Np. jeśli mamy formularz ‚search-form’, a w nim div ‚search-form__content’, w którym są inputy, klasy dla inputów możemy zapisać w dwojaki sposób.

NIE piszemy

search-form__content__input

ALE

search-form__input

lub

search-form__content-input

Obie wersje są poprawne – rekomendowane przez dokumentację BEM.

Przykład – tego unikamy:

<div class="c-card">
  <div class="c-card__header">
    <!-- Grandchild -->
    <h2 class="c-card__header__title">Title text here</h2>
  </div>

  <div class="c-card__body">
    <img class="c-card__body__img" src="pic.png" alt="description">

  ...
</div>

Zobaczmy teraz ten sam kod, z poprawionymi selektorami.

Przykład – tak robimy:

<div class="c-card">
  <div class="c-card__header">
    <h2 class="c-card__title">Title text here</h2>
  </div>

  <div class="c-card__body">
    <img class="c-card__img" src="pic.png" alt="description">
  ...
</div>

Lepiej? No ba.

Podobnie:

<div class="block">
  <div class="block__elem1">
    <div class="block__elem2">
      <div class="block__elem3"></div>
    </div>
  </div>
</div>
.block {}
.block__elem1 {}
.block__elem2 {}
.block__elem3 {}

I tak dalej. Dlaczego? Budujmy nasze komponenty w bystry sposób. BEM (czy inna konwencja) ma pomagać nam, a nie nas ograniczać, lub komplikować proste rzeczy.

Tip: dla wieloczłonowych nazw składowych selektora (bloków, elementów lub modyfikatorów), używamy po prostu myślnika, np.:

block-name__my-element-name–foo-bar-modifier-name

Schemat nazewnictwa zalecany, choć nie jedyny: https://en.bem.info/methodology/naming-convention/#alternative-naming-schemes (BEM jest rozwijany już jakiś czas ;-))

Więcej o dobrych praktykach i pułapkach do poczytania tutaj:

https://www.sitepoint.com/working-bem-scale-advice-top-developers

https://www.smashingmagazine.com/2016/06/battling-bem-extended-edition-common-problems-and-how-to-avoid-them

Słowo o miksach

Nie zawsze musimy tworzyć selektory związane z blokiem. Jest to wysoce zalecane, jeśli myślimy, że nasz blok będzie re-używalny. Ale np. zakładając, że miksujemy style menu item z buttonem, a klasy ‚button’ i ‚active’ wszystkich naszych przycisków będą definiowane przez ten sam kod CSS (i to wystarczy), wtedy możemy stworzyć osobne klasy, więc napiszemy:

<li class="menu__item button active">

zamiast np.:

<li class="menu__item menu__button menu__button--active">

Jednak częściej zdarzy się, że elementy naszego projektu będą się zbyt różnić od siebie, i wtedy oczywiście trzymamy się zalecanej konwencji BEM.

A co z Bootstrap?

Framework Bootstrap nie stosuje konwencji BEM, więc możemy się obawiać paskudnego kodu, gdy pomieszamy style Bootstrapa oraz nasze – BEM-owe. Myślę że to żaden problem. Stosujemy zupełnie normalnie klasy zdefiniowane w Bootstrap, a nasze komponenty piszemy używając konwencji BEM. Gołym okiem widać, które są z Bootstrapa, a które nasze. Nie powinno być problemów.

BEM – dodatkowe zasoby

http://getbem.com

https://en.bem.info/methodology/quick-start

https://robots.thoughtbot.com/keeping-the-frontend-modular-with-bem

https://evilmartians.com/chronicles/bootstrap-an-intervention

http://mono.company/journal/frontend/learning-to-love-bem

https://mono.company/journal/frontend/overthinking-bem

https://m.alphasights.com/bem-i-finally-understand-b0c74815d5b0

BEM w praktyce – znakomite artykuły (zwłaszcza cz. 1 i 2):

https://zellwk.com/blog/css-architecture-1

https://zellwk.com/blog/css-architecture-2

https://zellwk.com/blog/css-architecture-3

Inne metodologie CSS

Poznaliśmy popularne metodologie CSS, ale z pewnością nie jedyne. Jest wiele innych, niektóre już nie rozwijane. Możemy również spodziewać się pojawienia zupełnie nowych.

Obok OOCSS czy BEMa, znajdziemy takie jak:

Atomic – https://www.smashingmagazine.com/2013/10/challenging-css-best-practices-atomic-approach

MaintainableCSS – https://maintainablecss.com/chapters/reuse

ecss – http://ecss.io

Ale można jeszcze inaczej.

Scoped CSS

Chyba po raz pierwszy użyłem scoped CSS w praktyce przy okazji (wspaniałego) frameworku Vue.js, gdzie scoped CSS świetnie sprawdza się przy stylowaniu komponentów:

https://vue-loader.vuejs.org/en/features/scoped-css.html

Potrzebne style będą zastosowane do bieżącego komponentu, a nie do całego dokumentu. Prosto i przyjemnie. Pisząc CSSy z użyciem BEM czy innej metodologii, również definiujemy scopes (zakresy), w sposób odpowiedni dla danej konwencji.

Zobacz także:

https://www.w3schools.com/TAgs/att_style_scoped.asp

https://davidwalsh.name/scoped-css

A może po prostu CSS modules?

Zyskują one na popularności. Mogą być dobrym rozwiązaniem dla kogoś, kto pracuje z innymi technologiami i/lub nie chce adaptować tych wszystkich Sass’ów, BEM’ów, itd.

Moduły CSS dostępne są np. w css-loaderze dla Webpacka (ktokolwiek jeszcze nie korzystał z webpacka, niech spróbuje ;-)). Style (jako moduły) mogą elegancko zostać załadowane do projektu z konwencji modułów ES6, np:

import styles from './LoginForm.css';

Style z modułu stają się dostępne, a można ich użyć w taki sposób:

  <div class="${styles.root}">

Zasoby

https://css-tricks.com/css-modules-part-1-need

https://www.universalmind.com/blog/css-modules-solving-the-challenges-of-css-at-scale

https://www.triplet.fi/blog/practical-guide-to-react-and-css-modules

https://glenmaddern.com/articles/css-modules

https://nafrontendzie.pl/css-modules-kolejny-sposob-style-react

https://www.sitepoint.com/understanding-css-modules-methodology

https://x-team.com/blog/css-modules-a-new-way-to-css

https://x-team.com/blog/css-modules-rethinking-the-past

https://github.com/css-modules/css-modules

Idąc dalej, możemy dość do CSS styled components (zobacz także: React).

I jeszcze więcej zasobów…

Metodologie CSS – do poczytania

http://helion.pl/view/8448w/sasspp.htm

https://www.leemunroe.com/css-sass-scss-bem-less

http://timhartmann.net/frontend-development/scss-styleguide-with-bem-oocss-smacss

https://medium.com/peergrade-io/structuring-css-in-large-projects-37f1695f5ec8

https://sass-guidelin.es

http://helion.pl/view/8448w/iojak.htm

Metodologie CSS – podsumowanie

Kaskadowe arkusze stylów są problematyczne, ponieważ są… kaskadowe. Daje się to we znaki prędzej czy później, w miarę rozwoju projektu. Metodologie CSS pozwalają organizować style w lepszy, spójny sposób, rozwiązując typowe bolączki CSS.

Nikt niczego nikomu nie powinien narzucać. Potencjalnych rozwiązań jest cała gama, wiec każdy może znaleźć coś odpowiedniego dla siebie. Podejścia do pisania CSS powinny skupiać się na spójnej strukturze plików i folderów, a także konwencji nazw. Ponadto powinno się dążyć do opracowywania CSS (oraz JS) w sposób modularny, tak aby można było utrzymywać, importować i używać moduły zależnie od potrzeb.

Tak wygląda też sprawa JavaScript i AMD. W najświeższym wydaniu korzystamy po prostu ze znakomitego podejścia, oferowanego przez ES6 modules. Nie jest jeszcze wspierane w przeglądarkach bezpośrednio, ale żaden problem – zaprzęgamy do pracy Babel (transpiler) oraz webpack (module bundler) i gotowe.

Więc naprzód! Ku przyszłości 🙂

Programista WWW i aplikacji mobilnych z wieloletnim doświadczeniem. Bloger 🙂 Anty-lewak 🙂 Pasjonat programowania, nowych technologii, a także sportu i motoryzacji.

Twitter LinkedIn Google+ Skype Xing 

Podaj dalej: Share on Facebook12Tweet about this on TwitterShare on Google+0Share on LinkedIn0Share on Tumblr0Digg thisEmail this to someonePin on Pinterest0
Możesz skomentować leave a response, lub podać trackback z własnej strony.
  • Gdyby się przyjrzeć konwencjom nazewniczym istniejącym w BEM, to ta wymieniona w artykule jest bez wątpienia najpopularniejszą, niemniej – nie kanoniczną. Oryginalna konwencja bowiem do oddzielania modyfikatorów używa pojedynczego podkreślnika (_). Dodatkowo zabrania używania modyfikatorów poza blokami (więc .active odpada w przedbiegach) i całkowicie omija temat prefiksów w modyfikatorach (chociaż modyfikatory typu boolean nie mają w dokumentacji przedrostka „is”).

    Jeśli chodzi o prefiksy dla bloków, to na dobrą sprawę zdążyło się to rozwinąć w całkowicie osobną metodologię: SUIT CSS (https://suitcss.github.io/ ).

    Co do preprocesorów: wydaje mi się, że dołączanie mixinu button do .button–secondary jest całkowicie zbędne. Ta klasa nie może istnieć bez kontekstu, zatem wystąpi wraz z klasą .button. Nie widzę zatem powodu, dla którego te style są duplikowane.

    Ogólnie wolę rozpatrywać BEM na nieco innym poziomie niż po prostu jako sposób na pisanie efektywnego CSS-a. Raczej upatruję w nim dość złożoną warstwę abstrakcji na DOM, wręcz DSL → https://comandeer.github.io/blog/html-css/javascript/daj-sie-poznac-2017/2017/05/12/bem-jako-architektura.html

    Jeśli natomiast chodzi o scoped styles, tak naprawdę ten mechanizm został ze standardu usunięty (http://w3c.github.io/html/document-metadata.html#the-style-element – brak atrybutu [scoped]). Na dobrą sprawę nigdy nie miał on żadnego realnego wsparcia (http://caniuse.com/#feat=style-scoped ). Co prawda Vue.js go używa, ale wypada pamiętać, że format plików z komponentami tego frameworka tak naprawdę nie jest HTML-em. Występuje tu jedynie zbieżność nazw i na tym podobieństwo rozwiązania zaproponowanego w standardzie HTML a rozwiązaniem z Vue.js się kończy. Niemniej jest możliwość tworzenia prawdziwych scoped styles, przy pomocy Shadow DOM. I w tym wypadku nie jest to żadne udawanie, tylko faktycznie prawdziwe style lokalne.

  • Łukasz Polowczyk

    `.person–female__hand {}`
    Czy to ma sens?
    Modyfikator jest do bloku, więc gdy tego używamy, to dodajemy do bloku `.person–female` ale to jeszcze nie dotyczy elementu `__hand`, więc trzeba też dodać drugą klasę do samego elementu `.person–female__hand`. Czyli musimy dodać dwie dodatkowe klasy, żeby coś zmodyfikować.
    Nie wydaje się to bez sensu?
    Nie lepiej jednak:
    `.person–female .person__hand`
    I wtedy wystarczy dodać `.person–female` do bloku, żeby coś zmodyfikować? A już nie trzeba dodawać drugiej klasy, czyli `.person–female__hand` do elementu?

    Wyjaśnij mi to dobrze.

    • To tylko przykłady nazw…Przecież chodzi o definiowanie w sposób, aby miało to sens dla naszego projectu =>

      Mamy blok ‚person’, i definiujemy co nam potrzeba. Być może starczy tylko blok ‚person’ oraz ‚person__hand’, jeśli w naszym projekcie ręka lewa wygląda inaczej od prawej, piszemy ‚person__hand–left’, ‚person__hand–right’…

      Może być blok ‚person-male’, i ‚person-female’, dla nich elementy ‚__hand’ oraz modyfikatory ‚–left’, ‚–right’. Cokolwiek nam poterzba. To jest po to, aby ułatwiać nam odwzorowanie obiektów naszego projektu, i BEM jest do tego świetny. Ale są też inne konwencje.

      Idziemy od góry, jeśli person jest zbyt ogólny (zbyt wiele różnic między przypadkami male i female) tworzymy zamiast tego person-male, person-female. Itd. Od nas zależy jak sobie zorganizujemy style. W Sass części wspólne (aby się nie powtarzać – DRY), możemy sobie zdefiniować w placeholderach czy też mixinach i dołączyć do klas, a resztę czyli różnice – kodujemy w poszcz. klasach. BEM prosto mówi nam jaką konwencję stosować do nazw. ALE jak sugeruje też Comandeer, można z tym pójść znacznie dalej – spojrzenie na BEM jako DSL (y).

      • Łukasz Polowczyk

        Nie do końca wiem o co chodzi.
        Ja ogólną zasadę i kwestię dopasowania do potrzeb rozumiem, ale to o co mi chodzi to kwestia uproszczenia tego konkretnego przykładu, bo nie wiem czy ten konkretny przykład jest uzasadniony, czy może ja coś źle rozumiem.

        Tutaj modyfikator tylko w divie nadrzędnym:
        `[div class=”person person–female”]
        [div class=”person__hand”][/div]
        [/div]

        .person–female person__hand {}`

        Vs. tutaj modyfikator i tu i tu, chociaż używany tylko w divie podrzędnym:

        `[div class=”person person–female”]
        [div class=”person__hand person–female__hand”][/div]
        [/div]

        .person–female__hand {}`

        I jak jest tylko jeden element podrzędny, to nic, ale jak by było więcej, to by trzeba:
        `[div class=”person person–female”]
        [div class=”person__hand person–female__hand”][/div]
        [div class=”person__leg person–female__leg”][/div]
        [div class=”person__head person–female__head”][/div]
        [/div]

        .person–female__hand {}
        .person–female__leg {}
        .person–female__head {}`

        Zamiast:
        `[div class=”person person–female”]
        [div class=”person__hand”][/div]
        [div class=”person__leg”][/div]
        [div class=”person__head”][/div]
        [/div]

        .person–female person__hand {}
        .person–female person__leg {}
        .person–female person__head {}`

        I w razie, gdyby chcieć dynamicznie zmienić płeć(modyfikator), to trzeba to zrobić dla elementu nadrzędnego oraz dla każdego elementu podrzędnego(czyli w czterech miejscach), zamiast zmienić tylko w elemencie nadrzędnym z `person–female` na `person–male`(czyli w jednym miejscu).

        Czy może coś źle rozumiem?

        • Myślę ze wystarczy poczytać, popatrzeć na przyklady z docsów https://en.bem.info/methodology/quick-start/

          i popisać, żeby zrozumieć jak używac BEM, i ogólnie – po co go używać…

          Co ma do rzeczy przykład – to tylko przykład. Miał pokazać konwencje nazw(!)

          Może być uzasadniony w jednym projekcie i kompletnie bez sensu w innym, zależnie od jego specyfiki.

          W bemie staramy sie nie pisac bajzlu ‚person person–female’ , tak samo to nie ma większego sensu:
          [div class=”person person–female”]
          [div class=”person__hand person–female__hand”][/div]
          [/div]

          Zwyczajnie – przykład „person.scss”

          // Blok
          .person {
          // Style dla klasy person…
          border: solid 1px #d00;
          // … i inne style dla bloku – ogólne

          // Element
          &__hand {
          // style dla hand
          }

          &__hand–left {
          // lewa ręka
          }

          &__hand–right {
          // prawa ręka
          }

          }

          Jak tu teraz dodać male / female? Jak nam pasuje, ja bym zrobił tak: wywalamy hand–left i hand–right i piszemy:

          // Blok
          .person {
          // Style dla klasy person…
          border: solid 1px #d00;
          // … i inne style dla bloku – ogólne

          // Element
          &__hand-male { // JEDEN myślnik, to nazwa elementu, dla modyfikatora – podwójny myślnik…
          // style dla hand faceta
          }

          &__hand-female {
          // style dla hand kobiety
          }

          &__hand–left {
          // lewa ręka
          }

          &__hand–right {
          // prawa ręka
          }

          }

          To stworzy nam klasy typu person__hand-male, czy też person__hand–left. Oczywiście mówimy o Sass a nie czystym CSS – wtedy wszystko trzeba pisać ręcznie. Sass bardzo pomaga pisać BEMy i warto go używać 😉

          Piszemy potem np:

          Html dla reki kobiecej, lewej…

          Itd. Mega prosta sprawa.

          BTW piszę na szybko bo mam mega ograniczony czas, więc gdzie sie mogla wkrasc literowka – ja tylko podaje przyklady. Nie wklejam kodu realnego projetu – te mozna znalezc w open source.

          Dodatkowo, na co dzien pisze w Rails w IDE RubyMine, używajac Sass (składnia SCSS!) i IDE obecnie nie ma problemów z auto-uzupełnianiem / sugerowaniem klas, któremy napisaliśmy w BEMie.

          Możemy też inaczej np. zamiast modyfikatora &__hand–left towrzymy element &__hand-left i modyfikator &__hand–male / –female… Cokolwiek nam trzeba.

          Możemy np nie tworzyć klasy person, tylko person-male i person-female, i w nich poszczególne elementy i modyfikatory. Części wspólne jako mixiny lub placeholdery jak wspominałem. Itd.

          Można się zagłębiać, ALE dobre praktyki wskazują nie pisać zbyt mocno zagnieżdżonych klas. Płytko. O tym wspomniałem już w arcie, i dokumentacja BEM od jego autorów wyjaśnia wszystko elegancko. Sugeruje pewne rzeczy, ale też przypomina że mamy elastyczność.

          Chyba nie mam tu nic wiecej do dodania.