EN RU
Forum

Methodology

Technology

Toolbox

Libraries

Tutorials

States of a block

When designing a dynamic block in BEM style, you need to provide the complete logic of changes that occur in it as a set of states for the block. Then the block behavior is determined by triggers — callback functions that are performed when the block switches from one state to another.

This allows you to write the block code declaratively as a set of statements in the format: state description — action performed when switching to this state.

Modifiers

According to the BEM methodology, modifiers describe the state of a block and its elements.

A modifier indicates which of the possible states the block is in. A modifier is a name — value pair. The list of acceptable modifier values describes the set of block states. For example, to describe a block size, you can use the size modifier with the possible values s, m and l.

A simple modifier is a special case when only the presence or absence of the modifier on the block is important, and its value is insignificant. An example is the modifier describing the ”disabled“ state: disabled. A modifier with an unspecified i-bem.js value is interpreted as boolean and automatically assigned the value true.

Each block can have one or more modifiers set. A block isn't required to have any modifiers. The block developer defines the list of acceptable modifiers and their values.

Modifiers are set during initialization of a block instance (if modifiers and their values are specified in the class attribute of the corresponding HTML element).

Modifiers can change as part of the block functioning (for example, as a reaction to a DOM event of the block), or at the request of other blocks (see Interaction of blocks).

When setting, deleting, and changing modifier values, triggers are executed.

Note If modifiers were set in a block HTML element before its initialization, the triggers to set these modifiers are not executed. In this case, the block instance gets its original state, and doesn't change it.

Managing modifiers

Methods of a block instance for working with modifiers:

Example

The changeColor method of the square block toggles the color modifier between the values green and red, if the block has the has-color modifier set:

BEMDOM.decl('square', {
    changeColor : function(e) {
        if(this.hasMod('has-color')) {
            this.toggleMod('color', 'green', 'red');
        }
    }
});

The same methods allow managing modifiers of the block elements. To do this, a reference to the element DOM node (not the element name) is passed as the first argument.

Example

On a click, the searchbox block can assign its input element the simple modifier clean (the assumed value is true):

BEMDOM.decl('searchbox', {
    _onClick: function() {
        this.setMod(this.elem('input'), 'clean');
    }
});

Note Use the API for changing the values of modifiers. Don't set modifiers by altering the CSS classes of the corresponding DOM node yourself.

For complete documentation of the API for managing modifiers, see the JSDoc section for the i-bem block.

Triggers to set modifiers

Triggers to set modifiers are executed in two phases:

Triggers can be bound to the following types of changes to modifier values:

When setting the modName modifier to the modVal value, triggers in each phase (if they are defined) are fired in the same order as they are listed in the list of events above (from general to specific).

Thus, when defining a trigger, the user specifies:

Execution phases

An additional phase prior to setting a modifier allows performing certain checks without risk of affecting the logic for setting the modifier. For example, if there are mutually exclusive modifiers, it makes sense before setting one of them to check whether the other is already set.

Example

The focused modifier won't be set on the searchbox block if it has the disabled modifier.

BEMDOM.decl('searchbox', {
    beforeSetMod : {
        'focused' : {
            'true' : function() {
                return !this.hasMod('disabled');
            }
        }
    },

    onSetMod : {
        'focused' : {
            'true' : function() { /* ... */ }
        }
    }
});

If the trigger for the phase prior to setting (beforeSetMod) returns false, the modifier is not set.

For more information about using triggers, see Declaring triggers.

Note The trigger to set the js modifier to inited is a constructor of a block instance, but with the value '' it is a destructor of a block instance. For more information, see Initialization.