BEM Advice
I'm trying to use BEM in CSS, but I'm not sure how I should name these classes: I have a task element used throughout a block (game) and an input element that appears inside both sub-sections of the game (solution and question screens). How should I name the elements properly?
My current structure:
I can't just name both of them
game__input because they should have different CSS rules.
Also, do I have to say game__solution or is it okay to create a nested block (just solution)?
How should I write this so that it follows BEM?
NOTICE: I just used divs here for a simplified example23 Replies
BEM = Block Element Modifier.
Your input class would be "Block Element Element". That's not correct.
It would be
game__input
If you need a different variant for each you use modifiers like this
game__input game__input--solution
And
game__input game__input--questionOkay, I get it š
But the game has a lot of tags, so it might be confusing to have everything under the same
game block, right? But I guess that's how it works.Make sure you think in components.
In a card there might a button component which required a different block, it's just nested inside it.
1. But I should only "use" new block names if the component is unrelated to its parent, right?
This would be wrong?
Because the solution block is not a standalone block but it depends on the game block. So, it should be
game__solution to indicate the dependency?
2. And also, is it common practice to simply assign a class name to all HTML elements, even if you don't actually need to style them (Or later you might want to)?I want to suggest something different. Why BEM? You can simply use semantic elements and assign a parent class. You can add some child classes too if they make sense, but you're nesting BEM classes 2 levels deep and I think that's where it starts to get messy
I can't suggest which semantic elements to use because I'm not sure your usecase but what about something like:
This way you can just target your classes like
See how much simpler that is? If you used semantic elements for
.task and .input you wouldn't even need class names for those either (unless you're using reusable styles)
Though I will say something contradictory. You probably should assign a class name to those nested .solution elements because it's a bit easier to understand what they are. E.g having a div vs. having a div with class name .task tells me what it is, and then target that class name in the selector. My 2cents
Another question to ask too is do you even need separate class names or selectors for these? Are you applying specific styles for the tasks inside .solution vs. .question? Or will all .tasks and .inputs be styled the same?
No
Adding a class to an element which does nothing is confusing to yourself and other developers when they inspect the markup in the DOM. I actively avoid / remove any unused classes in my HTML & CSS when I spot themThat's a lot more complex then using BEM for example.
How?
:is() is just a way to select multiple elements in one line. You can separate them out if that's what is making it more complex:
This is equivalentThat's more complex then just writting
game__input tho.
You'd be writting like this
I am not saying that your solution is a complex solution but it's more complex then just writting the classnames.I don't agree, I think it's more complex to think of how to write the correct class names using BEM than to just keep it simple (and it's proving my point by the fact that they created a post for this)
They would have created a post for selectors as well if they where using that...
How so?
BEM isn't that hard, neither is your solution.
To better understand BEM, I came across a list of real-world websites that use BEM (https://github.com/benbrehaut/bem-examples). I have a question about one of the websites (see image): Why is there a
wrapper block inside a page-head block, and the wrapper block contains a page-head__text? Because page-head__text should only be a child of its own block page-head and not wrapper?
Idk, but you can have object classes that act as containers around elements.
So it's okay to have utility/object classes (that's the same right?) in a block but something like this would be not allowed:
Utility and object classes aren't the same.
yeah, one of the biggest mistakes people make with BEM is thinking every child has to be part of that block, but it doesn't.
I see this all the time:
Chances are, that button looks the same as all the other buttons on your site, so it can just be a
.button. That's just a block that happens to be living in another block.
wrappers are a great example of this too.I like to do just
.c-btn I like it short.
This is why developers should have some understanding how design works, cuz in design especially in figma they work in components. I usually use a different block class when there is a new component that I use in figma.
With that card example you can even do easier if you know you gonna have just 1 h2 and a p tag you don't even need the class there and use the tag directly nested like this.
It keeps the html cleaner.
And it will only style the h2 and p within the c-card.I thought one point of BEM was to give h2 and p a class for future-proofing too?
it is, nesting like that wouldn't be how you'd work with BEM, if you are going that way.
There are advantages to having classes for things like the heading, since the heading level can change. There are ways to write CSS that can deal with that as well... a lot of it comes down to how much time you want to spend making the css more robust, vs just using the right classes where you need them.
Encapsulating new components early also saves you from insanely deep and rigid classes like
card__header__row1__author__avatar__online-status
Chances are that avatar can be reused else where so it should be its own component and so onThat's bad BEM
Ah that's what you said
Yes lol