DEV Community

Cover image for BEM vs CSS Grid
Anton Korzunov
Anton Korzunov

Posted on • Updated on

BEM vs CSS Grid

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.

Flex Grow

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”

Grid Areas

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 few Elements
  • 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> 
Enter fullscreen mode Exit fullscreen mode

BEM Composition

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 between B and E

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 a Block

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>
Enter fullscreen mode Exit fullscreen mode

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 way Grid can lay Grid-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 with flex styles (explicit layout). That is not "your" problem.
  • (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:

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.

Discussion (0)