Let's say I have a product within a collection. Is it appropriate to call the product "feature-collection__product" so it's still an element within the block of "feature-collection" or call it "feature-collection-product" so it becomes it's own block, as it has other elements within it, or something different.
<div class="feature-collection">
<div class="feature-collection__product">
<h2 class="feature-collection__product-title"></h2>
<h2 class="feature-collection__product-price"></h2>
</div>
</div>
OR
<div class="feature-collection">
<div class="feature-collection-product">
<h2 class="feature-collection-product__title"></h2>
<h2 class="feature-collection-product__price"></h2>
</div>
</div>
Most likely the correct answer is both:
<div class="feature-collection">
<div class="feature-collection__product product">
<h2 class="product__title"></h2>
<h2 class="product__price"></h2>
</div>
</div>
The situation when you have different entities on the same DOM node is called mix. In this case it's reasonable to have independent block product and also an element of feature-collection to set some styling for production inside feature-collection.
For more info about mixes please take a look at https://en.bem.info/methodology/key-concepts/#mix and https://en.bem.info/methodology/faq/#mixes
Related
I have a question regarding BEM (Block Element Modifier) class naming conventions.
What if I need to have 3 nested divs, how should I name the class of the 3rd one?
.one{} //block
.one__two{} //block element
//?
<div class="one">
<div class="one__two">
<!-- How should I rename class "three"? -->
<div class="three"></div>
</div>
</div>
I want to rename ".three" to "one__two__three", or "two__three", but I'm not sure that this is right, because as I understand, according to BEM nesting elements inside of elements is not allowed.
To me, it's about relationships, particularly key-value relationships, so I would approach it that way.
Without exploring contextual naming paradigms, it could be suggested to use one__three.
Alternatively, if one is simply a container for two, then one could be renamed two__container and three renamed to two__item. Of course that doesn't make a whole lot of sense using numbered labels like this, but I hope you can see where it could lead.
Nesting elements is fine; build the structure to your needs. The important thing is to not couple the classnames to your nesting. The classname schema does really only recognize two types of DOM elements: the block itself and the elements of that block; of the latter all are equal regarding the naming schema, no matter how deeply nested in the block.
Here is an example:
<div class="product-card">
<div class="product-card__img-area">
<img class="product-card__product-picture" src="https://example.com/cabulator.jpg"/>
</div>
<div class="product-card__header">
<span class="product-card__main-headline">Encabulator</span>
<span class="product-card__sub-headline">The turbo shmeerf of all Shmoof</span>
</div>
<div class="product-card__text-body">
Lorem ipsum shmeerf of Shmoof quooz bar moof bla bla
</div>
<div class="product-card__footer">
<a class="product-card__cta" href="https://example.com/buy.html">Buy it!</a>
</div>
</div>
And modifiers are added as needed:
<div class="product-card__footer">
<a class="product-card__cta product-card__cta--bargain" href="http://exmpl.com/buy">
Buy it! 50% off for first-time customers!!!!!! OMG!!!!
</a>
</div>
I would like to know if, according to BEM methodology, I can have the following structure:
.block1
.block1__element1
.block2
.block1__element2 <-- ??
Am I allowed to use an element from a parent block, inside a children block?
Thanks.
UPDATE:
This is the actual DOM structure:
<div class="head">
<div class="head__user"></div>
<div class="head__nav">
<div class="menu">
// <-- ???
</div>
</div>
</div>
According to best practices of BEM methodology: am I allowed to move the element with head__user inside the menu block? Or all elements inside the menu block need to start with the menu__ prefix?
I hope this clears out the problem.
I been using BEM for sometime and from what I got it's not recommended nor intended to be used like that. You can nest different BEM elements to each other like menu-blockintohead-block, but menu-block items should not go outside its parent menu-block, like you should not put menu-block__item at the top of head-block. Does it makes sense? :)
To illustrate there are two ways to go. What should be noted here is that depending on the scale of your project and how you build things (component based?). If you don't have a large project and are not doing or reusing the menu else where you can do it both ways. Lets say your menu is huge amount of html/css I would do it like #1
This is not correct
<div class="head">
<div class="head__user"></div>
<div class="head__nav">
<div class="menu">
<div class="head__something"></div>
</div>
</div>
</div>
Recommended solution
Based on this part of the documentation. Now you can chop your own header design into blocks, does this below match?
<div class="head">
<div class="head__user"></div>
<div class="head__nav">
<div class="menu">
<div class="menu__something"><img src="" class="menu__image" /></div>
</div>
</div>
</div>
I think this variant is allowed:
<div class="head">
<div class="head__nav">
<div class="menu">
<div class="head__user"></div>
</div>
</div>
</div>
I haven't found the current part in the official BEM documentation, but I've found this part:
The block name defines the namespace, which guarantees that the elements are dependent on the block (block__elem).
A block can have a nested structure of elements in the DOM tree:
Example
<div class="block">
<div class="block__elem1">
<div class="block__elem2">
<div class="block__elem3"></div>
</div>
</div>
</div>
However, this block structure is always represented as a flat list of elements in the BEM methodology:
Example
.block {}
.block__elem1 {}
.block__elem2 {}
.block__elem3 {}
This allows you to change a block's DOM structure without making changes in the code for each separate element:
Example
<div class="block">
<div class="block__elem1">
<div class="block__elem2"></div>
</div>
<div class="block__elem3"></div>
</div>
The block's structure changes, but the rules for the elements and their names remain the same.
I understand it as there is only one rule about HTML structure for elements in BEM: an element has to be inside its block (it doesn't matter how deep).
One possible problem that I can imagine for this case is using some of BEM tree formats. But if you don't need it, I think there's no problem.
I would consider making the potential head__something into simply something, and then to provide multiple modifications of it. e.g. something--head and something--menu.
<div class="head">
<div class="head__user"></div>
<div class="head__nav">
<div class="menu">
<div class="something--menu" />
</div>
</div>
<div class="something--head" />
</div>
Also, refactoring further, I would consider getting rid of head__nav as it probably does not add any richer semantics than menu.
<div class="head">
<div class="head__user"></div>
<div class="menu">
<div class="something--menu" />
</div>
<div class="something--head">for those cases where you want <code>something</code> directly descending from <code>head</code></div>
</div>
I have a doubts about this HTML structure. Is it correct according to BEM approach?
<div class="boxWithBorder">
<div class="header">
<h2 class="boxWithBorder__element"></h2>
</div>
</div>
To my mind it should look like that
<div class="boxWithBorder">
<div class="header">
<h2 class="header__element"></h2>
</div>
</div>
What keeps elements encapsulated.
Generally we do components and structures, that means structures are compositions of components. It will require nesting so that part is ok. As far as your first approach that is not ok by our standards and not used. block1 should not live inside block2 but block2 has to live inside block1 as it's a nested component. Makes sense? BTW BEM is perfectly fine to use and a lot of frontend devs do it, heavyweights as well, check out csswizardry.com for instance, he got some great articles about BEM
Also I would suggest the following using BEM (or any html/css for that matter) is that skip the camleCase and use "-" instead
<div class="box-with-border">
<div class="header">
<h2 class="header__element"></h2>
</div>
</div>
<div class="hero hero--red-with-border">
<h1 class="hero__title>Title...</h1>
<p class="hero__body-text">Text...</p>
</div>
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.
I am using microformat for the first time.
So as examples given on http://support.google.com/webmasters/bin/answer.py?hl=en&answer=164506, I changed the code.
This is the existing code that was present on the page:
<div class="evD mr10">
<div class="imgH fl"><img /></div>
<div class="infAr">
<h3>EVENT NAME</h3>
<h4><span>at</span>VENUE NAME</h4>
<p>Event Description</p>
<a class="tdd" href="#">Genre</a>
</div>
<div class="dth">
<div class="sfrD fl">
</div>
<div class="strE sn fl">
</div>
<div class="Buy">
<a class="bkT" href="buy_link"></a>
</div>
</div>
</div>
The Changes I made include :
Change the doctype to html5, and added microformat classes.
<div class="vevent evD mr10">
<div class="imgH fl"><img class="photo" /></div>
<div class="infAr">
<h3><a class="url summary" href="event_URL">EVENT NAME</a></h3>
<h4 class="location"><span>at</span>VENUE NAME</h4>
<p class="description">Event Description</p>
Genre
</div>
<div class="dth">
<div class="dtstart frD fl">DATE_START<span class="value-title" title="Date in ISO"></span></div>
<div class="dtend strE sn fl"><span class="value-title" title="Date in ISO"></span></div>
<div class="Buy tickets">
<a class="bkT offerurl" href="buy_link"></a>
</div>
</div>
</div>
I have the following questions/doubts :
Is it ok to have existing classes alongwith the microformat tags as done above?
As mentioned on http://support.google.com/webmasters/bin/answer.py?hl=en&answer=1093493#usage, it is not allowed to have display:none on the content. However, I pass the data set and paginate using javascript, in which I show the relevant data. So how do I make sure that these is not ignored.
I load the images which are on the current page, leaving the src as blank, and later change the src, as the page is changed. So initally the event's photo is blank.
How do I counter from a search engine reading as blank.
Thank you.
(Sorry about the question being so long)
1) that is no problem. You can even combine multiple types of semantic markup on the same tags.
2) 3)
If the data is hidden and in JavaScript/AJAX then it is highly unlikely Google will see it.
You may have to restructure your architecture to make your content crawlable. That's a big subject. I suggest looking up "progressive enhancement" which is the method I currently think is best.