Confusion with BEM class naming convention. One level deeper - html

For example I have a menu block with menu elements:
.menu
.menu__element
.menu__element--current
But lets say .menu block is contained inside another block, .header
How to deal with naming in this case?
.header
.header__menu
.header__element
or
.header
.header__menu
.header__menu__element
or
.header
.menu
.menu__element

Consider using "mixes" (more than one BEM entity on the same DOM-node):
<div class="header">
<ul class="menu header__menu">
<li class="menu__element"></li>
<!-- ... -->
</ul>
</div>
So block menu is also element header__menu at the same time. That gives you the ability to apply styles for any abstract menu and add special rules for that particular menu inside the header.

The menu should be a class unto itself so .menu should suffice. If it's a menu that is ONLY in a header and never anywhere else, then .header-menu. Then you can point to the menu directly without going through the header class.
If you prefer to do it the way you outlined, then .header_menu.

<div class="header">
<ul class="menu">
<li class="menu__element">...</li>
<li class="menu__element menu__element--current">...</li>
...
</ul>
</div>
.header {...}
.menu {...}
.menu__element {...}
.menu__element--current {...}
will be right.
Block name does not change when block inserted into another block.
BEM prohibits put an elements in the elements and write classnames like block__element__element, more info: How to properly set an element's scope using BEM?

Here's what the official documentation of BEM says (http://getbem.com/faq/#css-nested-elements);
No matter how deep you're nesting, you always use the top parent as block element. So basically it would be;
.header
.header__menu
.header__element

Related

Avoid one single <li> tag getting styled by css

I'm not a pro with CSS and I've been struggling with this for hours.
So I have this in the CSS:
li { margin-bottom:6px;}
I want the photos in a gallery to have bottom margins. But in my site menu, I use <li> tags too, and they are affected by this rule.
How can I avoid a style conflict between the photos and the menu items?
This image has white space between the purple and the black line--that's the margin-bottom.
In your HTML, inside the <li> element, you can declare a style using the class attribute. For example:
<li class="menu">
Then, in your stylesheet, you can specifically refer to this class of list item with the . operator:
li.menu { margin-bottom: 6px; }
As remarked on in the comments, you should take the time to read/watch a tutorial. Here's one from Khan Academy that's designed as an introduction
You can exclude an element using the CSS 'not' property. Here's how to:
set a class for those elements you don't want to be affected by general CSS like: <li class="excluded"></li>
Change your CSS to
li:not(.excluded){
margin-bottom:6px;
}

css for the first direct child only

I have the following html structure:
<div class="nav-collapse">
<ul class="nav">
</ul>
<ul id="registerCart" class="nav pull-right">
</ul>
</div>
and I wanted to apply the following rule only to the first nav, so I did:
.nav-collapse > .nav {
left: 135px;
}
however this is applying to the registerCart as well. How do I apply this only to the first nav?
Use the first child selector:
.nav-collapse .nav:first-child {}
You can combine it with the direct child selector if you have more nested .nav elements.
.nav-collapse > .nav:first-child {}
The > operator means that it will select only the matching children that are a direct child (thus one level deep) of the defined parent, instead of matching all children on all levels from the defined parent.
Using :first-child is perfectly ok but some problems could arise in IE7 and IE8 when dynamic content is involved. See http://www.quirksmode.org/css/selectors for known issues. When in doubt, select the first child by it's class or id attribute.
If you change the class 'nav' to 'nave' it works as is! I suspect 'nav' is a reserved word.

Two level menu, setting text-decoration property

Ok, this sounds kind of silly and I don't know if this is some kind of bug in css or what, but when I try to create two level menu where items on the first level have text-decoration property set to underline, I couldn't find a way to set text-decoration to none on the items on the second level.
<ul>
<li style="text-decoration:underline;">item1
<ul>
<li style="text-decoration:none;">subitem1</li>
<li>subitem2</li>
</ul>
</li>
</ul>
Does anyone knows why is this and how can I fix it?
You could change your subitem to
<li style="text-decoration:none !important;">subitem1</li>
that should fix it for you.
However abuse of the !important rule is probably not the greatest way forward. A better strategy in the longer term would be to use a CSS file and add class attributes to your li elements.
Something like:
HTML
<ul>
<li class="main-item">item1
<ul>
<li class="sub-item">subitem1</li>
<li>subitem2</li>
</ul>
</li>
</ul>
CSS
.main-item {
text-decoration:underline;
}
.sub-item {
text-decoration:none;
}
This is simple, first understand that if you are giving text-decoration:underline; to the first level list item then the same css property is gonna apply for for the child so what u can do is
.main-nav > li {text-decoration:underline;} -- with this the css is gonna apply for only the first level of list or the parent items. Note this will not apply for other child list.
With this u dont need to add css for child list
http://jsfiddle.net/qL3Bp/

