Heim  >  Artikel  >  Web-Frontend  >  Alles, was Sie über die BEM-CSS-Architektur wissen müssen

Alles, was Sie über die BEM-CSS-Architektur wissen müssen

DDD
DDDOriginal
2024-10-02 06:12:02278Durchsuche

Ich habe diesen Artikel geschrieben, um Fragen zu BEM zu beantworten, die im Allgemeinen nicht gestellt werden, aber das Fehlen von Antworten wirkt sich auf die Entwicklung und das Verständnis der Architektur aus.

Dieser Artikel richtet sich nicht an Anfänger, die CSS jetzt SEHR gut kennen lernen und/oder noch nie Kontakt zu den Namenskonventionen für CSS-Klassen hatten. Wenn dies der Fall ist, fahren Sie mit dem Abschnitt „Quellen“ fort.

Header angepasst von der offiziellen Legacy-BEM-CSS-Website

 

  • Wozu dient eine CSS-Architektur?
  • Was ist BEM-CSS?
    • Kategorisierung von UI-Elementen nach ihrer Kopplung
    • Ausdrücken der Beziehung von Komponenten durch CSS
    • Komplexe Komponentenbeziehungen
  • Spezifitätskontrolle mit BEM
  • CSS-Wiederverwendung
  • BEM und Sass
  • Interaktionen mit anderen Architekturen
  • Quellen

? Wozu dient eine CSS-Architektur?

Wie bei Pflanzen hängt die Art und Weise, wie ein Code wächst und gedeiht, davon ab, wie wir ihn erstellen, pflegen und wo sich die Dinge befinden.

Es gibt Pflanzen mit unterschiedlichen Bedürfnissen an Boden, Behandlung, Wasser und Sonnenlicht, genauso wie es Codes mit unterschiedlichen Anforderungen an Standards, Standort und Management gibt.

CSS ist ein entscheidendes Element beim Laden einer Seite – der Rendering-Prozess beginnt nicht, bevor der Browser sämtliches HTML und CSS anfordert, herunterlädt und in DOM und CSSOM umwandelt und den Renderbaum zusammenstellt. Je weniger CSS, desto besser die Leistung, je organisierter, standardisierter und robuster das CSS, desto besser lässt es sich pflegen, verwalten, skalieren und komprimieren.

Die Art und Weise, wie CSS-Selektoren benannt werden, beeinflusst den Umfang der Regeln, ihre Spezifität, ihren Standort und ihre Semantik und beschleunigt oder verschlechtert den Entwicklungsprozess. In Projekten, in denen mehr als eine Person CSS schreibt, verfügen wir über unterschiedliche Sprachkenntnisse und unterschiedliche Bräuche oder persönliche Standards, die, wenn sie nicht beachtet werden, zu übermäßiger Wiederholung von Regeln und Fehlern führen können.


? Was ist BEM-CSS?

BEM ist eine CSS-Architektur, die sich auf Styleguide konzentriert und Standards für die Kategorisierung und das Schreiben von CSS-Regeln definiert. BEM wurde bei Yandex im Zusammenhang mit Anwendungen erstellt, die mehrere Seiten enthielten, die von einem oder mehreren Stylesheets verwaltet wurden.

BEM ist die Abkürzung für Block, Element, Modifier. Jede dieser Entitäten stellt eine Kategorie von Schnittstellenelementen dar, die direkt in CSS dargestellt wird.

Tudo o que você precisa saber sobre a arquitetura BEM CSS

Darstellung visuell getrennter Schnittstellenkomponenten, Quelle: offizielle Website von BEM CSS

 


? Kategorisieren von UI-Elementen nach ihrer Kopplung

Ein Block stellt ein unabhängiges UI-Element dar, er kann untergeordnete Elemente haben, so wie ein Header seine Navigationslinks hat, und diese untergeordneten Elemente können, wenn sie unabhängig sind, auch Blöcke sein.

Das Konzept der Unabhängigkeit einer Schnittstellenkomponente kann durch das folgende Axiom definiert werden

