In the simplest form a block is represented by a single DOM node but generally blocks and DOM nodes are not the same thing.
Mixes
are just the way to use several blocks and/or elements on the same DOM node.
That makes possible
- combining behaviour and/or styling of different BEM entities without copy/paste
- building new semantic components based on existed blocks.
For instance, we have a universal block logo
(a block with a logotype) that could be used anywhere on a page: in header, inside copy, in the footer, etc. We can specify its width, height and a background image but what we do with its margins that differ from case to case?
Of course, we could use modifiers like logo_type_header
or logo_type_content
to do so. However it is wrong semantically, because such things should lay down within a scope of parent block’s responsibility. And giving the right to define such things to an inner block contradicts the whole idea of blocks independency.
That's where mixes
shine:
<div class="header">
<div class="header__logo logo"></div>
</div>
.logo
{
width: 120px;
height: 60px;
background-image: url(logo.svg);
}
.header__logo
{
margin: 12px 26px;
}
As you know there's no global modifiers in BEM methodology but again — mixes
gives us possibility to achieve the same result with several different blocks on same DOM node.
Also you may want to use mixes
to provide some arbitrary block with JS logic.
A single DOM node can represent:
- several blocks
<div class="menu head-menu"></div>
- a block and an element of the same block
<div class="menu menu__layout"></div>
- a block and an element of another block
<div class="link menu__link"></div>
- elements of different blocks
<div class="menu__item head-menu__item"></div>
- a block with a modifier and another block
<div class="menu menu_layout_horiz head-menu">
- several different blocks with modifiers
<div class="menu menu_layout_horiz head-toolbar head-toolbar_theme_black"><div>
So try to develop your blocks as small and reusable as possible and then combine them in any way you want to build huge applications!
Can you give some examples of using
<div class="menu menu__layout"></div>
? I can't imagine any case when block's element need to be on the same node with parent.@hudochenkov What we using now for tabs:
Each block splitted on 2 dom nodes and has 1 element in each other. Caption listening for user events (e.g. click). And when tab becoming active we add a class to both elements activate it. And vice-versa if tab becoming inactive.
For
i-bem.js
it can be code like:Simple.
@hudochenkov Or if you don't need DOM nodes, but need to split some handlers out:
One JS class, several cases. DRY ONW.
Thank you, this makes sense.
Interesting...
What if
.logo
is defined at the bottom or @imported after.header
in Sass we run into issues, very common in a large application to import files in the wrong order or when combining blocks, especially with many developers.The
.header__logo
styles will not get applied for example:My proposed solution:
Is this a viable solution?
I think it's a way to go but we use build system (ENB) with special tech to explicitly describe dependencies of a block which also guarantee the order.
I've just discovered this when trying to make a block from an existing block but in an independent way, at first I had the following
However, using mixes to join the media and blog-post would result in the following
Is this the correct way to approach this? The other alternative is to ignore the existing b-media block and again implement those rules in the b-blog-article block?
@hendore sure
Hello, I've just joined the BEM forum. I'm really happy to come accross this whole idea. I'm still getting up to speed with it and have one question relating to this thread.
In the above example the element
content-section__step
as well as the blockstep
are the same node. Within that node I havestep__image
,step__heading
andstep__instruction
. Is that correct? Or maybe the elements ofstep
should also be marked as elements ofcontent-section
so then it would look like this:@ltarasiewicz Hi! It depends on what exactly you're going to do with
step__image
,step__heading
andstep__instruction
. Try to imagine it outside ofcontent-section
. Blockstep
with all its elements should still look the same. And if in this mental experiment you find out that some ofstep
elements have styles which are just forcontent-section
context (e.g. for positioning insidecontent-section
), you should mix them withcontent-section
elements and move these styles there.Also take a look at https://en.bem.info/method/key-concepts/#mix and https://en.bem.info/faq/#mixes
Hi @tadatuta,
This makes perfect sense. Thanks for this explanation!