Wprowadzenie do metodologii BEM

Opublikowany: 2022-03-11

Czym jest metodologia BEM?

Kiedy budujesz mniejsze strony internetowe, sposób organizacji stylów zwykle nie jest dużym problemem. Tworzysz swoje zwykłe pliki, piszesz wszystkie potrzebne CSS i to wszystko. Jednak w przypadku większych, bardziej złożonych projektów, sposób organizacji kodu staje się kluczowy . Struktura kodu jest jeszcze ważniejsza, jeśli pracujesz w zespole składającym się z wielu programistów front-end i back-end.

Metodologia BEM znacznie poprawi łatwość utrzymania kodu i przyspieszy proces rozwoju

Metodologia BEM znacznie poprawi łatwość utrzymania kodu i przyspieszy proces rozwoju
Ćwierkać

Obecnie istnieje wiele metodologii mających na celu zmniejszenie kodu CSS i uczynienie kodu CSS łatwiejszym w utrzymaniu. W tym artykule wyjaśnię i podam kilka przykładów jednego z nich: BEM. BEM to skrót od B lock E lement Modifier. Główną ideą przyświecającą temu jest przyspieszenie procesu rozwoju i ułatwienie pracy zespołowej programistów poprzez uporządkowanie klas CSS w niezależne moduły. Jeśli kiedykolwiek widziałeś nazwę klasy, taką jak header__form--search , oznacza to, że BEM działa. Tak, zajęcia można nazwać bardzo długimi, ale wszystkie są czytelne i zrozumiałe.

Zwróć uwagę, że najlepszą praktyką jest używanie BEM tylko z klasami, a nie z identyfikatorami, ponieważ klasy pozwalają w razie potrzeby powtarzać nazwy i tworzyć bardziej spójną strukturę kodowania. Ponadto, jeśli chcesz podzielić swoją witrynę na zorganizowane moduły, powinna składać się z tej samej struktury: bloku, elementu i modyfikatora. Gdzie każdy blok może mieć wiele elementów, a zarówno blok, jak i elementy mogą mieć wiele modyfikatorów. Zacznijmy jednak od podstawowej struktury BEM i wyjaśnijmy ją przykładami.

Blok

Blok reprezentuje obiekt w Twojej witrynie. Pomyśl o tym jako o większych strukturalnych fragmentach kodu. Najpopularniejsze bloki w każdej witrynie to nagłówek, treść, pasek boczny, stopka i wyszukiwanie. Bloki w BEM są zawsze punktem wyjścia do łączenia klas CSS. Spójrz na kilka przykładów bloków:

  • treść
  • jadłospis
  • formularz wyszukiwania
 .content {/* Styles */} .menu {/* Styles */} .search {/* Styles */}

Element

Element to komponent w bloku, który wykonuje określoną funkcję. Powinno to mieć sens tylko w kontekście swojego bloku:

  • artykuł z treścią
  • pozycja menu
  • pole wprowadzania wyszukiwania
 .content__article {/* Styles */} .menu__item {/* Styles */} .search__input {/* Styles */}

Modyfikator

Modyfikator to sposób, w jaki przedstawiamy wariacje bloku. Jeśli kiedykolwiek używałeś Bootstrapa, najlepszym przykładem są rozmiary przycisków. Rozmiary przycisków to tylko wariacje rozmiaru samego przycisku, co czyni go modyfikatorem:

  • artykuł polecany w treści
  • link do menu
  • pole wyszukiwania z ikoną lub bez
 .content__article--featured {/* Styles */} .menu__item--link {/* Styles */} .search__input--icon {/* Styles */}

Konwencje nazewnictwa

Podstawowym celem metodologii BEM jest uczynienie nazw selektorów CSS jak najbardziej informacyjnymi i przejrzystymi. Oryginalny styl BEM definiuje się w ten sposób:

Nazwa bloku jest zwykle pojedynczym słowem, takim jak .header , ale jeśli masz dłuższą definicję bloku, jest ona podzielona pojedynczym myślnikiem - :

 .lang-switcher {/* Styles */}

Nazwa elementu zaczyna się od podwójnego podkreślenia __ :

 .lang-switcher__flag {/* Styles */}