„Wenn die Komponente nur innerhalb eines bestimmten Kontexts Sinn macht, muss sie ein Element dieses Kontexts sein. Wenn sie in mehreren Kontexten existieren kann, muss sie ein unabhängiger Block sein.“

Ein Element ist eine Komponente, die ein anderes größeres Element ausmacht und zu diesem gehört. Wenn diese Komponente nicht existiert und nicht ausschließlich vom Kontext abhängt, in dem sie angewendet wird, kann es sich um einen Block handeln. In BEM können Blöcke andere Blöcke enthalten. Wenn ein Element ein Element enthalten muss, handelt es sich wahrscheinlich auch um einen Block.

Die Beziehung zwischen einem Block und einem Element wird durch den doppelten Unterstrich block__element dargestellt.

Blöcke und Elemente können innerhalb desselben Kontexts ästhetische oder Layout-Variationen enthalten. Dafür haben wir Modifikatoren. Diese Klassen können unterschiedliche Zustände oder Varianten derselben Komponente darstellen. Modifikatoren wie Elemente hängen vom Block ab und leiten sich nur von ihm ab.

Die Beziehung zwischen einem Block oder einem Element und seinen Modifikatoren wird durch den doppelten Bindestrich block--modifier oder block__element--modifier dargestellt.

 

Referência Descrição
Tudo o que você precisa saber sobre a arquitetura BEM CSS Um checkbox é independente, pode ser aplicado dentro de outros componentes como
,
ou , por exemplo.
Tudo o que você precisa saber sobre a arquitetura BEM CSS Uma label pode ser considerada um bloco independente se ela for igualmente aplicada nos inputs da aplicação. Se a diferença entre labels for estética, ela pode ser um bloco que contém diversas variantes (modifiers), se a diferença entre as labels do input for estrutural (no template), faz sentido ela ser o elemento de um bloco
Tudo o que você precisa saber sobre a arquitetura BEM CSS Um card pode ser incluído em qualquer container, em diferentes contextos, podendo ser considerado independente (block). Se a imagem e textos dentro dos cards tiverem características que só faz sentido no contexto do card, elas podem ser consideradas elements
Tudo o que você precisa saber sobre a arquitetura BEM CSS Um botão pode ser administrado em qualquer lugar, inclusive mais de uma variante no mesmo lugar. Cada variante pode ser representada pela classe modificadora derivada do mesmo bloco ou elemento.

 

? Die Beziehung von Komponenten durch CSS ausdrücken

Am Beispiel des Kontrollkästchens: Die Art und Weise, wie wir Komponenten erstellen und ihre Verantwortlichkeiten definieren, beeinflusst, was ein Block, ein Element oder ein Modifikator sein kann. Diese Entscheidungsfindung beginnt mit der Vorlage:

<div class="form-field">
  <input
   class="form-field__input form-field__input--checkbox" 
   type="checkbox"
   value=""
   id="checkbox"
  />
  <label class="form-field__label" for="checkbox">
    Default checkbox
  </label>
</div>

In dieser Vorlage haben wir die .form-field-Komponente als Block, der immer eine .form-field__input-Eingabe und eine .form-field__label-Klassenbezeichnung enthält. Die Beziehung zwischen Block (.form-field) und Element (Label oder Eingabe) wird durch einen doppelten Unterstrich ausgedrückt. Dieses Schreiben bedeutet, dass wir durch CSS Folgendes verstehen:

  • form-field ist eine unabhängige Entität, es hängt nicht vom Kontext der Komponente oder des übergeordneten Containers ab, damit seine Stile funktionieren. Jedes Formular kann Felder vom Typ .form-field empfangen

  • Das Formularfeld kann wiederum eine __input und ein __label enthalten, und sein Layout und Aussehen hängt vom Formularfeld-Container ab

.form-field {}
  .form-field__input {}
  .form-field__input--checkbox {}
  .form-field__label {}

 

