A comprehensive guide to using BEM with React (2024)

A comprehensive guide to using BEM with React (1)

In previous stories (“Using BEM conventions in CSS modules leveraging custom webpack loaders” and “A more JavaScript-friendly BEM naming convention”) we’ve discussed how using CSS Modules imposes some restrictions on which CSS class names are “valid”, and how those restrictions drive the “BEM flavor” we’ve chosen to use at Trabe

In this story I want to broaden the focus and give you a more detailed view on the way we use BEM naming conventions together with some tooling in our React projects.

CSS Modules lets you write CSS files where all the class names have local scope. This means no more CSS naming conflicts! How does this work? Well, you write “normal” CSS files, but instead of writing the class name verbatim in your component code, you import the CSS file and use the imported class names (see the example below):

The CSS Modules plugin or loader (depending on whether you are using PostCSS or Webpack to process your CSS Modules) will generate a unique name for each class name in the CSS file. So, when you use styles.Button in your component’s code, the actual class name will be something like button.css_Button___231as3s. This way you get non-clashing class names while you are still able to write “old-school” CSS.

The way local class names are transformed into global, non-clashing class names, can be configured. For instance, in our projects we configure Webpack CSS loader to use a global index, so we get simpler class names, like Button----1. These are easier on the eyes when you inspect the code using developer tools 😄.

You will have to configure your test environment so it “understands” CSS Modules. For Jest we configure a moduleNameMapper to get predictable class names in our tests, using identity-obj-proxy:

CSS Modules solve the problems derived from CSS having a global naming scope. When you write a component, you know that the class names you use will be “unique”, no matter what other components or even third party libraries do.

But you still have to tackle some problems which can appear at a local, single-component level:

  • Having truly composable components 😅
  • Naming consistency and semantics
  • Selector specificity

This is where BEM naming conventions come into play.

Having truly composable components

When you define a React component following BEM conventions, you must know that:

  • A Block “encapsulates a standalone entity that is meaningful on its own”. So, every React component you write must have a Block class name on its outermost element.
  • Elements are “parts of a Block and have no standalone meaning”. So Element class names should be given to inner… elements.
  • Modifiers are “flags on Blocks or Elements” which you can use to change the appearance of the modified item.

From the definitions above we derive two different sets of CSS properties, one for Blocks, the other one for Elements (Modifiers just use the same properties as the item being modified):

  • Block-related properties. A Block being a “standalone entity”, its properties should only affect appearance (background-*, color, font-*, border-*, padding-*, width, height, line-height, text-align, etc.) and/or the way it arranges its Elements (flex, grid, position).
  • Element-related properties. They should only affect the way the Element is positioned within the component and relative to other Elements (margin-*, top, left, right, bottom, z-index, align-self, justify-self, grid-column, grid-row, etc.).

How does this distinction affect composability? Well, each set of properties has a different scope. Block-related properties are “context-free”, in the sense that they can’t affect or be affected by where you place the Block. Element-related properties, on the other hand, are “context-sensitive”, because they do affect and are affected by its “surroundings”.

Limiting Block CSS properties to the “context-free” ones, and limiting Element-related properties to the ones having to do with positioning, guarantees that your components can be used as “standalone entities”, making them composable.

You may argue that this is not what the original naming convention says. There, no distinction is made on what properties apply to Blocks or Elements. But we have found that with this restrictions in place, it is much more easier to reason about the component structure (at both visual and code levels).

Naming consistency and semantics

Having a consistent and predictable naming convention is key to have a maintainable project. Being able to know the role each part of a component plays just by looking at its class name, has proven to be really useful for us while doing code reviews.

As I described in “A more JavaScript-friendly BEM naming convention”, we use the following BEM naming convention in our most recent projects:

  • Blocks are written using PascalCase, like in VideoPlayer.
  • Elements are written using camelCase, joined to the block name using a single underscore (_), like in VideoPlayer_buttonsContainer.
  • Modifiers are written using camelCase, but we use three underscores (___) to join the modifier to the block or element name, like in VideoPlayer___isLoading.

When we review code, we can immediately tell if a component lacks the relevant class names and, conversely, when we see each class name being applied to different parts of a component, we get a clue of that part’s role inside the component.

