Znajomość metodologii BEM jest bardzo istotna. W artykule opisuję czym jest w kontekście CSS, jak ją stosować, przedstawiam praktyczny przykład oraz kilka zasad, który każdy powinien znać.
Czym jest metodologia BEM
BEM czyli Block Element Modifier to metodologia, której celem jest podzielenie interfejsu użytkownika w niezależne komponenty. Komponenty, które można ponownie wykorzystać w innym miejscu bez kopiowania istniejącego rozwiązania (zasada DRY). BEM to nie tylko konwencja nazewnictwa CSS. Podejście BEM pozwala opisać interfejs użytkownika niezależnie od wykorzystywanej technologii. To oznacza, że można definiować komponenty we wczesnej fazie projektowania lub prototypowania.
W tym artykule przedstawię jak ma się BEM do nazewnictwa klass w CSS i struktury HTML. Więcej na temat metodologii BEM będzie w kolejnym artykule.
Dlaczego warto używać akurat BEM?
Konwencja nazewnictwa klass w BEM posiada wiele zalet. Kilka z nich zostały zawarte w powyższym akapicie. Podsumowując, dlaczego warto stosować BEM?
- szybka nauka zasad BEM w kontekście CSS
- BEM to nie tylko CSS, to metodologia, która organizuje architekturę projektu
- jedno z najpopularniejszych rozwiązań, które często pojawia się w wymaganiach pracodawców
- łatwo utrzymywać i wprowadzać zmiany w kodzie
- podział elementów na moduły (np. łatwo przenieść kawałek kodu do innego projektu i ponownie go wykorzystać, zasada DRY)
- niski próg wejścia dla nowych osób w projekcie
BEM CSS to nie jest jedyna konwencja nazewnictwa. Warto zapoznać się z innymi propozycjami i zastosować tą, która najbardziej pasuje dla nas bądź do projektu.
Podstawowe pojęcia
Na początku warto zacząć od wyjaśnienia kilku pojęć.
Block
To jednostka, która sama w sobie określa swoje znaczenie. Jest bazą dla pozostałych elementów. Najczęściej to będzie element wrapujący dany komponent / moduł.
Przykład: header, menu, button, input
Element
Element, który jest bezpośrednio związany z Block. Nie może występować samodzielnie.
Przykład: header__title, menu__item
Modifier
Ta część odpowiada za zmianę wyglądu lub zachowania danego elementu (Block lub Element)
Przykład: button–primary, input–large, input–disabled
Jak stosować BEM?
Najważniejsze to podzielić stronę na niezależne komponenty. Jak tego dokonać? Jeśli można je w łatwy sposób przenieść do innego projektu to już będzie to komponent. Poniżej przykład podziału.

Kolorem czerwonym są oznaczone komponenty (block). Elementy (element) danego komponentu to kolor żółty, natomiast modyfikatory (modifier) wyglądu są zaznaczone na kolor zielony.
Na powyższym przykładzie można znaleźć następujące komponenty: header, nawigacja, logo, blok wyszukiwania.
Więcej o BEM CSS
Zasada pojedynczej odpowiedzialności
Zasada pojedynczej odpowiedzalności (ang. „Single responsibility principle„) mówi, że konkretna klasa powinna odpowiadać za wykonanie jednej operacji. Dzięki tej zasadzie kod jest bardziej elastyczny.
<header class="header">
<div class="logo"></div>
</header>
Klasa logo określa wygląd loga, nie określa np. położenia względem komponentu headera.
Źle:
.header {
background: #E7E7E7;
}
.logo {
width: 200px;
height: 200px;
border: 1px solid #EEE; // <--
margin-left: 100px; // <--
padding: 20px 0;
}
Dobrze:
.header {
background: #E7E7E7;
}
.logo {
width: 200px;
height: 200px;
border: 1px solid #EEE;
}
Poprawne rozwiązanie z uwzględnieniem dodatkowych styli można uzyskać, dzięki mieszaniu klas (poniżej).
Mieszanie klas CSS (Mixes)
Mieszanie klas pomaga w określeniu np. położenia danego elementu względem innego, dodania dodatkowych styli, które nie są związanie bezpośrednio z danym komponentem.
<header class="header">
<div class="header__logo logo"></div>
</header>
Blok logo otrzymał klasę header__logo, w której można określić reguły względem komponentu header. W klasie header__logo określamy wszystko to co ma związek z headerem, np. marginesy.
Źle:
.header {
background: #E7E7E7;
}
.logo {
width: 200px;
height: 200px;
border: 1px solid #EEE;
margin-left: 100px; // <--
padding: 20px 0; // <--
}
Dobrze:
.header {
background: #E7E7E7;
}
.header__logo {
margin-left: 100px;
padding: 20px 0;
}
.logo {
width: 200px;
height: 200px;
border: 1px solid #EEE;
}
Stylowanie grupowe
Stylowaniu wielu elementów naraz odbywało się za pomocą grupowania elementów, żeby nie duplikować tych samych reguł CSS.
Źle:
.article__content,
.widget__content,
.footer {
font-family: 'Open Sans';
font-size: 14px;
}
Dobrze:
.text {
font-family: 'Open Sans';
font-size: 14px;
}
Zamiast grupować elementy, należy stworzyć nową klasę, która określi jak ma wyglądać typografia w danych elementach (w powyższym przypadku). Następnie trzeba dodać klasę text do powyższych elementów HTML.
<div class="article__content text"></div>
<div class="widget__content text"></div>
<div class="footer text"></div>
Przykład wykorzystania BEM
Do wykonania jest zakodowanie projektu zgodnie z BEM CSS. Projekt został przesłany przez grafika. Na ten moment tylko część z nawigacją (dla uproszczenia przykładu). Projekt wygląda następująco:

