Hello everyone,
I have a question about the Bemit convention, just to be sure how you use it and see a possible convergence for all devs :
If you have, for example :
"div" object, with a class "o-item"
with inside 2 elements
"o-item__title"
"o-item__text"
and imagine you want an item inside the title called "icon", let's see if you agree with me :
<div class="o-item">
<h1 class="o-item__title">
<span>Some text here for title</span>
<i class="o-item__title__icon"></i>
</h1>
<p class="o-item__text">Text of item</p>
</div>
Are you shock by the element with the classname : " class='o-item__title__icon' " ?
I know that all of us call him " class:'o-item__icon' ", but sometimes we can need the convention above.
(Explanation of the proposition : o-item__title__icon = Title is a part of Item Object, and Icon is a part of Title of Item Object)
Tell me your opinion, please !
Best regards.
BEM quick start guide says:
An element is always part of a block, not another element. This means
that element names can't define a hierarchy such as
block__elem1__elem2.
In case you need an icon to be part of the title - just add one more Block (called .o-title) to your code, Icon will be an Element of the Block .o-title.
<div class="o-item">
<h1 class="o-item__title o-title">
<span>Some text here for title</span>
<i class="o-title__icon"></i>
</h1>
<p class="o-item__text">Text of item</p>
</div>
This is called mixes in BEM, you can check how it works on the BEM site, but in few words, it means that you can have global styling (font-size, colors, etc.) for .o-title and its icon, that will be used everywhere on your site AND you can have the .o-item__title class to be used for title positioning in .o-item Block.
Related
I have the following piece of html code...
<div class="testimonials testimonials--scale testimonials--increase-shadow">
<div class="testimonials__image-wrapper">
<img class="testimonials__image" src="./assets/images/passion/money-box.jpg" alt="money box: for the poor">
</div>
<div class="testimonials__edge-touch">
<h2 class="headline headline--black headline--small headline--margin-bottom-large ">Fourth Created Forth Fill Moving Created Subdue Be</h2>
<div class="flex flex--align-items-center">
<img class="flex__margin-right-tiny" src="./assets/images/icon/passion_1.svg" alt="circle target">
<p class="paragraph paragraph--grey">GOAL: $2500 </p>
<img class="flex__margin-right-tiny flex__margin-left-auto icon-positioning" src="./assets/images/icon/passion_2.svg" alt="signal sign">
<p class="paragraph paragraph--grey">RAISED: $1533 </p>
</div>
<p>Read More</p>
</div>
</div>
There is 5 blocks 'testimonials, flex(display: flex), headline(for the headers), paragraph and button block'.
* is it a good code?
* what can I do for it to make it better?
It's okay for majority of cases, except of some parts like testimonials--increase-shadow and testimonials--scale.
Let's review the BEM quickly;
Block:
Referring to official documentation, Block Encapsulates a standalone entity that is meaningful on its own, in your case testimonials.
Element:
And elements are Parts of a block and have no standalone meaning, in your case testimonials__image-wrapper.
Modifier:
Flags on blocks or elements to change appearance, behavior or state, in your case headline--black.
Based on that, if you'd like to scale and add shadow to your element, you can have it defined as one variation (modifier). But what you're doing is more of an atomic approach of creating helper classes and adding it as a variation.
Reasoning:
Even though testimonials--scale can count as a modifier, but I presume, you're just adding scale to your testimonial, and that's a helper class. If you do name it like that, you'll limit yourself to only use that for the testimonial block which decreases reusability.
If you need a helper class, just name it globally like scale-up. As helper classes really do not count as modifiers. A good example of a modifier could be a heading and a heading--second where heading-second might have smaller font and different line-height and maybe different color. But simply making it heading--small-font or heading--green would only make your life harder.
Try to abstract a modifier into a more reusable class.
Fore more comprehensive read, check this out
For example:
<div class="menu">
<div class="menu__item">
<div class="menu__item-title">
</div>
</div>
</div>
There's some solution like menu__title.
But if menu has its own title, then how to recognize menu's title and menu item's title?
The main difference is that block__element__element is not a valid BEM selector. The markup you showed in your question is the CORRECT way of naming your elements.
Create a block
If a section of code might be reused and it doesn't depend on other
page components being implemented.
Create an element
If a section of code can't be used separately without the parent
entity (the block).
The exception is elements that must be divided into smaller parts –
subelements – in order to simplify development. In the BEM
methodology, you can't create elements of elements. In a case like
this, instead of creating an element, you need to create a service
block.
More info in the official documentation: https://en.bem.info/methodology/quick-start/#should-i-create-a-block-or-an-element
If you want to have Menu title, the markup should look something like this:
<div class="menu">
<h2 class="menu__title">..</h2>
<div class="menu__item">
<div class="menu__item-title">
</div>
</div>
</div>
BEM gets a bit tricky when you have "children" of an element. But either use the menu__item-title naming convention or rethink your element, perhaps it can be separated and reused as a Block?
Using BEM CSS class syntax, lets say I have an element with the following class:
...
<div class="purchase__module2__heading__tooltip">...</div>
...
Now lets say there is an event or something where this "tooltip" becomes active or visible. What is the proper way to express this with BEM? Do I replace the current class so now it becomes:
...
<div class="purchase__module2__heading__tooltip--active">...</div>
...
or do I add it
...
<div class="purchase__module2__heading__tooltip purchase__module2__heading__tooltip--active">...</div>
...
Or can I just do something simple like this:
...
<div class="purchase__module2__heading__tooltip active">...</div>
...
I think the answer is #2, but it seems very drawn out. #3 is nice and simple but I can't tell if this follows proper BEM guidelines or not.
If you're modifying a block or element you must include the base class as well.
For example
<div class="block">
<div class="block__element">...</div>
</div>
could have the block modified as:
<div class="block block--modifier">
<div class="block__element block--modifier__element">...</div>
</div>
or the element modified as:
<div class="block">
<div class="block__element block__element--modifier">...</div>
</div>
In either case you start needing to use multiple classes.
Looking over your example of:
<div class="purchase__module2__heading__tooltip">
It's clear that you're nesting too deeply, preventing yourself from being able to reuse the majority of your code.
Given the names you're using, I'd guess that what you actually have is:
a purchase module (.purchase-module)
with a heading (.purchase-module__heading)
a tooltip (.tooltip)
The markup could look something like:
<article class="purchase-module">
<h1 class="purchase-module__heading">
...heading text...
<span class="tooltip">...</span>
</h1>
</article>
Note how making the tooltip active now just requires changing a short class:
<span class="tooltip tooltip--active">...</span>
That's the ideal with BEM.
You are right and the answer is #2.
Here's why:
https://en.bem.info/methodology/faq/#why-include-the-block-name-in-names-of-modifier-and-element
https://en.bem.info/methodology/faq/#how-do-i-make-global-modifiers-for-blocks
BTW, you shouldn't keep DOM structure in naming. And here's why: https://en.bem.info/methodology/faq/#why-does-bem-not-recommend-using-elements-within-elements-block__elem1__elem2
I just started out using BEM and SMACCS for my stylesheets but have run into some trouble as far as naming deeply nested elements in the DOM. Say for instance I have a div called .main-container. Nested inside the first level of the main-container is an additional div which by convention would be named .main-container__article.
<div class="main-container>
<div class="main-container__article></div>
</div>
This is where things get confusing. Inside that article div let's say I have a header followed by a paragraph that has a nested span tags. Do I continue prepending classes with main-container__article as so?
<div class="main-container>
<div class="main-container__article>
<h1 class="main-container__article__header">Heading</h1>
<p class="main-container__article__copy">
<span class="main-container__article__copy__intro-text>Example text.</span>
</p>
</div>
</div>
How far down does the rabbit hole go when it comes to naming parent/child elements? Is there a point where you reset at the second-level element and go from there?
<div class="main-container>
<div class="article>
<h1 class="article__header">Heading</h1>
<p class="article__text">
<span class="article__text__intro-text>This is example text.</span> for a paragraph
</p>
</div>
</div>
BEM naming shouldn't resemble DOM structure because otherwise you won't be able to change markup without changes in CSS.
So for your example I'd make it like this:
<div class="main-container">
<div class="article">
<h1 class="article__header">Heading</h1>
<p class="article__copy">
<span class="article__intro-text">Example text.</span>
</p>
</div>
</div>
There's also a quite powerful thing called mixes, which gives possibility to mix different BEM entities on the same DOM node:
Heading
Example text.
So now you may apply CSS to article block and main-container__article element separately which is very useful when you need to reuse article outside main-container.
.main-container__article__copy__intro-text
definitely doesn't help the readability and maintainability of your stylesheets.
I suggest to break such giant blocks into several smaller blocks. If you do this, you can reuse your styles - in your example you couldn't use the article-block somewhere else.
I would "reset" everytime you can encapsulate a block which can potentially be used in several places in your app/website.
With HTML5, there were many additional elements added for structuring documents like blog posts or long texts. But what I have problems coming up with is a semantic way of structuring UI components.
On a typical webapp, you have many different components such as modals, button elements, interacitve forms, containers, and so on. Often, I see those things being constructed using div and span only or by misusing header, footerand nav elements and I get the feeling I missed something out.
Is it really semantic to create all structural, not content-related elements using the div element only? Will there be a more diverse element choice in the future?
EDIT: Here's a short example of what I mean:
<div class="modal foo">
<div class="inner wrapper">
<div class="upper bar">
<div class="inner">
<div class="window-name">
<span class="upper heading">
<h1>Foo</h1>
</span>
<span class="lower heading">
<h3>Extra Baz</h3>
</span>
</div>
<div class="buttons">
<div class="button close"><span class="icon"><i>×<i></span></div>
<div class="button maximize"><span class="icon"><i class="fa fa-maximize"><i></span></div>
</div>
</div>
</div>
<div class="content well">
<!--
Whatever happens inside the modal window named foo.
Pretty sure it needs many divs as well, though.
-->
</div>
<div class="lower bar">
<div class="buttons">
<div class="button help"><span class="icon"><i>?<i></span></div>
</div>
<span class="info">
<p>Enter your barbaz.</p>
</span>
</div>
</div>
</div>
The last W3C working draft for HTML 5.1 was released two days ago, on April, 13, and it is "semantic-centered": see
http://www.w3.org/TR/html51/Overview.html
It is an interesting reading, while waiting to have all those fancy things implemented by the most common browsers.
Is it really semantic to create all structural, not content-related elements using the div element only?
Not in my opinion. Even without to cite "the media is the message", everything has something to do with the content, even "open" and "close" buttons allowing users to see the content.
Will there be a more diverse element choice in the future?
Of course! And with a lot of proprietary prefixes, as usual, just to keep our life busier.
Ignoring div and span elements (which are meaningless, except for the case of specifying some meaningful attributes), your snippet consists of this:
<h1>Foo</h1>
<h3>Extra Baz</h3>
<i>×</i>
<i></i>
<!-- content -->
<i>?</i>
<p>Enter your barbaz.</p>
This is what your content looks like from the semantic perspective. Not very clear what gets represented here.
Using a heading element for a subtitle (h3 in your case) is not appropriate. (Or, if it’s not a subheading but really a new/own section, don’t skip a heading level; but I’m assuming the former.) Use one heading element, and use p for the subheading, and group them in header.
Using i elements for adding icons via CSS is not appropriate. Either use CSS only (with the help of existing elements), or, if you have to add an empty element, use span.
Using span/div elements for buttons is not appropriate. Use button instead.
As you are already using a heading element, it’s recommended to explicitly specify a sectioning content element. Depending on the context of this content, it may be article or aside (or nav if it’s for navigation), but in all other cases section.
Following this, you’d get:
<section>
<header>
<h1>Foo</h1>
<p>Extra Baz</p>
</header>
<button>Close</button>
<button>Maximize</button>
<!-- content -->
<button>Help</button>
<p>Enter your barbaz.</p>
</section>
Now you may add header/footer elements for those parts that are not part of this section’s (not this document’s, it’s only about this section!) main content.
You may, for example, enclose the maximize/close buttons in a header (however, opinions if this would be appropriate differ).
HTML 5.1 will probably have a menu element and a dialog element, which might be useful in this case.