Giter Site home page Giter Site logo

practical-bem's Introduction

Practical BEM

The TL;DR on BEM IRL

Table of contents

  1. BEM anatomy
  2. Dialects
  3. Entity
  4. Block
  5. Element
  6. Modifier

BEM anatomy

/*
 * Entity
 * A set of Elements and Modifiers related to a single Block
 */

/*
 * Block
 * The single root-class of your Entity
 */

.todo-item { }

/*
 * Element
 * Any number of Block-descendants
 */

.todo-item__mark { }
.todo-item__text { }

/*
* Modifier
* Any number of Block/Element modifiers
*/

.todo-item--complete { }
.todo-item--due { }

⬆ back to top

Dialects

There are a few alternative BEM dialects. These examples use the most popular -- dialect by Harry Roberts. Using -- for modifiers removes a small ambiguity around key/value modifiers.

⬆ back to top

Entity

An Entity is a collections of Elements and Modifiers, related to a single Block. Entities are analogous to "modules" or "components" in other CSS philosophies.

⬆ back to top

Practically, Entities should live in a single file and be easily transportable to other projects.

Block

A Block is the single, root-level, classes of any Entity.

.todo-item { }

A bunch of Blocks:

.report { }
.report-item { }
.report-subtotal { }

.person { }
.person-name { }
.person-child-list { }

.admin-person { }
.admin-person-responsibilities-list { }
.admin-person-responsibilities-item { }

Relationships

  • Block belongs_to Entity
  • Block has_many Elements
  • Block has_many Modifiers

⬆ back to top

Element

An Element is anything nested in a Block.

"Descendent" is actually a better word but BDM doesn't roll off the tongue.

Here are some elements:

.todo-item__mark { }
.todo-item__text { }
.todo-item__input { }
.todo-item__delete-button { }

Elements can have Modifiers. Though they're not preferred.

.todo-item__delete-button--blingy { }

Prefer Block-Modifiers

I find Block-Modifiers to be more maintainable than Element-Modifiers. In most cases, Element-Modifiers are partial Block-Modifiers waiting to grow up. You can avoid refactoring by preferring Block-Modifiers.

No grandchildren

BEM supports only one level of element. If you find yourself reaching for Element-Elements (grandchildren), you have two options:

  • Flatten out the Elements
  • Create a new Block

This is incorrect

<li class="todo-item">
  <header className="todo-item__header">
    <span className="todo-item__header__text">Mow Lawn</span>
  </header>
</li>

Option 1: Flatten

<li class="todo-item">
  <header className="todo-item__header">
    <span className="todo-item__header-text">Mow Lawn</span>
  </header>
</li>

Option 2: New Block

<li class="todo-item">
  <header className="todo-item-header">
    <span className="todo-item-header__text">Mow Lawn</span>
  </header>
</li>

Now .todo-item-header can be composed with Elements from the .todo-item Entities.

<li class="todo-item">
  <header className="todo-item__header todo-item-header">
    <span className="todo-item-header__text">Mow Lawn</span>
  </header>
</li>

Why?

This may seem pedantic but it's critical to how BEM scales. Grandchildren introduce relationships into Entities. Once you have relationships, how many descendants do you cut off at? BEM makes it easy and cuts it off at 1.

Relationships

  • Entity belongs_to Block
  • Entity has_many Modifiers

⬆ back to top

Modifier

Modifiers are like HTML attributes. They alter Blocks and Elements. They can be boolean or key/value pairs.

/* boolean */
.todo-item--hidden { }

/* named attributes*/
.todo-item--size_small { }
.todo-item--type_radio { }

/* Element_Modifier */
.todo-item__header--fancy { }

Prefer Block-Modifiers

I find Block-Modifiers to be more maintainable than Element-Modifiers. In most cases, Element-Modifiers are partial Block-Modifiers waiting to grow up. You can avoid refactoring by preferring Block-Modifiers.

This code commonly gets outgrown:

.todo-item__header--blingy { }

Prefer this by default:

.todo-item--blingy { }
.todo-item--blingy .todo-item__header { }

Alternatives

The BEM approach to Modifiers is hotly contested. This stems from a desire to type less or a misunderstanding of early BEM documentation. Granted, the early docs were in pretty poor English.

While I like variants with global states, e.g., .is-visible, it breaks the BEM model. More relevant, it makes utility-class libraries (e.g., minions.css and tachyons) harder to use.

Prefer inline for generic visibility changes

For generic visibility changes, prefer an inline-style on the Block.

<!-- ok -->
<div class="todo-item todo--visible"> ... </div>

<!-- preferred -->
<div class="todo-item" style="display: none"> ... </div>

Relationships

  • Modifier belongs_to Block
  • Modifier belongs_to Element

⬆ back to top

practical-bem's People

Contributors

chantastic avatar

Stargazers

Latch Jack avatar Ivan Tomić avatar Micah Fukazawa avatar gosenx avatar Pemberai Sweto avatar  avatar Bohdan Moroziuk avatar Ashwinikumar Patil avatar Uli Troyo avatar  avatar Parker Henderson avatar Picon Kayal avatar Code Explore avatar Aditya Agarwal avatar Manny Becerra avatar Kevin C avatar Yevhenii Herasymchuk avatar Kevin McCartney avatar Isaac Horton avatar Calvin avatar Jake Gavin avatar akshay kadam (a2k) avatar Jose avatar Luke Fiji avatar Tiago Luiz Aguiar de Souza avatar Markus Laurila avatar Riku Rouvila avatar Daniel Schildt avatar  avatar J avatar Russell Hoy avatar  avatar

Watchers

 avatar James Cloos avatar  avatar BlackCat avatar

practical-bem's Issues

Modifiers section typo?

Is it just me or should the following:

Modifiers are like HTML attributes. They alter Blocks and Modifiers.

Be:

Modifiers are like HTML attributes. They alter Blocks and Elements.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.