Introdução à Metodologia BEM

Publicados: 2022-03-11

O que é a Metodologia BEM?

Quando você está construindo sites menores, como você organiza seus estilos geralmente não é um grande problema. Você cria seus arquivos usuais, escreve todo o CSS necessário e pronto. No entanto, quando se trata de projetos maiores e mais complexos, a forma como você organiza seu código se torna crucial . A forma como o código é estruturado é ainda mais importante se você estiver trabalhando em uma equipe composta por vários desenvolvedores front-end e back-end.

A metodologia BEM melhorará massivamente a manutenção do código e acelerará o processo de desenvolvimento

A metodologia BEM melhorará massivamente a manutenção do código e acelerará o processo de desenvolvimento
Tweet

Hoje, existem muitas metodologias com o objetivo de reduzir o código CSS e tornar seu código CSS mais sustentável. Neste artigo, vou explicar e dar alguns exemplos de um deles: BEM. BEM significa B lock Element Modifier . A ideia principal por trás disso é acelerar o processo de desenvolvimento e facilitar o trabalho em equipe dos desenvolvedores organizando classes CSS em módulos independentes. Se você já viu um nome de classe como header__form--search , isso é BEM em ação. Sim, as classes podem ser nomeadas muito longas, mas todas são legíveis e compreensíveis.

Observe que a prática recomendada é usar BEM apenas com classes, e não com IDs, pois as classes permitem que você repita nomes, se necessário, e crie uma estrutura de codificação mais consistente. Além disso, se você quiser dividir seu site em módulos organizados, ele deve consistir na mesma estrutura: bloco, elemento e modificador. Onde cada bloco pode ter vários elementos, e tanto o bloco quanto os elementos podem ter vários modificadores. No entanto, vamos começar com a estrutura básica do BEM e explicá-la com exemplos.

Bloquear

Um bloco representa um objeto em seu site. Pense nisso como pedaços estruturais maiores do seu código. Os blocos mais comuns em todos os sites hoje são cabeçalho, conteúdo, barra lateral, rodapé e pesquisa. Blocos no BEM são sempre um ponto de partida para encadear suas classes CSS. Veja alguns exemplos de blocos:

  • um conteúdo
  • um menu
  • um formulário de pesquisa
 .content {/* Styles */} .menu {/* Styles */} .search {/* Styles */}

Elemento

Um elemento é um componente dentro do bloco que executa uma função específica. Só deve fazer sentido no contexto de seu bloco:

  • um artigo de conteúdo
  • um item de menu
  • um campo de entrada de pesquisa
 .content__article {/* Styles */} .menu__item {/* Styles */} .search__input {/* Styles */}

Modificador

Um modificador é como representamos as variações de um bloco. Se você já usou o Bootstrap, o melhor exemplo seriam os tamanhos dos botões. Os tamanhos dos botões são apenas variações de tamanho do próprio botão, o que o torna o modificador:

  • um artigo em destaque de conteúdo
  • um link de cardápio
  • um campo de pesquisa com ou sem ícone
 .content__article--featured {/* Styles */} .menu__item--link {/* Styles */} .search__input--icon {/* Styles */}

Convenções de nomenclatura

O objetivo principal da metodologia BEM é tornar os nomes dos seletores CSS tão informativos e transparentes quanto possível. O estilo BEM original é definido desta forma:

O nome do bloco geralmente é uma única palavra como .header , mas se você tiver uma definição de bloco mais longa, ela será dividida com um único hífen - :

 .lang-switcher {/* Styles */}

O nome do elemento começa com sublinhado duplo __ :

 .lang-switcher__flag {/* Styles */}

O nome do modificador começa com um único sublinhado _ :

 .lang-switcher__flag_basic {/* Styles */}

Existe apenas uma regra muito crítica na metodologia BEM - um modificador não pode ser usado fora do contexto de seu proprietário.

Exemplo:

 .btn_big {/* Styles */}

Você pode usar btn_big somente se o cabeçalho também estiver definido.

Mau exemplo:

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

Bom exemplo:

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

Além desses estilos BEM originais, existem esquemas de nomenclatura alternativos como os estilos Harry Roberts e CamelCase.

Exemplo de estilo Harry Roberts:

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

Exemplo de estilo CamelCase:

 .BlockName__ElementName_ModifierName {/* Styles */}

Existem alguns outros também, mas esses dois são os mais comuns. Pessoalmente, sou fã da convenção de nomenclatura proposta por Harris Roberts, que tem as seguintes regras:

  • Os nomes são escritos em minúsculas
  • As palavras dentro dos nomes das entidades BEM são separadas por um hífen -
  • Um nome de elemento é separado de um nome de bloco por um sublinhado duplo __
  • Os modificadores booleanos são delimitados por hífens duplos --
  • Modificadores de tipo de valor-chave não são usados

