BEM

Vladimir Grinenko, Yandex

BEM

BEM: complete guide for your component frontend development

BEM

Vladimir Grinenko,
28 May 2016, Frontend United

BEM is not just about CSS

Interfaces are built with
blocks

Blocks are made of
elements

Same blocks may behave differently with modifiers


bem.info

CSS without component approach is
a pain

Blocks are
independent
and
self-contained

BEM on file system

blocks/
    button/
        button.css
        button.js

BEM on file system

blocks/
    button/
        button.css
        button.js
        button.spec.js

BEM on file system

blocks/
    button/
        button.css
        button.js
        button.spec.js
        button.md

BEM tree

<body class="page">
    <header class="header">
        <a class="logo" href="/"></a>
    </header>

    <div class="main"></div>

    <aside class="sidebar"></aside>

    <footer class="footer">
        <div class="copyright"></div>
    </footer>
</body>

BEM tree

page
    header
        logo
    main
    sidebar
    footer
        copyright

BEMJSON

{
    block: 'page',
    title: 'Hello, BEM',
    content: [
        {
            block: 'header',
            content: { block: 'logo' }
        },
        { block: 'main' },
        { block: 'sidebar' },
        {
            block: 'footer',
            content: { block: 'copyright' }
        }
    ]
}

Mixes: several entities on same node

<nav class="nav">
    <a class="link nav__item" href="/">Main</a>
    <a class="link nav__item" href="/about/">About</a>
</nav>

Mixes: several entities on same node

{
    block: 'nav',
    content: [
        {
            block: 'link',
            url: '/',
            mix: { block: 'nav', elem: 'item' },
            content: 'Main'
        },
        {
            block: 'link',
            url: '/about/',
            mix: { block: 'nav', elem: 'item' },
            content: 'About'
        }
    ]
}

BEMHTML: BEMJSON to HTML

<button class="button">I'm a button</button>

BEMHTML: BEMJSON to HTML

<button class="button">
    <font color="red">I'm a button</font>
</button>

BEMHTML: BEMJSON to HTML

<button class="button">I'm a button</button>
.button {
    color: red;
}

BEMHTML: BEMJSON to HTML

<button class="button">I'm a button</button>
<div>
    <button class="button">I'm another button</button>
</div>
.button {
    color: red;
}

BEMHTML: BEMJSON to HTML

{
    block: 'button',
    content: 'I am button'
}
block('button')(
    tag()('button')
);

BEMHTML: BEMJSON to HTML

[
    {
        block: 'button',
        content: 'I am button'
    },
    {
        content: {
            block: 'button',
            content: 'I am another button'
        }
    }
]
block('button')(
    tag()('button')
);

BEMHTML

BEM on file system

blocks/
    button/
        button.css
        button.js
        button.spec.js
        button.md

BEM on file system

blocks/
    button/
        button.css
        button.js
        button.spec.js
        button.md
        button.bemhtml.js

Tune library on project side

Tune CSS

library/button/button.css

Tune CSS

library/button/button.css
project/button/button.css

Tune CSS

library/button/button.css
    .button {
        width: 200px;
        color: green;
    }
project/button/button.css

Tune CSS

library/button/button.css
    .button {
        width: 200px;
        --color: green;--
    }
project/button/button.css
    .button {
        color: red;
    }

Tune CSS

library/button/button.css
    .button {
        width: 200px;
        --color: green;--
    }
project/button/button.css
    .button {
        color: red;
    }
@import library/blocks/button/button.css;
@import project/blocks/button/button.css;

Tune HTML

library/
    button/
        button.bemhtml.js

project/
    button/
        button.bemhtml.js

Tune HTML

library/
    button/
        button.bemhtml.js

            block('button')(
                tag()('button'),
                attrs()({ 'area-role': 'button' })
            );

project/
    button/
        button.bemhtml.js

            block('button')(
                tag()('input')
            );

Tune JavaScript

.button {
    border-radius: 5px;
}

.button--disabled {
    opacity: .5;
}
<button class="button"></button>

Tune JavaScript

.button {
    border-radius: 5px;
}

.button--disabled {
    opacity: .5;
}
<button class="button button_disabled"></button>

Tune JavaScript

BEMDOM.decl('button', {








});

Tune JavaScript

BEMDOM.decl('button', {
    onSetMod: {




    }


});

Tune JavaScript

BEMDOM.decl('button', {
    onSetMod: {
        disabled: {


        }
    }


});

Tune JavaScript

BEMDOM.decl('button', {
    onSetMod: {
        disabled: {
            true: { this._onDisabled(); }

        }
    },
    _onDisabled: function() {}

});

Tune JavaScript

BEMDOM.decl('button', {
    onSetMod: {
        disabled: {
            true: { this._onDisabled(); },
            '': { this._onEnabled(); }
        }
    },
    _onDisabled: function() {},
    _onEnabled: function() {}
});

Ready-made UI libraries

Component based testing

Let’s take it all!

project-stub

BEM is not just about CSS

BEM is not just about CSS

BEM is not just about CSS

bem.info

Contacts

Vladimir Grinenko


bem.info

info@bem.info