Nazwa modyfikatora zaczyna się od pojedynczego podkreślenia _ :

 .lang-switcher__flag_basic {/* Styles */}

W metodologii BEM jest tylko jedna bardzo krytyczna zasada - modyfikatora nie można używać poza kontekstem jego właściciela.

Przykład:

 .btn_big {/* Styles */}

Możesz użyć btn_big tylko wtedy, gdy zdefiniowano również nagłówek.

Zły przykład:

 <div class=”btn_big”>...</div>

Dobry przykład:

 <div class=”btn btn_big”>...</div>

Oprócz tych oryginalnych stylów BEM istnieją alternatywne schematy nazewnictwa, takie jak style Harry Roberts i CamelCase.

Przykład stylu Harry'ego Robertsa:

 .block-name__element-name--modifier-name {/* Styles */}

Przykład stylu CamelCase:

 .BlockName__ElementName_ModifierName {/* Styles */}

Jest też kilka innych, ale te dwa są najczęstsze. Osobiście jestem fanem konwencji nazewnictwa zaproponowanej przez Harrisa Robertsa, która ma następujące zasady:

  • Nazwiska są pisane małymi literami
  • Słowa w nazwach jednostek BEM są oddzielone myślnikiem -
  • Nazwa elementu jest oddzielona od nazwy bloku podwójnym podkreśleniem __
  • Modyfikatory logiczne są oddzielone podwójnymi myślnikami --
  • Modyfikatory typu klucz-wartość nie są używane

Powodem, dla którego ta konwencja nazewnictwa jest znacznie lepiej sformułowana niż inne, jest to, że możesz łatwo odróżnić element modyfikujący od innych. W oryginalnych konwencjach nazewnictwa modyfikator byłby zdefiniowany tak:

 .block__element_modifier {/* Styles */}

Ale jak widać, nie ma dużej różnicy między pojedynczym a podwójnym podkreśleniem. Z drugiej strony podwójny myślnik zapewnia czyste oddzielenie i od razu widać modyfikator:

 .block__element--modifier {/* Styles */}

Przykład BEM w różnych formatach

Należy pamiętać, że oprócz CSS, BEM jest również bardzo przydatny w organizowaniu plików JSON, XML, plików drzewa lub dowolnego formatu obsługującego zagnieżdżanie. Pomyśl o metodologii BEM jako o dobrym sposobie budowania interfejsu użytkownika.

HTML ustrukturyzowany w formacie BEM

Rozważmy następujący kod HTML, ustrukturyzowany w formacie BEM:

 <header class=”header”> <img class=”header__logo”> <form class=”header__search-from”> <input class=”header__search-from__input” type=”input”> <button class=”header__search-from__button” type=”button”> </form> <div class=”header__lang-switcher”></div> </header>

To samo można osiągnąć za pomocą formatu JSON i XML.

XML:

 <block:header> <block:logo/> <block:search-from> <block:input/> <block:button/> </block> <block:lang-switcher/> </block>

JSON:

 { block: 'header', content: [ { block: 'logo' }, { block: 'search-form', content: [ { block: 'input' }, { block: 'button' } ] }, { block: 'lang-switcher' } ] }

Organizacja systemu plików projektu BEM

W BEM bardzo ważne jest prawidłowe organizowanie plików. BEM zapewnia nie tylko świetną organizację klas CSS i sprawia, że ​​są one całkowicie zrozumiałe, ale także zapewnia bardzo łatwą w utrzymaniu strukturę plików. Weźmy przykładowy projekt, wykorzystujący technikę organizacji plików BEM z plikami SASS:

 blocks/ input/ __box/ --big/ input__box--big.scss input__box.scss button/ --big/ button--big.scss

Jak widać powyżej, wystarczy zobaczyć strukturę podfolderów w głównym folderze, wszystko jest jasne i uporządkowane. W ten sposób nie ma znaczenia, kto pracuje po tobie, czy też po kimś, ponieważ niezwykle łatwo jest postępować zgodnie z tym samym schematem.

Podział projektu BEM na platformy