Also, as we’ve seen while talking about truly composable components, in theory (see the final notes to know more about the “in practice” side of things 😅), a component should only have a Block class, assigned to the outermost element of the component, and Element classes assigned to the inner elements. This leads to the following pattern:

  • There is only one Block class name (that of the component itself) in a React component’s source code file.
  • The rest of class names used in the source code have to be Element class names.

The use of class names diverging from the previous pattern is a code smell and should be reviewed.

Selector specificity

The problem of selector specificity is similar to the problem of global scope. You might have CSS Modules working and still face problems of “unwanted” styling:

In the example above, the Button text will be red when rendered inside the Footer component, despite the use of CSS Modules. While this behavior (due to the .Footer a selector having a highest specificity than the .Button one) is very useful to style a “website”, it can be frustrating when you are trying to style (supposedly) isolated “components”.

BEM imposes a restriction on the type of selectors you can use: only class name selectors. It also limits the use of CSS combinators to a single descendant selector, and only when you want to “alter elements based on a block-level modifier” (think something like .Button___disabled .Button_icon { display: none };). This means the code in the previous example is not valid from a BEM standpoint. A possible solution will involve creating a Link component and using it inside the Footer:

Now Button and Link styles don’t interfere with each other.

To prevent the most common errors before the code gets to the review process, we use stylelint with a bunch of plugins and configuration presets (adding prettier to the mix to ensure all the CSS code is uniformly formatted):

The following configuration file ties it all together. Pay special attention to the selector-bem-pattern configuration. This is the plugin we use to make sure we’re following the established BEM naming conventions:

With this configuration in place, you get lint errors whenever an invalid selector is used, forcing you to review your code.

A typical React component using the conventions I’ve outlined in the previous sections will look like this:

There are a few things to note in the example:

  • We use classnames and computed property names to apply the Block and possible Modifier class names.
  • Most of the time we prefer defining Elements with its own div, like we did above withButton_icon, wrapping other components. But in some cases using a wrapper can cause problems (mostly when dealing with flexbox and grid layouts) and the Element class has to be given to the component itself (<Icon /> in the example). That’s why our React components always accept a className prop. We use this prop, together with the component Block and Modifiers, to compute the class names which will be actually applied to the component wrapper. This way we can give our Block components an additional Element class name when they are used by other components.

Being 100% compliant with the conventions and restrictions I’ve described in this story is not always the best solution in terms of productivity. So we’ve come to use some “escape hatches”.

Auxiliary components

We allow the definition of auxiliary components in the same files (both .jsx and .css) as the “main” one. We treat this auxiliary components as BEM Blocks too, and they can have their own Elements and Modifiers.

To prevent stylelint from failing, we have to use a special directive to declare a new component in the main .css file (remember that our configuration infers the name of the Block from the file name):

Fixed positioning

For fixed-positioned Blocks, we allow them to receive position-related properties:

Non-BEM selectors

Sometimes we have to style some element deep in the DOM hierarchy. In those cases we use “forbidden” CSS combinators, disabling the linter as needed:

Third party code and global CSS

When we need to style some third party components via CSS class names, we use the :global switch in CSS Modules to prevent the class name from being “modularized” (no need to disable the linter here, as global selectors are not processed):

Embracing BEM with the additional restrictions stated above may seem overkill, but the burden pays off in the end. Having a clear distinction between Blocks and Elements simplifies the way we think about components, lets us avoid a lot of styling problems, and gives us a clear vocabulary to use when we discuss or review code.

A comprehensive guide to using BEM with React (2024)

FAQs

Can you use BEM with React? ›

In highly interactive React applications, however, BEM seems to struggle to manage component conditions effectively. If you're looking for a class-based solution to your applications style system, I recommend that you give BEM a try. It may not be the best solution in every situation, but it is a tried and true option.

What is BEM convention in React? ›

BEM stands for Block, Element, and Modifier. It's a CSS naming convention for writing cleaner and more readable CSS classes. BEM also aims to write independent CSS blocks in order to reuse them later in your project.

What is BEM and how do you use it? ›

BEM is a front-end naming method for organizing and naming CSS classes. The Block, Element, Modifier methodology is a popular naming convention for class names in HTML and CSS. It helps to write clean CSS by following some simple rules.

