better-bem
v2.0.3
Published
Chainable BEM classname generator with CSS Modules support
Downloads
120
Maintainers
Readme
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
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
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 akey-value
string when the value is a string or a number
- for
- 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
- React-Better-BEM - React component using better-BEM