Wenn wir die Beziehung in der Vorlage ändern, ändern wir die Topographie der CSS-Klasse. Im folgenden Beispiel sind Eingabe und Label separate Einheiten:

<div class="column">
  <label class="label" for="checkbox">
    Default checkbox
  </label>
  <input
   class="input input--checkbox"
   type="checkbox"
   value=""
   id="checkbox"
  />
</div>
  • .column kann in diesem Fall sowohl als Block als auch einfach als Utility-Klasse betrachtet werden. Zusätzlich zu anderen CSS-Architekturen ist es möglich, BEM mit Dienstprogrammklassen zu verwenden, einschließlich solcher, die ihrer eigenen Konvention folgen.
  • .input ist ein Block, der sich auf alle Eingaben bezieht und in einem .column-Container oder einem anderen verwendet werden kann und unabhängig von der Existenz von .label funktioniert. Es gibt eine Variante --checkbox, die bestimmte Stile für die Eingabe des Kontrollkästchentyps lädt, z. B. den Status von :checked.
  • .label ist ein Block, dessen Layout und Aussehen nicht von der Eingabe abhängen und der sogar eine .input als untergeordnetes Element haben kann.

In CSS ausgedrückt würde es so aussehen:

.column {}

.input {}
.input--checkbox {}
.input--checkbox:checked {}

.label {}

 

BEM konzentriert sich auf die Unabhängigkeit von Komponenten – das Ändern der Position einer Komponente im HTML sollte sich nicht auf deren Layout auswirken, und das Ändern des CSS einer Komponente sollte sich nicht auf die anderen Komponenten auswirken. Wenn wir Elemente erstellen, zeigen wir eine Liste der Auswirkungen, wenn wir ihren Block ändern. Auf diese Weise haben Sie einen Überblick darüber, was eine mit ihren Teilen gekoppelte Komponente und ein völlig unabhängiges Modul wäre. Wie in der Legacy-Dokumentation zitiert:

Im Jahr 2006 begannen wir mit der Arbeit an unseren ersten großen Projekten: Yandex.Music und Ya.Ru. Diese Projekte mit Dutzenden von Seiten offenbarten die Hauptnachteile des aktuellen Entwicklungsansatzes:

  • Alle Änderungen am Code einer Seite wirkten sich auf den Code anderer Seiten aus.
  • Es war schwierig, Klassennamen auszuwählen.

Übersetzung

Im Jahr 2006 begannen wir mit der Arbeit an unserem ersten großen Projekt: Yandex.Music und Ya.Ru. Diese Projekte mit Dutzenden von Seiten erwiesen sich als Nachteile des aktuellen Entwicklungsansatzes:

  • Jede Änderung am Code einer Seite würde sich auf die anderen Seiten auswirken.
  • Es war schwierig, sich für einen Namen für die Klassen zu entscheiden.

 

? Komplexe Komponentenbeziehungen

Als BEM 2010 Open Source wurde und eine Website erhielt, war die Idee, dass jedes UI-Element eine „Komponente“ sei, bereits vorhanden, noch vor Atomic Design (Brad Frost, 2013) als Reaktion auf die Herausforderung, die Konsistenz von aufrechtzuerhalten die gleichen Komponenten auf verschiedenen Seiten. Als BEM beispielsweise bei Yandex erstellt wurde, verwendeten sie mehrere HTML-Dateien und nur eine CSS- und eine Javascript-Datei.

Wenn jede Seite ein Block wäre und ihre Elemente vom Kontext dieser Seite abhängig wären, würde der gesamte Code, der zwischen den Seiten konsistent wäre, dupliziert. Durch die Aufteilung der Benutzeroberfläche in kleine Komponenten konnten diese Teile wiederverwendet werden, unabhängig davon, auf welchen Seiten sie verwendet wurden.

Um dieses Konzept der Wiederverwendung zu veranschaulichen, können wir eine komplexere Komponente verwenden, beispielsweise einen Header:

Tudo o que você precisa saber sobre a arquitetura BEM CSS

Dieser Header kann wie folgt geschrieben werden (kurzes HTML):