A razão pela qual essa convenção de nomenclatura é muito melhor formada do que outras é que você pode distinguir facilmente o elemento modificador de outros. Nas convenções de nomenclatura originais, o modificador seria definido assim:

 .block__element_modifier {/* Styles */}

Mas como você pode ver, não há muita diferença entre um sublinhado simples e duplo. Por outro lado, o hífen duplo fornece uma separação limpa e você pode ver o modificador instantaneamente:

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

Exemplo BEM em Diferentes Formatos

Observe que, além do CSS, o BEM também é muito útil para organizar seus arquivos JSON, XML, árvore ou qualquer formato que suporte aninhamento. Pense na metodologia BEM como uma boa maneira de construir sua interface do usuário.

HTML estruturado no formato BEM

Vamos considerar o seguinte HTML, estruturado no formato 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>

O mesmo pode ser alcançado usando o formato JSON e 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' } ] }

Organização do sistema de arquivos de um projeto BEM

No BEM, é fundamental organizar seus arquivos de maneira correta. O BEM não apenas fornece uma ótima organização de classes CSS e as torna completamente compreensíveis, mas também oferece uma estrutura de arquivos muito sustentável. Vamos dar um exemplo de projeto, usando a técnica de organização de arquivos BEM com arquivos SASS:

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

Como você pode ver acima, apenas vendo a estrutura de subpastas dentro da sua pasta principal, tudo fica claro e organizado. Dessa forma, não faz diferença quem está trabalhando atrás de você ou se você está trabalhando atrás de alguém, porque é incrivelmente fácil seguir o mesmo padrão.

Dividindo o projeto BEM em plataformas

Além de apenas organizar seus arquivos usando técnicas da metodologia BEM, você também pode entrar em coisas mais específicas. Por exemplo, se você estiver construindo um projeto da web que será totalmente responsivo e o cliente especificou que alguns blocos no celular são totalmente diferentes dos dispositivos desktop, seria melhor dividir sua estrutura de pastas BEM em plataformas. Exemplo de organização de botões em várias plataformas:

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

Observe que este é apenas um exemplo se você deseja organizar todo o seu projeto usando a metodologia BEM. Árvore de arquivos com estrutura BEM não é obrigatória para usar BEM corretamente, você pode usar BEM apenas em alguns segmentos do projeto. Até agora, não tenho usado essa organização estrita de estrutura de arquivos BEM, onde cada elemento e modificador tem seu arquivo criado. Em vez disso, estou apenas criando uma estrutura de arquivos para blocos que possuem uma declaração de seus elementos e modificadores.

Organização em Árvore de um Projeto BEM

BEM na prática

Como você já está familiarizado com as convenções de nomenclatura, demonstrarei a metodologia BEM na prática. Digamos que temos este código HTML em ação:

 <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>

Com a seguinte marcação CSS aplicada:

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

Agora, não se engane. Em nossos exemplos até agora, quase sempre tivemos um bloco, um elemento e um modificador, o que nem sempre precisa ser o caso.

Por exemplo, digamos que temos um bloco chamado person . Uma pessoa tem pernas e mãos, também pode ser do sexo feminino ou masculino. Se quisermos definir uma pessoa do sexo masculino com a mão direita, ficará assim:

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

Agora você pode ver o real significado do BEM. Definimos uma pessoa cujo modificador é um gênero. Como não importa se uma pessoa é homem ou mulher, ela tem uma mão, e a mão é um elemento. E, novamente, cada pessoa pode ter a mão direita ou esquerda, que é novamente um modificador.

Em outro caso, se quisermos definir pessoa geral com uma única mão, faremos assim:

 .person__hand {/* Styles */}

Como você pode notar, uma vez que você se familiarize com o BEM, é muito fácil estruturar sua estrutura CSS e HTML com ele.

Usando BEM com pré-processadores CSS

Pessoalmente, não consigo imaginar iniciar nenhum novo projeto sem usar um dos pré-processadores de CSS. Como todos sabem, os pré-processadores são ótimos e estão nos proporcionando muitos benefícios e, o mais importante, são uma combinação perfeita com a metodologia BEM.

Relacionado: Abraçando o Sass: Por que você deve parar de usar Vanilla CSS

No exemplo a seguir, você pode ver o exemplo mais típico de BEM, em combinação com 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 */} } } }

O código SASS será compilado no seguinte 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 */}

Se você quiser ir ainda mais longe, você pode usar um prático mixins SASS para 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; } }

E você pode usar assim:

 .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 */ } } } }