How do you use BEM naming convention? ›

Names are written in lowercase Latin letters. Words within the names of BEM entities are separated by a hyphen ( - ). The element name is separated from the block name by a double underscore ( __ ). Boolean modifiers are separated from the name of the block or element by a double hyphen ( -- ).

Does Bloomberg Use React? ›

The first mobile app Bloomberg has built using React Native uses it to feature the latest business and financial news.

Should I use RxJS With React? ›

RxJS is not necessary to build robust React application. RxJS provides a functional programming implementation for building React applications with event streams, asynchronous data, and more. RxJS implements the Observable primitive that is compatible to Promises (but without async/await).

How do you explain BEM to a 5 year old? ›

Explaining BEM to a 5 year Old

BEM attempts to divide the overall user interface into small reusable components. It is an award winning image of a stick-man :) The stick-man represents a component, such as a block of design. You may have already guessed that the B in BEM stands for 'Block'.

How do I structure my React code? ›

What is the Folder Structure for React Project?
  1. Assets Folder.
  2. Layouts Folder.
  3. Components Folder.
  4. Pages Folder.
  5. Middleware Folder.
  6. Routes Folder.
  7. Config Folder.
  8. Services Folder.
Sep 12, 2022

What is the difference between block and element in BEM? ›

A BEM class name includes up to three parts. Block: The outermost parent element of the component is defined as the block. Element: Inside of the component may be one or more children called elements. Modifier: Either a block or element may have a variation signified by a modifier.

Is BEM obsolete? ›

Since class collision between components is not a problem anymore, a lot of devs consider now BEM obsolete.

Is BEM methodology good? ›

Benefits of using BEM

Because of its unique naming scheme, we won't run into conflicts with other CSS names. BEM also provides a relationship between CSS and HTML. Ambiguous names are hard to maintain in the future⁣. Overall, BEM is my favourite CSS naming scheme, and I strongly suggest you try using it too!

What is the disadvantage of BEM in CSS? ›

What Are the Cons of Using BEM? The only downside to using BEM is that, sometimes, the HTML can get a bit bloated with long unreadable names. That's it. Overall, the scale is tipping to using BEM on all future projects.

What are the 3 things to consider in establishing a naming convention? ›

Elements to consider using in a naming convention are:

Location. Project name or number. Sample. Analysis.

What is BEM naming methodology? ›

BEM stands for block, element, and modifier. It's a naming convention that divides the user interface into small, reusable components that will prepare us for the changes in design of our websites. This convention also enhances the cross-site copy/paste feature by helping make elements reusable components.

Does bootstrap use BEM? ›

Bootstrap is the most popular HTML, CSS, and JS framework for developing responsive, mobile first projects on the web. BEM and Bootstrap can be primarily classified as "Front-End Frameworks" tools. Bootstrap is an open source tool with 135K GitHub stars and 66.4K GitHub forks.

Do people still use Bloomberg Terminal? ›

320,000 people around the world pay roughly $20,000 annually to use the Terminal. Despite the steep cost and arguably outdated appearance, most financial firms have Bloomberg subscriptions and continue to rely (albeit begrudgingly) on the tool to conduct business. There's even a Bloomberg Terminal in the Vatican.

Why do people still use Bloomberg Terminal? ›

The Bloomberg Terminal revolutionized an industry by bringing transparency to financial markets. More than four decades on, it remains at the cutting edge of innovation and information delivery — with fast access to news, data, unique insight and trading tools helping leading decision makers turn knowledge into action.

Does Tesla use React Native? ›

We also help support utility grids worldwide with the Tesla Virtual Power Plant, a product that improves grid stability for even those without Solar and Powerwall. We build our app in TypeScript, React Native, the Godot 3D Engine.

Can RxJS replace Redux? ›

They are very different things. RxJS can be used to do Reactive Programming and is a very thorough library with 250+ operators. And Redux is as described on the github repo "Redux is a predictable state container for JavaScript apps". Redux is just a tool to handle state in apps.

Which is better NgRx or RxJS? ›

RxJS is for handling complex asynchronous work like handling communication between client and server. Ngrx is for optimally storing data in the client and recalling them from all over the application, usually. If you want to take advantage of single direction data flow using Store in Angular NgRx is the solution.

