I read about the difference between descendant and child selectors and thought I had understood it but kept getting the same result whether I would use the first or the latter.
It took me a while to understand that there are exceptions to the rule and it's not always true that you don't target descendant tags when you would use child selectors. I don't know if I am wrong here but it seems that you have to have chosen a style on your descendent tags or you will still target the descendent tags even if you use child selectors.
Here is an example where I get the same result no matter what I use:
ul#firstUl > li{
color:red;
background-color: lightblue;
}
<div >
<ul id="firstUl">
<li> Child </li>
<li> Child </li>
<li> Child </li>
<li>
<ul>
<li> Descendant </li>
</ul>
</li>
</ul>
</div>
As I have understood, the li tag with the text 'Descendant' should not had been targeted here but it is. So am I right that if the descendent tags haven't already been altered, you target them as well?
Interesting question.
So basically you're defining a color red for a li element. This color will be applied to all the element into the li. So the rule is applying correctly, however, setting up a default value (as I did below) will fallback to the black as soon as we're getting out of the scope of your css rule.
li {
color: black;
}
ul#firstUl > li {
color:red;
background-color: lightblue;
}
<div >
<ul id="firstUl">
<li> Child </li>
<li> Child </li>
<li> Child </li>
<li>
<ul>
<li> Descendant </li>
</ul>
</li>
</ul>
</div>
Related
i'm trying very hard to get the first link, see below. They are very hard to get without class or id. I tried all, nothing works because the selector are nested und similar.
<nav>
<ul>
<li>
First /* this one */
<ul>
<li>
First menu item
</li>
<li>
Second menu item
</li>
<li>
Another one
</li>
<li>
Last one
</li>
</ul>
</li>
<li>
Second menu item /* this one */
<ul class="m1">
<li>
Another menu item
</li>
<li>
Next one
</li>
<li>
Last one
</li>
</ul>
</li>
</ul>
</na>
if you have only one nav and one menu, you can use this one:
nav > ul > li > a { /* styles */ }
Assuming the nav element is unique on the page, you can simply select the link based on that it is within the first LI in the top-level UL:
nav > ul > li:first-child > a { color: red; }
UPDATE: The fiddle link I posted has the working code now. :not(:last-child) and :nth-last-child(n + 2) both work perfectly.
I'm trying to use the nth-child or nth-last-child selector to select every li in a ul except for the last one. The catch is, the length of the list can vary from 1 to 5 elements. I haven't been able to find any documentation or examples of how to accomplish this.
Here is the HTML for the ul:
<ul class="breadcrumbs">
<li>
Home
</li>
<li>
Articles
</li>
<li>
Specials
</li>
<li class="current">
Song Lyrics
</li>
</ul>
Here is my current code:
ul > li:nth-last-child(-1n+4) > a:hover {
color: red;
}
This code still selects the last element in the list. I've also tried the code below, but that doesn't select anything. I tried a number of other combinations as well, but they either didn't work at all or selected the last element.
ul > li:nth-child(1):nth-last-child(2) > a:hover {
color: red;
}
Here is a fiddle.
Use :not(:last-child) to target all except the last.
http://jsfiddle.net/96nd71e3/1/
Use :nth-last-of-type or :nth-last-child
http://jsfiddle.net/t0k8gp4d/
li:nth-last-of-type(n + 2) a {
color: red;
}
<ul class="breadcrumbs">
<li>
Home
</li>
<li>
Articles
</li>
<li>
Specials
</li>
<li class="current">
Song Lyrics
</li>
</ul>
You can use this
<ul class="breadcrumbs">
<li>
Home
</li>
<li>
Articles
</li>
<li>
Specials
</li>
<li class="current">
Song Lyrics
</li>
</ul>
CSS
ul > li{
background:red;
}
ul > li:last-child{
background:black;
}
But if you absolutely need to change their style outside of the main li element use this
ul > li{
background:black;
}
ul > li:not:last-child{
background:red;
}
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.
Could some one explain me how CSS drop downs works?
I've seen alot of them, most of them has the > selector,
My question is:
How can you make CSS dropdown with the > selector?
I looked towards a lot of tutorials and never understood what does the > do and how does it connects with the HTML classes\Ids.
Could someone explain me that, part by part?
Thank you.
It is used to select direct children.
Consider following markup
<div id="container">
<ul>
<li> List Item
<ul>
<li> Child </li>
</ul>
</li>
<li> List Item </li>
<li> List Item </li>
<li> List Item </li>
</ul>
</div>
A selector of #container > ul will only target the uls which are direct children of the div with an id of container.
It will not target, for instance, the ul that is a child of the first li.
For this reason, there are performance benefits in using the child combinator.
HTML:
<ul class="menu">
<li>
<span>menu 1</span>
<ul>
<li><a href="#" >Sub 1-1</a></li>
<li><a href="#" >Sub 1-2</a></li>
<li><a href="#" >Sub 1-3</a></li>
</ul>
</li>
<li>
<span>menu 2</span>
<ul>
<li><a href="#" >Sub 2-1</a></li>
<li><a href="#" >Sub 2-2</a></li>
<li><a href="#" >Sub 2-3</a></li>
</ul>
</li>
</ul>
css:
ul.menu>li{ /*Only direct children*/
float:left;
width: 60px;
}
ul.menu li ul{
display:none; /*not visible*/
}
ul.menu li:hover ul{
display:block; /* visible when hovering the parent li */
}
Explanation is in the css.
Demo:
http://jsfiddle.net/FH7Z3/
The > operator in CSS means that following expression must be a direct child.
For example, div span matches SPAN elements which are descendants of a DIV element, but div > span only matches SPAN elements which are a direct child of a DIV.
http://www.w3schools.com/cssref/sel_element_gt.asp
see this the > is a child selector. Rather than referencing to all the descendents we want to address only the direct descendents. View it as wanting to select only the children but not grand children or any further.
trying to select an adjacent's child element with CSS... not really sure how to
This is the HTML structure
<ul>
<li>
<a href="#">
<span class="icon"></span>
First level
</a>
<ul>
<li>
Second level
</li>
</ul>
</li>
</ul>
I want to say that there is a menu with multiple levels. When theres a UL existing within a LI then the needs to have a dropdown/expand icon... so I thought if I use the adjacent selector I can determine if this level has kids to expand and this is what I thought would work but didn't:
ul li a ~ ul .icon {
// doesnt work
}
ul li a .icon ~ ul {
// doesnt work
}
This works but I need to target the .icon
ul li a ~ ul {
// works
}
Cheers, Dom
Building upon my comment on your question. If you have control over how the HTML for the menu is generated, a workaround would be to add an extra class to each li-element that has a sub-menu. Like this:
<ul>
<li class="has-submenu">
<a href="#">
<span class="icon"></span>
First level
</a>
<ul>
<li>
Second level
</li>
</ul>
</li>
</ul>
Then you could use a selector like this:
.has-submenu .icon {
/* Do your stuff here */
}
ul is a child of li, not the anchor. So ul li ul .
If you want to select it as a sibling, then ul li a + ul