Que produzirá a seguinte saída 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 */ }

Eu sei que provavelmente você não terá um caso de uso por tanto tempo, mas este é um ótimo exemplo de como o BEM é usado e por que ele é tão poderoso, tanto em projetos de pequena quanto de grande escala.

Iniciando seu projeto BEM

Conforme explicado na documentação oficial do BEM, a maneira mais fácil de iniciar seu novo projeto BEM é usar o repositório GIT existente. Basta usar o comando Git clone:

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

Em seguida, vá para um diretório recém-criado e instale todas as dependências:

 $ npm install

Todas as dependências necessárias serão instaladas:

Dependências BEM

Construa o projeto usando ENB:

 $ node_modules/.bin/enb make

Execute um modo de servidor para desenvolvimento:

 $ node_modules/.bin/enb server

Como resultado, aparece a seguinte mensagem:

 Server started at 0.0.0.0:8080

Agora, isso significa que o servidor está funcionando. Agora você pode conferir os resultados neste endereço:

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

Como você pode ver, existem muitos elementos já criados que são definidos dentro do arquivo bemjson que está localizado aqui:

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

Você pode ver e explorar a estrutura atual do arquivo que está gerando todo esse HTML, que você vê em seu arquivo localhost index.html . Vamos alterar este arquivo para obter nosso projeto BEM “Person” que explicamos em um capítulo anterior. Você pode remover (ou comentar) todo o código do arquivo index.bemjson.js e substituí-lo por este:

 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' } ] }, ] } ] };

Agora, o seguinte HTML será gerado:

 <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>

Como você pode ver no código acima, o esquema de codificação BEM padrão foi usado neste cenário, pois estamos apenas usando as configurações padrão que o BEM nos forneceu. Há muito mais comandos e opções que você pode explorar e usar, como criar novas páginas, blocos ou modificar BEM HTML. Não vou me aprofundar muito nisso, e tudo pode ser encontrado na documentação oficial do BEM.

Vantagens e preocupações do BEM

Vantagens e preocupações

Vantagens

  • BEM é excelente para manutenção. Quantas vezes você teve que trabalhar atrás de alguém em um projeto de grande escala e está com muito medo de mudar alguma coisa sem que algo desconhecido desmorone? Ao usar o BEM, você sabe a finalidade exata do elemento e em qual bloco ele pode aparecer.
  • Os nomes das classes são lógicos e intuitivos, e cada membro da equipe sabe o que esse elemento faz no site. O BEM fornece a todos em um projeto uma sintaxe declarativa que eles podem compartilhar para que estejam na mesma página.
  • BEM elimina seletores CSS aninhados. Cada elemento HTML tem sua própria classe CSS e, pelo nome, você sabe qual é o seu propósito. Um seletor para governá-los todos .

Preocupações e erros comuns

  • Não vá muito fundo no aninhamento. A regra principal deve ser não usar mais de dois níveis de pai e filho.
  • Tenha cuidado com onde você inicia seu escopo de bloco. Um erro comum aqui é quando um desenvolvedor está usando o bloco, mas ele não está percebendo que no ponto posterior do desenvolvimento esse mesmo bloco terá o bloco pai principal que possivelmente quebrará a regra com o aninhamento.
  • Evite SASS @extend. Para citar Harry Roberts sobre isso:

Você pode criar um número maior de combinações na visão não 'amarrando' classes no Sass. O HTML tem uma trilha de papel muito melhor, pois você pode ver todas as classes atuando em um pedaço do DOM. Seu CSS fica muito mais fino, pois você não precisa criar novas classes de espaço reservado (ou as classes de manifesto que as combinam) toda vez que quiser criar uma nova parte da interface do usuário.

Conclusão

Quando vi o esquema de codificação BEM pela primeira vez, meu primeiro pensamento foi:

Essas classes são muito longas para escrever e ler.

Mas depois de experimentar, agora não consigo imaginar começar um novo projeto sem usá-lo. Para mim, o BEM melhorou enormemente a capacidade de manutenção do meu código, e posso dizer com certeza que todo desenvolvedor que será “lançado” no projeto baseado em BEM alcançará rapidamente toda a estrutura do código.

Apesar de tudo isso, há muita discussão nas redes sociais sobre o BEM. Alguns dizem que o BEM não é bom, imaginando por que eles deveriam escrever classes de nomes tão longos em vez de apenas usar elementos HTML aninhados padrão. Bem, ninguém diz que você deve gostar do BEM, mas o fato é que a maioria dos desenvolvedores front-end o adotam e o consideram extraordinariamente útil.

Relacionado: Contrate os 3% melhores desenvolvedores front-end freelance.