target first submenu of parent ul - css

I need to target css for the first level ul submenu in a parent ul.
CSS:
#menu li:hover > ul.sub_menu { ...some styles }
..but this will ofcourse do it for all the sub_menu's, I only want this particular style for the first sub_menu relative to the parent when you hover over the parent list item.
HTML:
<ul id="menu">
<li>Item
<ul class="sub_menu"><!-- target only this one -->
<li>Item
<ul class="sub_menu">etc...</ul><!-- do not do for this one and so on-->
</li>
</ul>
</li>
<li>Item
<ul class="sub_menu"><!-- target only this one -->
<li>Item
<ul class="sub_menu">etc...</ul><!-- do not do for this one and so on-->
</li>
</ul>
</li>
</ul>
Thanks for any feedback...

You can use the :first-child selector:
#menu > li:first-child > ul.sub_menu {
color: red;
}
And then use the descendant selector to revert the changes for the other elements:
#menu > li:first-child > ul.sub_menu ul {
color: black;
}
Demo: http://jsfiddle.net/6y4Sb/

Related

Is it possible to select nth-child(x) but only if it is not the last child?

I want to select the third element within a ul, only if it is not the last element in the ul.
Sample 1:
<ul>
<li>Home</li>
<li>Cat 1</li>
<li>Subcat 1</li>
<li>Product</li>
</ul>
Sample 2:
<ul>
<li>Home</li>
<li>Cat 1</li>
<li>Product</li>
</ul>
I want a single CSS selector, which, for sample 1, selects the li with "Subcat 1", and for sample 2, does not select anything.
ul > li:nth-child(3) will work for sample 1, but will also match the 'Product' li in sample 2, which I don't want it to do.
In this case I'm not able to modify the HTML.
You could use the :nth-child with :not to achieve what you need. here is an example.
ul li:nth-child(3):not(:last-child) {
color: red;
}
<ul class="sample1">
<li>Home</li>
<li>Cat 1</li>
<li>Subcat 1</li>
<li>Product</li>
</ul>
<ul class="sample2">
<li>Home</li>
<li>Cat 1</li>
<li>Product</li>
</ul>
The classic CSS approach here, without using :not (which can sometimes be tricky), is to give the general rule first, then override it with the special case.
ul > li:nth-child(3) { color: red; }
ul > li:last-child { color: inherit; }
I want a single CSS selector,
If this is important, you'll need to use :not.
You can use the :last-child selector. So it would be something like this:
ul >li:last-child {
/* Your CSS */
}
More about :last-child
ul > li:nth-child(3):not(:last-child), ul > li:nth-child(2):not(:last-child) {
color: red;
}

Styling nested lists with any depth

I was wondering if it's possible to style nested unordered lists with CSS only, without using any scripts. The problem is that CSS needs to work for any depth of the list tree.
For example, I have a list:
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li class="holder">
<ul>
<li>Item 4</li>
<li>Item 5</li>
<li class="holder">
<ul>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
<li class="holder">
<ul>
<li>Item 9</li>
<li>Item 10</li>
<li>Item 11</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
And this is my CSS:
li{
background: gray;
border: 1px solid;
display: block;
margin: 2px;
}
.holder{
background: none;
border: none;
}
/*replace these styles*/
li > ul > li{
background: white;
}
li > ul > li > ul > li{
background: gray;
}
li > ul > li > ul > li > ul > li{
background: white;
}
If node's parent has background A, node should have background B. If node's parent has background B, node should have background A.
Please check : http://jsfiddle.net/bCU34/6/
CSS selectors allow you to select all named elements of a parent node by separating the named element from the parent element with a space. To select all unordered list elements, for example, you would do like below. Notice all ul elements at any depth inherit the style no bullets/margin/padding. In order do style nth layer for an element type, you need to use the parent selector >. See below. I used font color but you could set background images the same way. Note there is no decendant level selector at this time that I know of. This was addressed on another post CSS select nested elements up to N levels deep.
.container ul {
list-style-type: none;
margin: 0;
padding: 0;
}
.container > ul > li {
color: green;
}
.container > ul > li > ul > li {
color: red;
}
.container > ul > li > ul > li > ul > li {
color: blue;
}
<section class="container">
<h1>CSS Nested List Styling</h1>
<ul>
<li>
<h3>Section 1</h3>
<ul>
<li>
<h4>Foo</h4>
<ul>
<li>
<h5>Bar</h5>
</li>
<li>
<h5>Bar</h5>
</li>
</ul>
</li>
<li>
<h4>Foo Bar</h4>
<ul>
<li>
<h5>Bar</h5>
</li>
<li>
<h5>Bar</h5>
</li>
</ul>
</li>
</ul>
</li>
<li>
<h3>Section 2</h3>
<ul>
<li>
<h4>Hello</h4>
<ul>
<li>
<h5>World</h5>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</section>
There isn’t any specific way of doing this currently with Selectors level 3, and the current draft of Selectors level 4 doesn’t seem to add anything either. I had a dig through the www-style mailing list and came up with this post by Lachlan Hunt from April 2005 that suggests that an :nth-descendant() style selector had been considered but never specified.

Select Last of Type with CSS