<nav class="navbar">
  <div class="navbar__container">
    <a class="navbar__logo" href="#">Navbar</a>
    <button class="navbar__toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar__toggler-icon"></span>
    </button>
    <div class="navbar__collapse" id="navbarSupportedContent">
      <ul class="navbar__list">
        <li class="navbar__item">
          <a class="navbar__link active" aria-current="page" href="#">Home</a>
        </li>
        <!-- etc -->
        <li class="navbar__item navbar__dropdown">
          <a class="navbar__dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
            Dropdown
          </a>
          <ul class="navbar__dropdown-menu">
            <li>
              <a class="navbar__dropdown-item" href="#">
                Action
              </a>
            </li>
            <!-- etc -->
          </ul>
        </li>
        <!-- etc -->
      </ul>
      <form class="navbar__form" role="search">
        <input class="navbar__form-input" type="search" placeholder="Search" aria-label="Search">
        <button class="navbar__form-btn" type="submit">
          Search
        </button>
      </form>
    </div>
  </div>
</nav>

Beachten Sie, dass in diesem Beispiel die gesamte Navigationsleiste als ein großer Block deklariert wurde und alles, was darin enthalten war, als Element der Navigationsleiste betrachtet wurde. Dadurch verlieren wir mehrere Möglichkeiten zur Wiederverwendung.

Oportunidade Descrição
Tudo o que você precisa saber sobre a arquitetura BEM CSS O logotipo dentro de .navbar__logo é representado por um link contendo imagem ou texto. Existem diversos elementos que podem ser 'envelopados' em um link, como ícones back to top ou cards clicáveis. Esse código poderia pertencer a um bloco .link ou .media
Tudo o que você precisa saber sobre a arquitetura BEM CSS Os itens .navbar__list e .navbar__item nada mais são que uma lista desordenada no formato de linha ao invés de coluna. Isso poderia reutilizado representando-a pelo bloco .list com o modificador .list--row. O dropdown por sua vez pode ter o mesmo funcionamento fora do navbar, dentro do seu próprio bloco .dropdown, com seus elementos .dropdown__toggle e, como ele renderiza uma lista, podemos reutilizar .list e, se necessário, complementar com um modificador
Tudo o que você precisa saber sobre a arquitetura BEM CSS Esse componente de busca pode ser representado de forma mais "fechada" com um bloco .search e elementos .search__input, search__label e .search__trigger ou de forma mais "aberta" como .form-field, .input--text, .label e .button--outline

 

Ainda pensando nessa relação de componentes "abertos" e "fechados", podemos representar o componente de busca usado no último exemplo das duas forma usando CSS.

Componente de busca "fechado"
Os elementos input, label e button são acoplados ao bloco search, mudanças no componente ou no HTML de search influenciam nos seus elementos.

.search {}
  .search__input {}
  .search__label {}
  .search__button {}

Componente de busca "aberto"
Os elementos input, label e button são independentes do bloco de search, ele apenas organiza os blocos já existentes que compõe esse componente.

.form-field {}

.input {}
.input--text {}

.label {}

.button {}
.button--outline {}

? Controle da especificidade com BEM

Um dos problemas citados pela galera do Yandex é que mudanças no CSS podiam afetar partes indesejadas. No caso deles era utilizada uma folha de estilo pra todas as páginas da aplicação, e você pode achar que não é um problema pra ti se você usa algum processador como Sass ou diversos arquivos de CSS, mas é uma dor de cabeça ainda maior quando seletores de diferentes abrangências moram em múltiplos arquivos.

A forma que o BEM encontrou de contornar esse problema além da modularização de blocos é a especificidade. BEM só utiliza classes por motivos bem claros:

  • Classes podem ser reaproveitadas
  • Como você se refere diretamente aos elementos usando as classes, a especificidade tende a ser sempre muito próxima de 0,1,0
  • Pra alterar ou sobrescrever uma regra, basta adicionar outra classe
  • Regras que se referem à seletores mais globais como de resets ou normalizers são facilmente sobrescritas pelas classes.