Why should I use React instead of Angular? ›

React is simple to use and provides developers with various options for performing similar tasks. In comparison to Angular, React is faster and easier to learn. React also features a unidirectional data flow and is less than Angular (just 46KB).

What is Bem with example? ›

BEM stands for Block Element Modifier. The main idea behind it is to speed up the development process, and ease the teamwork of developers by arranging CSS classes into independent modules. If you ever saw a class name like header__form--search , that is BEM in action.

Why is my 5 year old so badly behaved? ›

Some children have undetected medical issues such as allergies (food or otherwise) that can truly impact their behavior. Other children who are chronically defiant, constantly breaking rules or having trouble handling frustration may be experiencing ADHD, Asperger's Disorder, anxiety or depression.

How do you discipline a 5 year old who doesn't listen? ›

Discipline: Top Do's and Don'ts When Your Kids Won't Listen
  1. Don't view discipline as punishment. Discipline may feel as though you're punishing your kids. ...
  2. Do find opportunities for praise. ...
  3. Do set limits and keep them. ...
  4. Do be specific. ...
  5. You're their parent, not their buddy.
Apr 1, 2021

How do I make my React code more readable? ›

One of the most important aspects of code is its readability.
...
How to write more readable React code
  1. Length of the code.
  2. How closely-related code is grouped together.
  3. Complicated JavaScript constructions.
  4. How many flows are handled at once.
  5. Variable naming.
  6. Highlighting similarities and differences.
Nov 25, 2021

Is Facebook coded in React? ›

Facebook. Facebook's website uses ReactJS as an integrated script in the application code. The mobile app is created with React Native, which is a framework of ReactJS and is responsible for displaying native iOS and Android components rather than DOM elements.

What are the 4 blocks of elements? ›

The elements in the periodic table are divided into blocks based on their valence electron orbitals. S-block, p-block, d-block, and f-block are the four blocks.

How do you use modifiers in BEM? ›

Guidelines for using modifiers

From the BEM perspective, a modifier can't be used in isolation from the modified block or element. A modifier should change the appearance, behavior, or state of the entity, not replace it. Why write the block name in the names of modifiers and elements?

What are the two commonly used block elements? ›

Two commonly used block elements are: <p> and <div> . The <p> element defines a paragraph in an HTML document. The <div> element defines a division or a section in an HTML document. The <p> element is a block-level element.

Is Bem widely used? ›

BEM (Block, Element, Modifier) methodology is a widely used naming convention for CSS classes that is gaining popularity because of the ease of use it offers.

Why You Should Use bem? ›

BEM (Block Element Modifier) is a commonly used naming convention for writing classes in HTML. It helps you speed up the development process while keeping things organized and easy to understand for the whole team. It is based on a simple idea where every big chunk of markup is called a Block.

What are the benefits of bem? ›

BEM will consider providing financial assistance to a seminar or conference which is organised by a non-profit making organisation. The seminar or conference must be technical one that will benefit the registered engineers. The promotion of continued learning and education does not stop here.

Why inline CSS is not recommended? ›

Disadvantages of Inline CSS:

Adding CSS rules to each HTML element takes time and makes your HTML structure unorganized. It's difficult to keep up, reuse, and scale. The size and download time of your page can be affected by styling multiple elements.

What is the important rule in CSS and why should you generally avoid it? ›

The !important rule in CSS is used to add more importance to a property/value than normal. In fact, if you use the !important rule, it will override ALL previous styling rules for that specific property on that element!

What CSS should not do? ›

8 things to avoid doing in CSS
  1. 1 – Too much specificity. ...
  2. 2 – Misusing ! ...
  3. 3 – CSS's @import. ...
  4. 4 – Inconsistent naming. ...
  5. 5 – Inline CSS. ...
  6. 6 – Senseless z-index values. ...
  7. 7 – Using ID selectors instead of classes. ...
  8. 8 – Very generic class names.
Mar 30, 2020

Can you use React and bootstrap together? ›

Bootstrap can be used directly on elements and components in your React app by applying the built-in classes as you would any other class.

Can you use React for back-end? ›