Oprócz porządkowania plików przy użyciu technik metodologii BEM, możesz również zająć się bardziej szczegółowymi sprawami. Na przykład, jeśli budujesz projekt internetowy, który ma być w pełni responsywny, a klient określił, że niektóre bloki na telefonie komórkowym są zupełnie inne niż na urządzeniach stacjonarnych, najlepiej byłoby podzielić strukturę folderów BEM na platformy. Przykład organizacji przycisków na różnych platformach:

 common.blocks/ button/ button.scss desktop.blocks/ button/ buttons.scss mobile.blocks/ button/ button.scss

Zauważ, że jest to tylko przykład, jeśli chcesz zorganizować cały projekt za pomocą metodologii BEM. Drzewo plików ze strukturą BEM nie jest wymagane do prawidłowego korzystania z BEM, można używać BEM tylko w niektórych segmentach projektu. Do tej pory nie używałem tej ścisłej organizacji struktury plików BEM, w której każdy element i modyfikator ma swój plik. Zamiast tego tworzę strukturę plików dla bloków, które mają deklarację swoich elementów i modyfikatorów.

Organizacja drzewa projektu BEM

BEM w praktyce

Ponieważ znasz już konwencje nazewnictwa, zademonstruję metodologię BEM w praktyce. Załóżmy, że mamy w akcji ten kod HTML:

 <a class=”btn btn--big btn--primary-color” href=”#” title=”Title”> <span class=”btn__price”>$3.99</span> <span class=”btn__text”>Product</span> </a>

Z zastosowanymi następującymi znacznikami CSS:

 .btn__price {/* Styles */} .btn__text {/* Styles */} .btn--big {/* Styles */} .btn--primary-color {/* Styles */}

Nie daj się zwieść. W naszych dotychczasowych przykładach prawie zawsze mieliśmy blok, element i modyfikator, co nie zawsze musi mieć miejsce.

Załóżmy na przykład, że mamy blok o nazwie osoba . Osoba ma nogi i ręce, może to być również kobieta lub mężczyzna. Jeśli chcemy zdefiniować mężczyznę prawą ręką, będzie to wyglądać tak:

 .person--male__hand--right {/* Styles */}

Teraz możesz zobaczyć prawdziwe znaczenie BEM. Zdefiniowaliśmy osobę, której modyfikatorem jest płeć. Ponieważ nie ma znaczenia, czy dana osoba jest mężczyzną czy kobietą, ma rękę, a ręka jest elementem. I znowu, każda osoba może mieć prawą lub lewą rękę, co znowu jest modyfikatorem.

W innym przypadku, jeśli chcemy zdefiniować ogólną osobę jedną ręką, zrobimy to tak:

 .person__hand {/* Styles */}

Jak możesz zauważyć, gdy już oswoisz się z BEM, bardzo łatwo będzie za jego pomocą ustrukturyzować strukturę CSS i HTML.

Korzystanie z BEM z preprocesorami CSS

Osobiście nie wyobrażam sobie rozpoczęcia nowego projektu bez użycia jednego z preprocesorów CSS. Jak wszyscy wiecie, preprocesory to świetna rzecz i przynoszą nam wiele korzyści, a co najważniejsze doskonale współgrają z metodologią BEM.

Powiązane: Obejmując Sass: dlaczego powinieneś przestać używać Vanilla CSS

W poniższym przykładzie widać najbardziej typowy przykład BEM w połączeniu z SASS:

 .person { &__hand {/* Styles */} &__leg {/* Styles */} &--male { /* Styles */ &__hand { /* Styles */ &--left {/* Styles */} &--right {/* Styles */} } &__leg { /* Styles */ &--left {/* Styles */} &--right {/* Styles */} } } &--female { /* Styles */ &__hand { /* Styles */ &--left {/* Styles */} &--right {/* Styles */} } &__leg { /* Styles */ &--left {/* Styles */} &--right {/* Styles */} } } }

Kod SASS zostanie skompilowany w następujący CSS:

 .person__hand {/* Styles */} .person__leg {/* Styles */} .person--male {/* Styles */} .person--male__hand {/* Styles */} .person--male__hand--left {/* Styles */} .person--male__hand--right {/* Styles */} .person--male__leg {/* Styles */} .person--male__leg--left {/* Styles */} .person--male__leg--right {/* Styles */} .person--female {/* Styles */} .person--female__hand {/* Styles */} .person--female__hand--left {/* Styles */} .person--female__hand--right {/* Styles */} .person--female__leg {/* Styles */} .person--female__leg--left {/* Styles */} .person--female__leg--right {/* Styles */}

