Why BEM and clear naming conventions make your CSS more maintainable
Last modified: 3rd March 2025

One of the biggest challenges in front-end development is maintaining scalable and conflict-free CSS. A lack of structure often leads to unintended styling conflicts, making debugging frustrating and time-consuming. A prime example? The .active
class issue—when a generic class name affects multiple elements unintentionally.
The best way to avoid this? Use the BEM (Block, Element, Modifier) methodology and establish clear naming conventions. In this post, I’ll break down why this approach is so effective and how you can implement it to keep your styles organized and maintainable.
The problem with generic class names
Imagine you’re working on an existing WordPress project, where another developer has been building elements. You build a block of code like this, and style the active class:
<div class="accordion">
<button class="accordion-button active">
</button>
<div class="accordion-panel">
</div>
</div>
.active {
color: red;
}
That will make the button red when the button is clicked, but what you may not know, is that there’s another block on another part of the site that’s also using .active
. Now that also has the color: red
; applied. This happens because generic class names lack specificity, leading to unintended global styling conflicts.
This is where BEM and strict naming conventions come to the rescue.
The BEM Approach: Structure and Clarity
BEM (Block, Element, Modifier) enforces a strict, structured approach to class naming, making styles modular and preventing conflicts. Here’s how it works:
- Block: The parent component, representing a standalone entity.
- Element: A child inside the block that has no standalone meaning.
- Modifier: A variation of a block or element that alters its appearance or behavior.
The code above would work better as a standalone component if coded like this:
<div class="accordion">
<button class="accordion__button accordion__button--active">
</button>
<div class="accordion__panel">
</div>
</div>
The styles in scss:
.accordion {
&__button {
&--active {
color: red;
}
}
}
Or CSS if you prefer:
.accordion__button--active {
color: red;
}
Example: A Testimonial Block
Instead of using vague class names like .content
, .image
, or .title
, BEM ensures every class is tied to its parent block:
<div class="testimonial">
<div class="testimonial__content">
<h2 class="testimonial__title">Customer Testimonial</h2>
<p class="testimonial__text">"This service was excellent!"</p>
</div>
<div class="testimonial__image testimonial__image--rounded">
<img src="customer.jpg" alt="Happy customer" />
</div>
</div>
And the corresponding SCSS:
.testimonial {
display: flex;
justify-content: space-between;
align-items: center;
gap: 2rem;
padding: 2rem;
&__content {
width: 50%;
}
&__title {
font-size: 2rem;
font-weight: bold;
}
&__text {
font-style: italic;
}
&__image {
width: 40%;
// Modifier for rounded image
&--rounded {
img {
border-radius: 50%;
}
}
}
}
This structure ensures that styles remain self-contained and do not interfere with other components.
Naming conventions: Keep it clear and consistent
To further reinforce modularity and avoid conflicts, it’s essential to follow these best practices:
1. Always name your SCSS files after the block name
If you create a new block, its SCSS file should follow the same naming pattern:
/src/sass/blocks/_testimonial.scss
That way when you end up with lots and lots of code, your file system should look like this:
/src/sass/
├── __hero.scss
├── __nav.scss
├── __testimonial.scss
This keeps files easy to find and ensures styles remain component-specific.
2. Start a new SCSS file for a new naming convention
If you need a fresh set of styles that aren’t linked to an existing block, start a new SCSS file instead of repurposing an old one. This forces you to think about naming more carefully and prevents vague class names that might unintentionally overlap with other components.
Don’t worry about creating dozens of new .scss files – that’s ok! Your SCSS will all get compiled at the end anyway.
3. Avoid global class names (e.g., .active
, .content
, .box
)
Global class names should be reserved for utility classes and never used for block-specific styles. Instead of .active
, use .button--active
or .menu__item--active
to ensure specificity.
4. Use meaningful and descriptive names
Bad example:
.card .content {
padding: 1rem;
}
Better example:
.card__content {
padding: 1rem;
}
This small change eliminates ambiguity and makes it clear which component the styles belong to.
The Benefits of BEM and Naming Conventions
- Prevents style conflicts – No more unintended CSS overrides from vague class names.
- Easier maintenance – When you need to update a component, you know exactly where to look.
- Scalability – As your project grows, structured class names prevent chaos.
- Reusability – You can copy and paste a block’s SCSS into another project without worrying about global conflicts.
To sum up
Using BEM and strict naming conventions isn’t just about organisation – it’s about preventing common styling headaches before they happen. If you’ve ever spent hours debugging unexpected styles, this approach will save you time and frustration.
By always naming your SCSS files after the block name, avoiding generic class names, and ensuring every new convention gets its own SCSS file, you create a robust, maintainable, and scalable CSS structure.