Given the following HTML, what CSS rule would select and ONLY select the line that says TWO?
<ul class="menu">
<li><a>void</a></li>
<li class="active">
<a>one</a>
<ul class="sub-menu">
<li class="active"><a>two</a></li>
<li><a>three</a></li>
</ul>
</li>
</ul>
The following selector doesn't work:
.active:last-of-type {...}
Also, I must clarify that if there is no sub-menu or rather the link in the sub-menu is NOT active, then the parent menu must be selected by the same rule. In other words, given the following HTML, the same rule would highlight the line that says ONE:
<ul class="menu">
<li><a>void</a></li>
<li class="active">
<a>one</a>
<ul class="sub-menu">
<li><a>two</a></li>
<li><a>three</a></li>
</ul>
</li>
</ul>
No single selector statement will match both of your use cases (not until parent selectors are supported, anyway). You would have to include, for example, an additional class in one of those use cases in order to fulfill your requirements without your selector matching all .active elements.
Assuming the following use cases:
Active sub-menu element
<ul class="menu">
<li class="active"><a>one</a></li>
<li>
<ul class="sub-menu">
<li class="active"><a>two</a></li>
<li><a>three</a></li>
</ul>
</li>
</ul>
No active sub-menu element
<ul class="menu no-active-sub-menu">
<li class="active"><a>one</a></li>
<li>
<ul class="sub-menu">
<li><a>two</a></li>
<li><a>three</a></li>
</ul>
</li>
</ul>
The following selectors would work:
.menu .sub-menu > .active,
.menu.no-active-sub-menu > .active {
...
}
ul > ul > li:first-child
but you should nest the child UL inside the li in which case:
ul > li > ul > li:first-child
You can use this
ul ul .active {...}
Going from the code provided
Just use :last-child
ul .active:last-child {
color: green;
}
As was suggested by one of the contributors, the parent required another class to set it apart from the child(ren) menu items for this to work. I am posting my solution in case others are faced with something similar.
This is the HTML when the parent is the active page:
<ul class="menu">
<li><a>void</a></li>
<li class="active">
<a>one (parent, active page)</a>
<ul class="sub-menu">
<li><a>two (child)</a></li>
<li><a>three (child)</a></li>
</ul>
</li>
</ul>
This is the HTML when a child menu item of the parent is the active page:
<ul class="menu">
<li><a>void</a></li>
<li class="active page-parent">
<a>one (parent)</a>
<ul class="sub-menu">
<li class="active"><a>two (child, active page)</a></li>
<li><a>three (child)</a></li>
</ul>
</li>
</ul>
These are the rules I used:
/* Highlights the parent and any child
menu item under the parent when the
parent is the active page. */
ul.menu li.active a {
color: red;
}
/* Keeps the children menu items normal
when the parent is the active page.
Also keeps the parent normal when a
child menu item is the active page. */
ul.menu li.active ul.sub-menu li a,
ul.menu li.active.page-parent a {
color: black;
}
/* Highlights the child menu item that
is active */
ul.menu li.active.page-parent ul.sub-menu li.active a {
color: red;
}
It definitely is straightforward once you identify the parent state with a unique rule when one of its children menu items is active. Obviously, this would be easier if the child items didn't inherit the "active" state from the parent, but the menu system I am using behaves as described here. Thanks to everyone for their contributions.
Note: I have not tested this with a menu containing more than 1 sub-menu level deep.

Simple vertical multilevel menu

I am looking for some really simple vertical multilevel menu, but I did not find anything. My idea of menu is for example like this:
<ul id="menu">
<li>Item 1</li>
<li class="parent">Item 2
<ul>
<li> Sub 1</li>
<li> Sub 2</li>
</ul>
</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5
<ul>
<li> Sub 1</li>
<li> Sub 2</li>
</ul>
</li>
<li>Item 6</li>
And I would like to at first hide all sub categories. And if I click on the some category, the page will load and one the category with class="parent" will show its category. My question is, how can I reach this only with css?
This is basically how a hover menu works; hide the <ul> by default and show it when being hovered.
jsFiddle
#menu li > ul {
display:none;
}
#menu li:hover > ul {
display:block;
}
If you want .parent to show as well just put it in with the hover rule:
jsFiddle
#menu li:hover > ul,
#menu li.parent > ul{
display:block;
}
to hide the sub categories you need to add these to css file
#menu li > ul { display:none;}
#menu ul li ul {display: none;}
#menu ul li.parent ul {display: block;}

css3 last-child not working as expected

I have match listings dynamically generated. After each member I display a li that displays VS within it. However the very last ul li in the div match shouldnt be visible. Any ideas how I can do that?
HTML
<style>
.match {
}
.match ul {
}
.match ul li {
float: left;
margin-right: 50px;
}
.match ul li:last-child {
display: none;
}
</style>
<div class="content">
<div class="match">
<ul>
<li>Wade Barrett</li>
<li style="">VS</li>
</ul>
<ul>
<li>Shaemus</li>
<li style="">VS</li>
</ul>
<ul>
<li>Randy Orton</li>
<li style="">VS</li>
</ul>
<ul>
<li>John Cena</li>
<li style="">VS</li>
</ul>
<ul>
<li>Edge</li>
<li style="">VS</li>
</ul>
<ul>
<li>Chris Jericho</li>
<li style="">VS</li>
</ul>
<p class="clear"></p>
</div>
</div>
The :last-child pseudo-class should apply to the ul, not li, because you want VS text of the last ul of the list to be hidden. By applying the pseudo-class to li, you're applying styles to the last li of every ul, which is incorrect.
You should also apply a class attribute to the li elements with the VS text so that it's more convenient to match with a class selector.
Change
<li style="">VS</li>
to
<li class="vs">VS</li>
And use this instead of your current :last-child selector:
.match ul:last-child li.vs {
display: none;
}
What browser are you using, IE does not support it. The latest version of the other browsers do, but I would recommend placing a class on it to make it 100%.

Resources