Jeśli chcesz pójść jeszcze dalej, możesz skorzystać z poręcznych mixinów SASS dla BEM:

 /// Block Element /// @param {String} $element - Element's name @mixin element($element) { &__#{$element} { @content; } } /// Block Modifier /// @param {String} $modifier - Modifier's name @mixin modifier($modifier) { &--#{$modifier} { @content; } }

Możesz go użyć w ten sposób:

 .person { @include element('hand') {/* Person hand */} @include element('leg') {/* Person leg */} @include modifier('male') { /* Person male */ @include element('hand') { /* Person male hand */ @include modifier('left') { /* Person male left hand */ } @include modifier('right') { /* Person male right hand */ } } } }

Co da następujący wynik CSS:

 .person__hand { /* Person hand */ } .person__leg { /* Person leg */ } .person--male { /* Person male */ } .person--male__hand { /* Person male hand */ } .person--male__hand--left { /* Person male left hand */ } .person--male__hand--right { /* Person male right hand */ }

Wiem, że najprawdopodobniej nie będziesz miał tak długiego przypadku użycia, ale jest to świetny przykład na to, jak BEM jest używany i dlaczego jest tak potężny, zarówno w małych, jak i dużych projektach.

Rozpoczęcie projektu BEM

Jak wyjaśniono w oficjalnej dokumentacji BEM, najłatwiejszym sposobem na rozpoczęcie własnego nowego projektu BEM jest użycie istniejącego repozytorium GIT. Po prostu użyj polecenia klonowania Git:

 $ git clone https://github.com/bem/project-stub.git

Następnie przejdź do nowo utworzonego katalogu i zainstaluj wszystkie zależności:

 $ npm install

Wszystkie wymagane zależności zostaną zainstalowane:

Zależności BEM

Zbuduj projekt za pomocą ENB:

 $ node_modules/.bin/enb make

Uruchom tryb serwera do programowania:

 $ node_modules/.bin/enb server

W rezultacie pojawia się następujący komunikat:

 Server started at 0.0.0.0:8080

Teraz oznacza to, że serwer działa. Możesz teraz sprawdzić wyniki pod tym adresem:

 http://localhost:8080/desktop.bundles/index/index.html

Jak widać, wiele elementów zostało już utworzonych, które są zdefiniowane w pliku bemjson , który znajduje się tutaj:

 project-stub/desktop.bundles/index/index.bemjson.js

Możesz zobaczyć i zbadać obecną strukturę pliku, który generuje cały ten kod HTML, który widzisz w pliku localhost index.html . Zamierzamy zmienić ten plik, aby otrzymać nasz projekt BEM „Osoba”, który wyjaśniliśmy w poprzednim rozdziale. Możesz usunąć (lub skomentować) cały kod z pliku index.bemjson.js i zastąpić go następującym:

 module.exports = { block: 'page', title: 'Person BEM', favicon : '/favicon.ico', head : [ { elem : 'meta', attrs : { name : 'description', content : '' } }, { elem : 'meta', attrs : { name : 'viewport', content : 'width=device-width, initial-scale=1' } }, { elem : 'css', url : 'index.min.css' } ], scripts: [{ elem : 'js', url : 'index.min.js' }], content: [ { block: 'person', content: [ { elem: 'male', content: [ { elem: 'leg', mods: {side: 'left'}, content: 'Male person leg -- left' }, { elem: 'leg', mods: {side: 'right'}, content: 'Male person leg -- right' }, { elem: 'hand', mods: {side: 'left'}, content: 'Male person hand -- left' }, { elem: 'hand', mods: {side: 'right'}, content: 'Male person hand -- right' } ] }, { elem: 'female', content: [ { elem: 'leg', mods: {side: 'left'}, content: 'Female person leg -- left' }, { elem: 'leg', mods: {side: 'right'}, content: 'Female person leg -- right' }, { elem: 'hand', mods: {side: 'left'}, content: 'Female person hand -- left' }, { elem: 'hand', mods: {side: 'right'}, content: 'Female person hand -- right' } ] }, ] } ] };