Na początek należy stworzyć samą strukturę HTML.
Struktura HTML istnieje, kolejnym krokiem będzie nadanie klas CSS.
Tworzenie klas zgodnych z BEM
W powyższym przykładzie komponentem będzie nawigacja (block), zaczynająca się od znacznika ul. Otrzymała ona klasę .navigation. Elementy listy (element) otrzymały klasę .navigation__item. Linki (element) wewnątrz elementów list otrzymały klasę .navigation__link. Ostatni link na projekcie posiada dodatkowy element graficzny, który ma go wyróżnić. Contact otrzyma dodatkową klasę .navigation__link–star (modifier).
Kilka zasad, o których trzeba pamiętać
Element nie może być wewnątrz elementu
Ważne jest, aby nazwy klas były relatywnie krótkie.
Dobrze nadana klasa CSS
.navigation__link
Źle nadana klasa CSS
.navigation__item__link
Czyli podczas tworzenia klas CSS nie zwracamy uwagi na to, jak zagnieżdżony jest dany element. Ważny jest block, w tym przypadku navigation i element czyli link (pomijamy element item, który jest rodzicem elementu link).
W CSS tylko jedna klasa
Podczas stylowania ważne jest, aby opisywać jedną klasę (czyli waga konkretnego stylu powinna być jak najmniejsza).
Dobrze
.navigation {}
.navigation__link {}
Źle
.navigation {}
.navigation .navigation__link {}
Klasa CSS powinna opisywać funkcję, a nie wygląd
Podczas tworzenia klas CSS ważne jest, aby klasy opisywały funkcję danego elementu, a nie jego wygląd.
Dobrze
.button--primary {}
.button--secondary {}
Źle
.button--blue {}
.button--green {}
Jeśli na stronie zmieni się kolorystyka to nazwy klas również będą musiały się zmienić (w przypadku błędnego nazewnictwa), żeby nie wprowadzały w błąd.
Stylowanie tylko po klasach
Stylowanie elementów na stronie powinno odbywać się tylko po klasach CSS. Nie ma wtedy problemu ze specyficznością elementów (łatwiej stylować) oraz łatwo zmienić strukturę HTML (ponieważ style nie są powiązane z tagiem HTML). Wyjątkiem jest ustawianie domyślnych styli (reset.css).
Dobrze:
.navigation {}
.button {}
.button--primary {}
Źle:
#navigation {}
div.navigation {}
button.button {}
Ćwiczenie
Zachęcam do wykonania ćwiczenia, w którym wykonasz prostą stronę HTML oraz kilka komponentów, a następnie przeniesiesz je na inną podstronę HTML. W trakcie ponownego używania kodu HTML nie powinno dojść do zmiany CSS (wtedy kod komponentów nie jest gotowy do ponownego użytku, dopracuj stylowanie CSS i spróbuj ponownie).
Więcej informacji na temat BEM
Najlepszym źródłem informacji jest oficjalna dokumentacja metodologii BEM. Na stronie Introduction można znaleźć linki do materiałów na temat BEM.
Z polskiego podwórka mogę polecić artykuł NA FRONTENDZIE.
Więcej na temat metodologii BEM można przeczytać w artykule Comandeera.
Podsumowanie
BEM CSS posiada bardzo proste zasady, dlatego zastosowanie tej metodologii w codziennej pracy będzie również bardzo proste. Oczywiście wymaga to również praktyki, dlatego zachęcam do ćwiczeń. W przypadku problemów zachęcam do zadawania pytań w komentarzach czy szukania wsparcia w grupach tematycznych (np. na grupie https://www.facebook.com/groups/742940452405327/).
Podziel się opinią na temat artykułu lub napisz czy BEM jest już dla Ciebie zrozumiały.
Dodaj komentarz