Abaixo vemos um accordion que mantém uma diversidade de seletores, pra nos referirmos, por exemplo ao h2 desse accordion, temos que explicitamente dizer #accordion-item > h2:

<div id="accordion-item">
  <h2>
    <button class="btn">
      Accordion Item #1
    </button>
  </h2>
  <div class="collapse show">
    <div>
      <strong>This is the first item's accordion body.</strong>
    </div>
  </div>
</div>

 

Pra estilizar todos os elementos desse componente, precisamos estabelecer as seguintes relações:

/* 1,0,0 */
#accordion-item {}

/* 1,0,1 */
#accordion-item > h2 {}

/* 1,1,0 */
#accordion-item .btn {}

/* 1,1,0 */
#accordion-item .collapse {}

/* 1,2,0 */
#accordion-item > .collapse.show {}

/* 1,1,1 */
#accordion-item > .collapse > div {}

/* 1,1,2 */
#accordion-item > .collapse strong {}

Esse exemplo assume que .collapse por não se referir diretamente ao accordion (não é um .accordion-collapse, por exemplo) pode existir em outros lugares do código ou até em outros lugares de #accordion-item. Isso obriga a gente a deixar explícita sua relação com #accordion-item.

A regra #accordion-item > .collapse > div existe pois o estilo não pode impactar qualquer div, nem qualquer .collapse, pra alterar apenas aquilo que existe dentro do bloco #accordion-item precisamos adicionar muito mais complexidade e especificidade, além de que qualquer mudança no HTML desse componente causa bugs imprevisíveis.

<div class="accordion-item">
  <h2 class="title">
    <button class="button">
      Accordion Item #1
    </button>
  </h2>
  <div class="accordion-item__collapse">
    <div class="accordion-item__wrapper">
      <strong>This is the first item's accordion body.</strong>
    </div>
  </div>
</div>

No HTML acima estabelecemos as relações entre o .accordion-item e o .accordion-item__collapse sem adicionar especificidade. Ao nos referirmos diretamente aos elementos pela classe e não compondo seletores, quando alteramos o .accordion-item podemos quebrar o .accordion-item__collapse, mas ao alterar .accordion-item__collapse, o .accordion-item dificilmente será influenciado.

.title e .button serem blocos independentes faz com que alterarmos o HTML desse componente ou o CSS dessas classes não cause nenhum bug, pois elas existem de forma independente do bloco do accordion. Em relação à especificidade, a relação passa a ser da seguinte forma:

/* 0,1,0 */
.accordion-item {}

/* 0,1,0 */
.accordion-item__collapse {}

/* 0,1,0 */
.accordion-item__wrapper {}

/* 0,1,0 */
.title {}

/* 0,1,0 */
.button {}

 

A especificidade dessas regras é muito mais previsível, tanto que se eu quiser adicionar uma variante ao .accordion-item__wrapper basta eu criar uma classe com as regras e incluir no elemento no HTML, sem precisar criar no CSS um seletor .accordion-item__wrapper.accordion-item__wrapper--vertical.


? Reuso de CSS

Quando me refiro a reuso de CSS, não falo apenas de blocos que podem ser reaplicados em diferentes componentes, à nível de seletores, mas também à conjuntos de regras que realizam as mesmas ações. No exemplo abaixo, temos 3 componentes diferentes e mesmo se escritos na convenção do BEM haverá repetição de conjuntos de regras:

Elemento Regras
Tudo o que você precisa saber sobre a arquitetura BEM CSS
.alert {
  display: flex;
  gap: 0.5rem;
  /* etc... */
}
Tudo o que você precisa saber sobre a arquitetura BEM CSS
.nav {
  display: flex;
  gap: 1rem;
  /* etc... */
}
Tudo o que você precisa saber sobre a arquitetura BEM CSS
.breadcrumb {
  display: flex;
  gap: 0.5rem;
  /* etc... */
}

 