Teraz zostanie wygenerowany następujący kod HTML:

 <div class="person"> <div class="person__male"> <div class="person__leg person__leg_side_left"> Male person leg -- left </div> <div class="person__leg person__leg_side_right"> Male person leg -- right </div> <div class="person__hand person__hand_side_left"> Male person hand -- left </div> <div class="person__hand person__hand_side_right"> Male person hand -- right </div> </div> <div class="person__female"> <div class="person__leg person__leg_side_left"> Female person leg -- left </div> <div class="person__leg person__leg_side_right"> Female person leg -- right </div> <div class="person__hand person__hand_side_left"> Female person hand -- left </div> <div class="person__hand person__hand_side_right"> Female person hand -- right </div> </div> </div>

Jak widać z powyższego kodu, w tym scenariuszu został użyty domyślny schemat kodowania BEM, ponieważ używamy tylko domyślnych ustawień, które dostarczył nam BEM. Istnieje znacznie więcej poleceń i opcji, które można przeglądać i używać, takich jak tworzenie nowych stron, bloków lub modyfikowanie kodu HTML BEM. Nie będę się w to zagłębiał, a to wszystko można znaleźć w oficjalnej dokumentacji BEM.

Zalety i obawy BEM

Zalety i obawy

Zalety

  • BEM doskonale nadaje się do konserwacji. Ile razy musiałeś pracować nad kimś nad dużym projektem i boisz się czegoś zmienić bez upadku czegoś nieznanego? Korzystając z BEM, znasz dokładne przeznaczenie elementu i w jakim bloku może się on pojawić.
  • Nazwy klas są logiczne i intuicyjne, a każdy członek zespołu wie, co ten element robi na stronie. BEM daje każdemu w projekcie deklaratywną składnię, którą mogą udostępniać, dzięki czemu są na tej samej stronie.
  • BEM eliminuje zagnieżdżone selektory CSS. Każdy element HTML ma swoją własną klasę CSS, a po nazwie wiesz, do czego służy. Jeden selektor, który wszystkim rządzi .

Obawy i powszechne błędy

  • Nie wchodź zbyt głęboko w zagnieżdżanie. Główną zasadą powinno być nie używanie więcej niż dwóch poziomów rodzica i dziecka.
  • Uważaj, gdzie zaczynasz swój zakres blokowy. Częstym błędem jest tutaj to, że programista używa bloku, ale nie zdaje sobie sprawy, że w późniejszym etapie rozwoju ten sam blok będzie miał główny blok nadrzędny, który prawdopodobnie złamie regułę z zagnieżdżaniem.
  • Unikaj SASS @extend. Cytując Harry'ego Robertsa na ten temat:

Możesz utworzyć większą liczbę kombinacji w widoku, nie „wiązując” klas w Sass. HTML ma znacznie lepszą ścieżkę papierową, ponieważ możesz zobaczyć, jak każda klasa działa na fragmencie DOM. Twój CSS pozostaje znacznie szczuplejszy, ponieważ nie musisz tworzyć nowych klas zastępczych (lub klas manifestu, które je łączą) za każdym razem, gdy chcesz utworzyć nowy element interfejsu użytkownika.

Wniosek

Kiedy po raz pierwszy zobaczyłem schemat kodowania BEM, moją pierwszą myślą było:

Te zajęcia są po prostu za długie, by pisać i czytać.

Ale po spróbowaniu, teraz nie wyobrażam sobie rozpoczęcia nowego projektu bez jego użycia. Dla mnie BEM znacznie poprawił utrzymywanie mojego kodu i mogę z całą pewnością powiedzieć, że każdy programista, który zostanie „wrzucony” do projektu opartego na BEM, bardzo szybko nadrobi całą strukturę kodu.

Mimo to w sieciach społecznościowych toczy się wiele dyskusji na temat BEM. Niektórzy twierdzą, że BEM nie jest dobry, zastanawiając się, dlaczego powinni pisać klasy o tak długich nazwach, zamiast po prostu używać domyślnych zagnieżdżonych elementów HTML. Cóż, nikt nie mówi, że musisz lubić BEM, ale faktem jest, że większość programistów front-end przyjmuje go i uważa, że ​​jest niezwykle przydatny.

Powiązane: Zatrudnij najlepszych 3% niezależnych programistów front-end.