React is a JavaScript library used in web development to build interactive elements on website User Interfaces (UI) based on UI components. It is used in both frontend and backend, this means it can be used to develop full-stack web applications.

Can we use React and EJS together? ›

It makes sense if you want to incrementally add React to an existing, large project that uses EJS (which React uses as a selling point). It also makes sense if you are implementing generators and need templatized react components.

Can you use both node and React? ›

Yes, it is possible to combine React with Node. js for full-stack web development. This allows you to use a single language (JavaScript) for the entire application. You'll be able to write your code in one place and have it run on both the front-end and back-end!

Is it a good idea to use Bootstrap with React? ›

Using the React-Bootstrap integration saves you time because the JavaScript elements are already there, wrapped in neat little React-shaped bows. If you opt to use Bootstrap as/is, you should be well-versed in JavaScript and JavaScript plug-ins, because you'll need to work with those components on your own.

Should I use React Bootstrap or just Bootstrap? ›

Bootstrap vs React Comparison at a Glance. While React is known for enhancing user experience by loading web pages faster, Bootstrap helps to build mobile-friendly websites, CSS designing, HTML layouts, and JavaScript functions perform well.

Is Bootstrap necessary for React? ›

React-Bootstrap's clean syntax and straightforward components make responsive design simple to implement on any project. The ability to work with Bootstrap and React-Bootstrap is a must for front-end developers. With these tools in your skill set, you're ready for easier web application design and prototyping.

What is the easiest backend for React? ›

Firebase is one of the simplest and best backends for React that developers can use. You need to add Firebase to your JavaScript project page, and you are ready to go.

What is the easiest backend to use with React? ›

We recommend using Express Js with NodeJS as they have proven to be the best and most appropriate backend framework for React. Although, it varies from user to user.

Which backend language is best for React? ›

NodeJS is considered a perfect backend partner of React JS because of its great compatible features. Both front-end and backend libraries use the same JavaScript language that enables them to develop modern applications.

Why React over ejs? ›

More ease with logic

While ejs does allow javascript logics (like else-if conditioning or for loops), the syntax is both cumbersome to write and a pain to read. React introduces the JSX syntax, which while maintaining the proximity to traditional HTML, elucidates the use of programming logic to a great extent.

Can React replace ejs? ›

Again, React and ejs are very different ways to structure an app. It's not as simple as “replace this with that”. You really have to understand how to structure an app in React because you will be creating that from scratch. Much of the JS logic can get reused but you will have to make the React components and JSX.

Which template engine is best? ›

That said, we will look at today's most popular and dubbed best (by the community) templating engines for JavaScript.
  • Mustache. Mustache is one of the most widely known templating systems that works for several programming languages, including JavaScript, Node. ...
  • Handlebars. ...
  • doT. ...
  • EJS. ...
  • Nunjucks. ...
  • Underscore.
Jan 4, 2023

Is React harder than NodeJS? ›

Thanks to its simple design, use of JSX (an HTML-like-syntax), and highly detailed documentation, React is the best library that makes web development easier to implement and iterate. In contrast, Node may be easy to learn, but it takes more effort to implement web applications with it.

Should I learn Node or React first? ›

So before moving to React, you should have a solid understanding NPM (Node package manager) registry and how to install packages using NPM. NPM registry keeps track of the file that has been submitted.

What is harder to learn React or Node? ›

React is a frontend UI library, whereas Node is a runtime environment(Backend). It all depends on where your area of interest lies, or if you're looking to go fullstack, then yes, React is harder to learn than Node.

Top Articles
Latest Posts
Article information

Author: Fredrick Kertzmann

Last Updated:

Views: 6026

Rating: 4.6 / 5 (66 voted)

Reviews: 81% of readers found this page helpful

Author information

Name: Fredrick Kertzmann

Birthday: 2000-04-29

Address: Apt. 203 613 Huels Gateway, Ralphtown, LA 40204

Phone: +2135150832870

Job: Regional Design Producer

Hobby: Nordic skating, Lacemaking, Mountain biking, Rowing, Gardening, Water sports, role-playing games

Introduction: My name is Fredrick Kertzmann, I am a gleaming, encouraging, inexpensive, thankful, tender, quaint, precious person who loves writing and wants to share my knowledge and understanding with you.