Percebe como todos os elementos que tem a disposição de 'linha' muito provavelmente terão um grupo de regras de display: flex o configura dessa forma, terão um gap: npx e provavelmente um flex-wrap: wrap quando fizer sentido pro layout 'quebrar' pra linha de baixo?

Usando o breadcrumb como exemplo, podemos criar um bloco que represente uma linha ou coluna genérica e que seja configurável à partir de variantes.

<ol class="breadcrumb">
  <li class="breadcrumb__item">Home</li>
  <li class="breadcrumb__item active">Library</li>
</ol>

Ao invés de repetir o conjunto de regras que configura uma coluna, podemos adicionar à classe .breadcrumb o bloco de .row. Não há restrições sobre o mesmo elemento ser representado por dois blocos distintos, pois o conceito de bloco é acoplado com seus elementos, não com componentes específicos.

/* Breadcrumb deixa de configurar o layout e passa apenas a implementar estilos estéticos */
.breadcrumb {
  font: 200 1rem Poppins;
  line-height: 1.45;
}

/* Row se torna responsável pelo layout */
.row {
  display: flex;
  gap: 1rem;
}

/* E pode ter variantes na convenção BEM caso conveniente */
.row--flexible {
  flex-wrap: wrap;
}

Nesse caso o gap de .row é estático, mas os elementos apresentados nos exemplos tem diferentes valores nessa propriedade, de quem é a responsabilidade? Se você possuí uma estrutura de CSS utilitário, a responsabilidade pode ser de .row que será configurada pelo CSS utilitário .gap-0.5 ou .gap-sm.

Se você não usa CSS utilitário, o gap pode ser configurado pelo próprio componente breadcrumb:

/* Ao implementar o gap com variáveis CSS temos um valor
default e um valor configurável */
.row {
  --row__gap-default: 1rem;
  display: flex;
  gap: var(--row__gap, var(--row__gap-default));
}

/* Dessa forma podemos configurar o gap pelo breadcrumb.
A row ainda não depende dele, mas caso ele seja aplicado com
uma row, ele a configura */
.breadcrumb {
  --row__gap: 0.5rem;
  font: 200 1rem Poppins;
  line-height: 1.45;
}

Separar os estilos de layout dos de aparência é uma prática do OOCSS (link do artigo na Smashing Magazine, em inglês). Categorizar o CSS em skin e structure vem do entendimento de que a estrutura e layout de um elemento ou componente é mais reaproveitável e ubíqua do que a aparência de um componente.

Usando a convenção BEM é possível criar blocos que se referem à estruturas e modificadores que se referem à aparência, sendo ela apenas uma convenção de escrita de classes, a categorização e separação dessas classes pode ficar na responsabilidade de outro tipo de arquitetura.


? BEM e Sass

Sass foi criado em 2009, um ano antes de BEM se tornar open source, a interação entre eles funciona extremamente bem (rsrs) por dois motivos:

  • Sass permite a criação de múltiplas folhas de estilo e a co-locação dos estilos de acordo com as necessidades do projeto,logo podemos criar uma folha pra cada bloco ou conjunto de blocos que se referem a um componente ou contexto.
  • Sass tem suporte à concatenação de string, o que torna ainda mais visual a relação da classe com seus elementos e modificadores. Pensando no exemplo do bloco .search citado anteriormente:
.search {
  &__input {}
  &__label {}
  &__button {}
}

 

Com CSS a relação de blocos e elementos se dá pelo prefixo do bloco, ex: .search__, no Sass os elementos são declarados dentro do bloco.

Um problema muito comum com Sass é o 'overnesting', que é quando aninhamos múltiplas classes em um bloco. Essa abordagem além de dificultar a legibilidade do bloco cria especificidade sem necessidade e acopla os elementos ao bloco mais do que o necessário.

/* Esse tipo de nesting ao invés de gerar seletores  0,1,0 */
.search {
  .search__item {}

  .search__label {
    &.search__label--floating {

    }
  }
}

/* Gera o CSS */
/* 0.2.0 */
.search .search__item {}

/* 0.2.0 */
.search .search__label {}