Add css rule specific to component with multiple classes

I have the following HTML code:
<LI id=treeMenu:2 class="ui-treenode ui-treenode-leaf ui-treenode-unselected" role=treeitem sizset="false" data-nodetype="default" data-rowkey="2" sizcache0014053099738481567="771 85 282">
<SPAN aria-expanded=false aria-checked=false class="ui-treenode-content ui-tree-selectable" aria-selected=false sizset="false" sizcache0014053099738481567="771 85 282">
<SPAN class=ui-treenode-leaf-icon></SPAN>
<DIV class="ui-chkbox ui-widget" sizset="false" sizcache0014053099738481567="771 85 282">
<DIV class="ui-chkbox-box ui-widget ui-corner-all ui-state-default">
<SPAN class="ui-chkbox-icon ui-c"></SPAN>
</DIV>
</DIV>
<SPAN></SPAN>
<SPAN class="ui-treenode-label ui-corner-all">dfvc</SPAN>
</SPAN>
</LI>
I need to add a CSS rule only to LI components that with "ui-treenode ui-treenode-leaf ui-treenode-unselected" class and Besides applies for this div component that is inside on LI:
<DIV class="ui-chkbox ui-widget" sizset="false" sizcache0014053099738481567="771 85 282">
I've created the following rule but doesn't work
li .ui-treenode-leaf span div .ui-chkbox {
position: relative !important;
top: -15px !important;
}
I'm working on IE8 and this is HTML generated from node (node without leaf) of Tree component of "Primefaces" (Tree Component on showcase example)
What is the correct CSS rule?
One problem you have is that your rule is looking for a tag with class 'tree-node-leaf' within an li.
To indicate that you want to target a tag with a specific class, do not put a space between the tag and class.
li.tree-node-leaf targets an li with that class.
li .tree-node-leaf targets a tag with the class tree-node-leaf within an li.
The same is done with ID selectors, li#id targets an li with the ID of id. li #id targets an element with ID id within an li.
As Pavlo has said, you should try to keep your selectors as simple as possible - it greatly increases maintenance and reduces the chances of small mistakes becoming big problems.
Try this:
li.ui-treenode-leaf span div.ui-chkbox {
position: relative !important;
top: -15px !important;
}
It depends on what kind of hierarchy you want in the CSS selectors. If you already defined meaningful class names, there should be no need to include type selectors. It doesn't matter, if you implement ui-treenode-leafs with a div or a li element.
.ui-chkbox should already be sufficient to add styling information, unless you need different styles in specific contexts. But even then .ui-treenode-leaf .ui-chkbox should be all you need.
You also should not use !important. When you have the need to use important, you should think about your classes and about how specific your (other) selectors are.

Changing display value with CSS '+' operator

I'm trying to create a dropdown menu using CSS, it's centered around using the following:
#submenu_div {
display: none;
}
#li_id:hover + #submenu_div {
display: block;
}
EDIT:
Here's the fixed HTML for the entire thing.
<ul id="main_nav">
<li id="li_id">Home</li>
<ul id="sub_who">
<li>Foo</li>
</ul>
</ul>
The #submenu_div is outside the parent div for the ul in which the li the previous code refers to resides. As far as I know, this should work. But I'm obviously doing something wrong, any ideas?
The #submenu_div is outside the parent div for the ul in which the li the previous code refers to resides.
The + combinator looks only for a true sibling element, i.e. an element with the same parent as whatever matched the left-hand side of the +. You cannot make it match anything else. You will need to change either your HTML (so that #submenu_div is a true sibling of #li_id) or your CSS (so the thing on the LHS of the + is a true sibling of #submenu_div) or both.
Without seeing the structure of your HTML I cannot give more precise advice.