better-bem
DefinitelyTyped icon, indicating that this package has TypeScript declarations provided by the separate @types/better-bem package

2.0.3 • Public • Published

better-BEM 2.x

better-BEM is a dynamic classname generator using BEM methodology (.block__element--modifier) which supports CSS Modules. better-BEM is chainable and allows modifier inheritance. Disclaimer: In contrast to what the package name suggests, better-BEM might not actually be better than other packages handling BEM classname generation. It definitely is better than better-BEM 1.x.

Getting Started

Installing

# install
npm i better-bem
// import
import bem from 'better-bem';

Usage

bem( [classNames [, mods [, classNameMap [, strict [, glue ] ] ] ] ] )

const className = bem('article').el('header').mod('large').el('title').mod('red').cn;

document.querySelector('h1').className = className;
// => <h1 class="article__header__title article__header__title--large article__header__title--red"> ...

Jump to examples.

Parameters

classNames

Classname(s) which will form the 'block' part of the generated classname(s).

Optional

Default: []

Accepts: String, object or array of strings and/or objects

Please refer to the ClassName parameter usage section for details on how this parameter works.

mods

Modifiers for the generated classnames. Modifiers are passed down the chain, see the section on Chaining and modifier inheritance.

Optional

Default: []

Accepts: String, object or array of strings and/or objects

See ClassName parameter usage for more details.

classNameMap

Object which maps input classnames to output classnames.

Optional

Default: {}

Accepts: Object

See using className maps

strict

When strict is true and when classNameMap isn't empty, classnames which aren't mapped in classNameMap will be ignored.

Optional

Default: true

Accepts: Boolean

See using className maps

glue

Object with strings which will be used to concat classnames. If not set these fall back to -- for modifiers, __ for element classnames and - for key-value modifiers. See examples.

Optional

Default: {}

Accepts: Object

Return value

Object { string cn, function el, function mod }

cn

Outputted classname string for current BEM chain. Note: All classnames are checked for valid characters using the following regular expression: /^(-[_a-zA-Z]|[_a-zA-Z][-_a-zA-Z0-9])[-_a-zA-Z0-9]*$/

el

function el( [ elementClassNames ] )

Function to push a new element on the BEM chain. See chaining for examples.

elementClassNames

Default: []

Accepts: String, object or array of strings and/or objects

See ClassName parameter usage for more details.

mod

function mod( [ modifiers ] )

Function to add a modifier the current BEM className and all descendants. See Chaining and modifier inheritance for examples.

modifiers

Default: []

Accepts: String, object or array of strings and/or objects

See ClassName parameter usage for more details.

ClassName parameter usage

bem(), el() and mod() all accept the same types of parameters. These types are:

  • a string containing a single classname or modifier
  • a string containing multiple classnames or modifiers separated by spaces
  • an object where the keys are used as classnames or modifiers when the related value is thruthy
    • for mod() key-value pairs are mapped as a key-value string when the value is a string or a number
  • an array containing any of the above
Parameter value classnames modifiers
"foobar" "foobar" "--foobar"
"foo bar" "foo bar" "--foo", "--bar"
{ foo: true, bar: 0, prop: "value" } "foo mod" "--foo", "--bar-0", "--prop-value"
[ "foo bar", { prop: "value" } ] "foo bar mod" "--foo", "--bar", "--prop-value"

Examples

Chaining and modifier inheritance

const header = bem('header');
console.log(header.cn); // "header"

const title = header.el('text title');
console.log(title.cn); // "header__text header__title"

const blueTitle = title.mod({ color: 'blue' });
console.log(blueTitle.cn);
// "header__text header__text--color-blue header__title header__title--color-blue"

const emphasizedText = blueTitle.el('emp').mod('bold');
console.log(emphasizedText.cn);
// "header__text__emp header__title__emp header__text__emp--color-blue
//   header__title__emp--color-blue header__text__emp--bold header__title__emp--bold"

// note that modifiers are inherited by child elements

Using CSS Modules

/* styles.css */
.header {
	font-size: 2em;
}

.header__title {
	font-weight: bold;
}

.header__title--blue {
	color: blue;
}
import styles from './styles.css';

const header = bem('header', 'blue', styles);
console.log(header.cn); // "header"
// note that "header--blue" is omitted from the output, because it's not defined in styles.css

const title = header.el('title');
console.log(title.cn); // "header__title header__title--blue"
// both the base classname and modified classname are outputted, since they are defined in styles.css
// note that the 'blue' modifier is still inherited

const nonStrictHeader = bem('header', 'blue', styles, false);
console.log(nonStrictHeader.cn); // "header header--blue"
// now strict is set to `false`, all classnames will be outputted

Custom glue strings

const defaultGlue = bem('element', [{ color: 'blue' }], {}, true).el('child');
console.log(defaultGlue.cn); // "element__child element__child--color-blue"

const customGlue = bem('element', [{ color: 'blue' }], {}, true, { el: '_', mod: '-', prop: '--' }).el('child');
console.log(customGlue.cn); // "element_child element_child-color--blue"

Built With

Versioning

better-BEM uses SemVer for versioning. For the versions available, see the tags on this repository.

Authors

License

This project is licensed under the ISC License - see the LICENSE file for details

Related

Package Sidebar

Install

npm i better-bem

Weekly Downloads

31

Version

2.0.3

License

ISC

Unpacked Size

67.6 kB

Total Files

13

Last publish

Collaborators

  • luuuud