/* 0.3.0 */
.search .search__label.search__label--floating {}

O overnesting geralmente acontece pelo não conhecimento de como o Sass funciona ou pela tentativa de imitar o formato do HTML no CSS.


? Interações com outras arquiteturas

Como naming convention BEM é flexível quando nos apropriamos de outras arquiteturas ou apenas características delas. Como citado na documentação:

No matter what methodology you choose to use in your projects, you will benefit from the advantages of more structured CSS and UI. Some styles are less strict and more flexible, while others are easier to understand and adapt in a team.

Tradução

Não importa qual metodologia você use em seus projetos, vbocê vai se beneficiar das vantagens de uma UI e CSS mais estruturados. Alguns estilos são menos estritos e mais flexíveis, outros sãi fáceis de entender e adaptar em um time.

 

Podemos escrever as regras do tipo block do CUBECSS na convenção do BEM.

A diferença entre os blocos do CUBECSS e do BEM é o seu escopo, no CUBE há uma separação semântica entre estrutura, configuração e aparência. Após declarar a camada de Composition que defini layouts num nível mais macro (Como o object no OOCSS ou ITCSS) e criar classes utilitárias na camada de Utility, sobra pouca configuração a se fazer na cabada do Block, o deixando mais enxuto.

Podemos também criar as diversas camadas propostas pelo ITCSS e criar Objects, Components e Utilities na sintaxe do BEM. O ITCSS não define a forma que criamos modificadores e a relação dos componentes e seus estados/variantes, mas sim a taxonomia e localização dos elementos respeitando seu escopo e dando previsibilidade na sua especificidade e posição na cascata.

Podemos expressar as mesmas relações do SMACSS, por exemplo, declarando states quando esses alteram um módulo específico na sintaxe BEM:

/* Na convenção SMACSS */
.tab {
  background-color: purple;
  color: white;
}

.is-tab-active {
  background-color: white;
  color: black;
}

/* Na convenção BEM */
.tab {
  background-color: purple;
  color: white;
  &__is-active {
    background-color: white;
    color: black;
  }
}

States que não são específicos de um módulo podem ser declarados como classes utilitárias ou blocos independentes.

Há muitas outras formas de se escrever BEM, não necessariamente vinculadas a uma arquitetura, como no exemplo abaixo.


Afinal, BEM é a melhor arquitetura de CSS?

Não existe 'melhor arquitetura'. Todas as metodologias já propostas são claras nos problemas que elas visam resolver, e elas não necessariamente vão resolver todos os problemas da sua organização, time ou codebase. BEM pode resolver seus problemas de acoplamento de classes e especificidade, mas talvez não resolva o de performance ou localização.

O interessante é aumentar seu gabarito de metodologias, convenções e arquiteturas e escolher sua ferramenta de acordo com os problemas que tu visa resolver.

BEM num contexto de aplicação Vue com SFC pode ser incrível quando localizamos o bloco CSS no mesmo lugar que o componente que ele estiliza, mas pode gerar muito CSS duplicado ou inutilizado se não houver uma arquitetura mais voltada pra reuso de estruturas, como OOCSS ou CUBECSS.


? Fontes

  • Artigo BEM: guia definitivo do padrão CSS mais famoso de Tárcio Zemel (DPW), em português (Muito bom)
  • Vídeo BEM: A Convenção CSS Para Um Front End Muito Melhor de Tárcio Zemel (DPW), em português
  • Artigo An Introduction To Object Oriented CSS (OOCSS) na Smashing Magazine, em inglês
  • Artigo MindBEMding – getting your head ’round BEM syntax de Harry Roberts, em inglês
  • Artigo BEMIT: Taking the BEM Naming Convention a Step Further de Harry Roberts, em inglês
  • Artigo Side Effects in CSS de Phillip Walton, em inglês
  • Artigo BEM 101 em Smashing Magazine, em inglês

Das obige ist der detaillierte Inhalt vonAlles, was Sie über die BEM-CSS-Architektur wissen müssen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn