Forum

Methodology

Toolbox

Platform

Community

bem-naming

Tool for working with BEM entity representations: allows you to parse string representation and stringify object representation.

Install

$ npm install --save @bem/naming

Usage

const bemNaming = require('@bem/naming');
const BemEntityName = require('@bem/entity-name');

bemNaming.parse('button__text'); // { block: 'button', elem: 'text' }

const entityName = new BemEntityName({ block: 'button', mod: 'checked' });

bemNaming.stringify(entityName); // button_checked

Table of Contents

Object representation

The BemEntityName class describes the representation of a BEM entity name.

String representation

To define BEM entities, we often use a special string format that allows us to define exactly which entity is represented.

According to the original BEM naming convention, it looks like this:

'block[_block-mod-name[_block-mod-val]][__elem-name[_elem-mod-name[_elem-mod-val]]]'

(Parameters within square brackets are optional)

Examples:

  • Block — block-name.
  • Block modifier — block-name_mod-name_mod-val.
  • Simple modifier of block — block-name_mod.
  • Block element — block-name__elem-name.
  • Element modifier — block-name__elem-name_mod-name_mod-val.
  • Simple modifier of element — block-name__elem_mod.

Delimiters

The original naming uses the following delimiters:

  • __ — to separate an element from a block
  • _ — to separate a modifier name from a block or element and to separate a modifier value from a modifier name

Common misconceptions

The BEM methodology uses a flat structure inside blocks. This means that a BEM entity can't be represented as an element of another element, and the following string representation will be invalid:

'block__some-elem__sub-elem'

For more information, see the FAQ:

Why doesn't BEM recommend using elements within elements (blockelem1elem2)?

Also, a BEM entity can't be a block modifier and an element modifier simultaneously, so the following string representation will be invalid:

'block_block-mod-name_block-mod-val__elem-name_elem-mod-name_elem-mod-val'

Harry Roberts' naming convention

According to this convention elements are delimited with two underscores (__), modifiers are delimited by two hyphens (--), and values of modifiers are delimited by one underscore (_).

Read more in the Guidelines.

Example:

const twoDashesNaming = require('@bem/naming')('two-dashes');

twoDashesNaming.parse('block__elem');    // { block: 'block', elem: 'elem' }
twoDashesNaming.parse('block--mod_val'); // { block: 'block',
                                         //   mod: { name: 'mod', val: 'val' } }

twoDashesNaming.stringify({
    block: 'block',
    elem: 'elem',
    mod: 'mod'
});

// ➜ block__elem--mod

Custom naming convention

Use the bemNaming function to create an instance where you can manage your own naming convention.

Example:

const bemNaming = require('@bem/naming');

const myNaming = bemNaming({
    elem: '-',
    mod: { name: '--', val: '_' }
    wordPattern: '[a-zA-Z0-9]+'   // because element and modifier's separators include
});                               // hyphen in it, we need to exclude it from block,
                                  // element and modifier's name

myNaming.parse('block--mod_val'); // { block: 'block',
                                  //   mod: { name: 'mod', val: 'val' } }

myNaming.stringify({              // 'blockName-elemName--simpleElemMod'
    block: 'blockName',
    elem: 'elemName',
    mod: 'simpleElemMod'
});

API

bemNaming({ elem, mod, wordPattern })

Parameter Type Description Default
elem string Separates element's name from block. __
mod string, { name: string, val: string } Separates modifier from block or element. _
mod.name string Separates a modifier name from a block or an element. _
mod.val string Separates the value of a modifier from the modifier name. Default as the value of the mod.name.
wordPattern string Defines which characters can be used in names of blocks, elements, and modifiers. [a-z0-9]+(?:-[a-z0-9]+)*

parse(str)

Parameter Type Description
str string BEM entity name representation.

Parses the string into an instance of BemEntityName.

Example:

const bemNaming = require('@bem/naming');

bemNaming.parse('block__elem_mod_val');

// ➜ BemEntityName {
//     block: 'block',
//     elem: 'elem',
//     mod: { name: 'mod', val: 'val' }
// }

stringify(entityName)

Parameter Type Description
entityName BemEntityName, object BEM entity name representation.

Forms a string from the instance of BemEntityName.

Example:

const bemNaming = require('@bem/naming');
const BemEntityName = require('@bem/entity-name');

bemNaming.stringify(new BemEntityName({
    block: 'block',
    elem: 'elem',
    mod: { name: 'mod', val: 'val' }
});

// ➜ block__elem_mod_val

elemDelim

String to separate an element from a block.

modDelim

String to separate a modifier name from a block or element.

modValDelim

String to separate a modifier value from the name of the modifier.

License

Code and documentation copyright 2014 YANDEX LLC. Code released under the Mozilla Public License 2.0.

If you notice a mistake or want something to supplement the article, you can always write to us at GitHub, or correct an article using prose.io.