Does an element in BEM need to be inside a block? - css

I have a question regarding BEM. Is it ok to have a .block__element on its own with having a block as a parent? I'm building a site with WordPress where there are a lot of other classes from the theme, page builder and plugins, so the need to have parent blocks sometimes makes it all a bit messy. So is this then ok, to have a block__element on its own and then style it via SCSS, or should I add a block to the footer to do this properly?
HTML
<footer id="footer">
<div class="theme-class page-builder-class">
<div class="footer-block__text">Some footer element text</div>
</div>
</footer>
CSS
#footer .footer-block__text {
color: #ffffff;
}

My opinion would be no, for two reasons:
BEM is designed to enforce module separation, so that they are easier to reason about, and to minimize the risk of styles leaking from one module or block to another. If you're mixing BEM blocks with non-BEM code, you're not really doing BEM.
Blocks are designed carefully and assume inheritance from block to block__element. Without seeing any code I of course can't say for sure, but it's possible that the styling of block__element depends on inheriting some rules from block. If the library designer can't assume that all block__elements have a block ancestor, then there's no benefit in structuring the library this way. For instance, if block defines display:flex, and block__element has flex-grow:1, the latter will have no effect without a block parent. If it's getting display:flex from some other ancestor, again you're not really doing BEM.

I think you can mix BEM classes with others in a lot of cases. BEM could be mixed with other methodologies, with some old code, or even with medium specific classes.
For example, I used to mix methodologies:
You have specific changes to make to a block that are not based on logic. In this case, I would prefer use a utility class (ex: .u-uppercase) that will be shorter to write and available for every blocks, than to write an non-logical BEM modifier (ex: .title--uppercase)
You have a layout class (that distribute the screen space) that your repeat in multiple blocks. In this case, I would prefer use an OOCSS object class (ex: .o-container) that will reduce BEM complexity, than to write the same BEM element everywhere (ex: .header__container).
You could find a great presentation about extending BEM here: Modular CSS at Rangle.
From my experience, I tried to mix OOCSS (with l- prefix) and BEM classes (with p- prefix) when building this website https://www.netalis.fr. It was strange at first, but finally very useful and stable.
An example from netalis website:
<!-- HEADER BLOCK -->
<div class="p-header p-header--hero">
<!-- NESTED BLOCK -->
<div class="p-menu"></div>
<!-- OBJECT CLASS -->
<div class="l-container">
<!-- HEADER ELEMENT -->
<div class="p-header__content"></div>
</div>
</div>
It works because theses external classes are:
Isolated from BEM classes, for example no selector that mix both (.p-header > .l-container)
Immutable, the utilities/object classes should not change over time.
So my question is: Does your page-builder-class isolated and immutable?

Related

What to do when the Block element in a BEM component doesn't need any styles?

Let's say I have a structure like this:
<article class="product">
<header class="product__header">
<h1 class="product__headline">Headline</h1>
<img class="product__hero" src="" alt="">
</header>
<p class="product__description">Content</p>
</article>
As the Block element article brings all the styles it needs by default, it actually doesn't have any CSS. So I'm not defining it in the CSS like this, because it only clutters the styles:
.product { }
But I'm unsure about the HTML. Should it be
<article class="product"></article>
… anyways or simply …
<article></article>
… as there are no styles attached?
What is the right thing to do when usin BEM?
As I understand it, the idea with BEM is to use a standard and have a markup ready for any present or future CSS, so you would always include the class, even if you don't use it right now.
Another good reason is that the parent class improves readability and order for anyone looking at the markup. I would even suggest you to include the class in your CSS and left it blank, functioning almost like a subtitle, with the potential to be useful later on.
Finally, BEM recommends against nesting elements in the stylesheet, which means preferring the use of classes even in the smallest children (like a strong tag inside a p). Seems natural, then, to have a class in the parent as well.
Keep the class to keep your independence. Future changes might require you style . This approach has several advantages:
In 2 months you'll still be able to determine the module components and structure without further ado
You and everybody else will know that is the component container even if you add further wrapping elements in-between.
You might be able to alter the layout without touching the HTML
No dependency between HTML semantics and layout.
All present structure is mirrored into the layout so you can see all variants and elements in the CSS. Get things out of your head
Finally, I agree with you that CSS clutter isn't nice but it could be useful, especially when you're working on a larger codebase with a larger team where you need to rely on standards.
On your parser/IDE: it will probably be configurable to ignore such entries. Your build process should be able to remove these empty selectors so it doesn't make its way into production CSS.
I have come across a similar scenario, If you are following BEM, then keep that class in the article element, since it will help in maintenance(such as removing unused styles, better understand markup).
for example(in product.scss):-
.product {
&__header {
font-size: 1.7rem
// etc...
}
}
Hope this helps. Happy coding....
Note:- Depends upon your markup, you can hoist block element class responsibility to the parent element and updated child class with new parent class.(eg:- .root__prdHeader)

BEM Common Styles

