BEM
is not a “naming convention”. It’s a separation between Blocks
and Elements
. And Modifiers
... but let’s just forget about them for a while.
Today we better focus on something different.
So, I've written this article because people do not understand the core principles behind BEM
, not to be able to see them behind other features.
This is why let’s forget about BEM
for a while as well.
To get things started we all can generally agree that…
CSS Grids are awesome 🥳
The main difference between display block
and display flex
is that the first one sees all children nodes as a separate elements, while they act like a Team🤜 within flex
– they can grow and shrink.
They are connected.
Grid
fosters this connection, lets you handle bigger blocks, giving more power and more control.
But there is one big difference, really BIG difference, - the majority of power and control is given to the “grid parent”, not “grid element”
Let's imagine a conversation between Grid and Cell:
🤖: Dear Grid-Item, I've prepared a place for you, where shall you stay according to my very plan 😈
📦: Can I have my own opinion?
🤖: Dear Grid-Item, well yes, some of you can move self to other places, but not particularly you 😅. Please stay within my template because I do have a plan for you 👮🏻♂️.
And like the Grid
, which can use grid template
or grid areas
to control all direct children, BEM also has a plan...
BEM has a Plan
Technically speaking BEM
works in the same way as Grid
- they share the same ideology. BEM
is just not bound to the "2d grid" and one level of children nodes.
It can be easier to think about BEM
from a Component Model
point of view:
- there is a
Parent
component and a fewElements
-
according to the plan
Elements
has to be placed in some well known location. - children
Elements
should not think or even know about their placement.
const ParentTemplate = () => (
<html>
<body>
<header>
<slot>
<Component1 /> <--- Another block
</slot>
</header>
<main>
<slot>
<Component2 /> <--- Another block
</slot>
</main>
</body>
</html>
A few rules
Let me be honest - there are two major sites about BEM methodology, where you can read some information - http://getbem.com/ and https://en.bem.info/. I hope you likely to see the key information hidden between the lines, but according to my experience no one has seen it yet.
BEM is not about that-strange__naming--convention
BEM is about the Separation betweenB
andE
Here is what you might miss:
-
Elements do not lay themselves out. Parent
Block
does - Block style themselves and layout only their children.
-
Blocks cannot be (visually) styled 🎨 outside, except via own known
Modifiers
- Every
Element
can be aBlock
Note: "Children" is not an "immediate DOM node". Still easy to think in React terms - children is everything defined among component
const List = () => (
<ul> // children
<li> // also children
<SomeItem> // still children, but also a Block
</li>
</ul>
Rule them all
How Block
can rule children? Usually (for the last 15 years? BEM was created back in 2006) by passing extra classname
, which is expected to obey the principles above and cannot style children
, except using modifiers
defined in the children
.
modifiers
are equal to (React)props
Block
only can:
-
lay
Elements
inside. In the same wayGrid
can layGrid-Items
inside. - configure own children by picking/using different modifiers/props, but only among the explicitly supported by children Components. Well, you can do the same with
Grids
, not something particular bound to BEM.
Look like there are at least something in common between BEM and Grid. Grids are just more about "how" to do something - they are providing a particular way to command a Browser Engine. While BEM 🤷♂️ it's just a way to keep things clear
Both Grid and BEM define layout for their children gently asking those children not to interfere.
While this moment might sounds like NOT something really important - it is the core essence of both technologies
Step away from technical implementation. Try to understand the intent behind the actual approach and principles according to which both technologies ended like this.
What to do
- (dimension) do not let components define own dimensions - different Parents can have different Plans
- and your parent will configure "you" one way or another - or by placing "you" in
grid
(browser layout) or by giving you extra classname withflex
styles (explicit layout). That is not "your" problem.
- and your parent will configure "you" one way or another - or by placing "you" in
- (gaps) do not let components define margins - that gonna break any order anyone will try to establish
- margins are still file, just define it "inside" block, the area under your control, not "outside", creating unexpected behaviour for consumers.
- (isolation) do not style other components, tell them what they shall do
So what?
So please stop writing random code, which always ends in some messy, completely unmaintainable state, causing a lot of performance issues, especially if you overuse CSS-in-JS for no reason.
Think structurally. Think in relationships. Think about you styles in the same way you think about your code, files, function and packages - and I believe there are some rules you follow and some pain you've experienced due to bad habits.
Well, apart of Grids there is another concept which should explain you the main point behind separation of responsibilities and concerns - Open Closed Principle, a part of SOLID pattern
software entities should be open for extension, but closed for modification
Which, in this case, controls what Elements can be asked to do by Blocks(blocks are "extension"), and how Blocks could not affect Elements(which are "closed for modification")
See also:
- https://non-traditional.dev/encapsulated-css-the-key-to-composable-layouts-94f11c177cc1
- https://www.joshwcomeau.com/css/styled-components/#isolated-css
- https://mxstbr.com/thoughts/margin/
Wait!
Should you read anything about BEM methodology in particular?
No, because:
- you don't need naming pattern with CSSModules, and especially CSS-in-JS
- the main thing is a separation, and frankly speaking it does not have to be exactly the same separation
Keep the last point in mind. Remember how Grids work. Only then go and research information about BEM you can found in other places.
And keep in your mind one more thing - as I've mentioned above the vast majority of developers, including the ones who uses BEM, "did not get the point", something more than that_strange__naming--pattern.
I know this for sure. I was among them.
Top comments (0)