What is the best way of defining general non-block-specific styles throughout the site?
For example:
html
<div class="intro">
<p class="intro__text">foo</p>
</div>
<div class="profile">
<p class="profile__text">bar</p>
</div>
sass/css
.intro__text {
}
.profile__text {
}
.text {
margin-bottom: 0.5em;
}
If I wanted the text to be styled the same, would I (given I am using a pre-processor) #extend .text into the .intro__text and .profile__text classes, or just have all paragraphs throughout the site have a class of text?
Both those solutions seem slightly incorrect to me.
If I have a very common style, it feels like I'm going to be duplicating a lot of styles throughout my rendered css (bumping up the filesize) but having a class of text repeated all throughout my markup seems unnecessarily verbose and untidy.
Is there a best practice for this situation?
I can't say that there is the best way to do it. It depends on the structure of your project and what style your prefer. Both approaches are used in mostly code.
If you like to manage styles through css files - write #extend. However in case you want an element without common style you have to create a modifier for the el. For example - .profile__text--reset.
If you want declare common styles, your class list with common classes may become too long. But it is more clear and specific. And you have a possibility to manage it via javascript.
One improvement for this code is that it is better to use helpers with modifiers. For example, instead of simple .text use .text--sm or .text--m-sm. Or if you want only margin - .m-sm. But it is up to you.
You have several options:
Preprocessor (Sass/LESS/etc) mixins + clean-css/postcss cleaner — this way is simple and powerful, but not flexible, since it's not useful for dynamic landing pages, SPA, etc.;
Element of outer block mix (BEM/runtime mixin): class="intro__text grid__text" — in that way you just splitting manually visual and positioning styles and use their classes together;
Other block mix: class="intro__text paragraph paragraph--valuable" — almost like the previous variant but without linking to the abstract grid block, the best and the most flexible way (IMHO).
NB: Also you can extend BEM mixes with modifiers even in runtime, it's VERY powerful tool.
NB2: If you don't need dynamic web pages, you can freely use sass mixins. Personally I don't use sass/less mixins, only global variables for colors, grid, gaps, etc used in my own classes.

BEM and single selectors

This is sort of a theoretical question, but it bugs me for a couple of hours now.
I'm learning BEM and it's great so far, but I have a problem. Let's say I have this code:
<div class="section-hi main-section">
<h2 class="main-section_header">Blah</h2>
<p>Generated from the CMS</p>
</div>
How do I target the p to make it good with BEM? Can I just go with
.main-section p
or this would be against the rules? I coudn't find any answers to this, since every example and article about BEM focuses only on classes, and I can't expect my CMS to add different class to every groups of paragraphs.
One of the concepts of BEM is to create reusable components, using an element such as p goes against that.
Why?
By specifying p we are restricting the ways in which our component can be used. To display correctly the p tag must be used. For example the following markup would not work with the component.
<div class="section-hi main-section">
<h2 class="main-section_header">Blah</h2>
<span>Generated from the CMS</span> <!-- this will not pick up the styles -->
</div>
Specificity
Another important point is BEM aims to keep specificity to a minimum, using single class names. Creating a style with a p increases specificity.
.main-section p
It is now hard for me to override this style with a utility class, as it has a higher specificity than a single class.
More on CSS specificity
The solution
So instead the idea is to use class names to describe the element. That way we can choose to use whatever markup we like and the component will display as expected. e.g.
<div class="section-hi main-section">
<h2 class="main-section_header">Blah</h2>
<h3 class="main-section_subHeader>Generated from the CMS</h3> <!-- This will work -->
</div>
Must I always use class names?
You will find occasions when it is OK or necessary to create styles for elements and not use class names. For example you may have a component that you only want to be used with certain markup. Then it is perfectly valid to do so.
Summary
As a general rule always try and keep to the single class rule unless there is a valid reason not to do so. Otherwise it will trip you up later on down the line.
For further reading on BEM I recommend this post http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/
If we just look on this code - you can do that, but what if you have more <p> elements? If you can't add class to every element, you can always add id and call element by
#element_id{ }

Should I bother adding a class on a <main> tag?

Should I bother adding a class on a <main> tag?
I try to avoid poor selector Intent like header {} to avoid risk of applying very specific styling to a very wide number of elements in my project, but according to MDN:
There must not be more than one <main> element in a document
So I wonder, if I use a simple selector like main {}, would this still be considered a bad practice?
well, while I understand your premise, my answer is yes without a doubt. I use it a lot, and I develop custom WP sites and templates, so I add classes to main element in order to have only a stylesheet, then I can target the main element for different templates from the same stylesheet or re-using declarations with minimal changes. For example: main element on index page will usually differ from main element's content on inner pages, archives, search pages, etc, specially on highly customized sites
Of course, if that's not your case, then there's no need and it's probably better to leave it without a class, but this goes also in taste. I tend to build my themes with classes, no matter if unused. This way, if a client or user needs to use that element at a later time, is easier to do it.
Needless to say, from a semantic point of view:
<main class="index">
<main class="page">
<main class="archive">
<main class="blog">
looks a lot better than just <main>
All this being said, it depends on your and your workflow, it's not set in stone, like many HTML5 and W3C recommendations

Multiple classes in body tag, multi-dimensional css structure or blueprint for insanity?

This question is about an approach to css structuring, and so is more discussion oriented.
I'm working with some outsourced css where the body tags have multiple classes assigned, up to half a dozen. (To make things a little worse, none of the css selectors include an html tag which is making it confusing to analyze the css.) These body classes are then used to modify classed or id'd widgets within.
It seems like this approach is like adding an additional dimension to the css, perhaps in some attempt to create a structured css approach. Documentation might have helped, had we been provided any.
This differs from my approach where widgets are styled primarily via id'd divs, perhaps extracting the more generic elements into a class, i.e. div#MyWidget.widgets.
Any ideas on whether such an approach is maintainable, especially considering I am dealing with websites with thousands of pages including tons of legacy stuff, all done by different people with different skill levels? Thanks...
I find nothing particularly wrong with this approach, provided you are conceptually using the body tags to apply very general style rules. The higher up the class is in the DOM, the more generic it should be.
It's hard to answer specifically without examples. One I frequently use is to turn the URL segments into classes for body tag in my pages, for relatively small sites:
// mysite.com/users/show/
<body class="users show">
<div id="Content">
...
</div>
</body>
I use this almost exclusively for overriding default styles on very specific pages:
#Content {
width:500px;
}
.users.show #Content {
width:600px;
}

Resources