How to read a syntax like .nav-menu li:hover ul?
How is it different from .nav-menu li ul:hover?
I've searched w3schools but all the examples there are of the latter type.
Can anyone explain?
Below is the code that I've implemented for creating a dropdown submenu.
HTML
<ul class="nav-menu">
<li>Home</li>
<li>Retrievals
<ul class="dropdown-menu">
<li>Data Listing</li>
<li>Web Scheduling</li>
<li>Google Maps Application</li>
</ul>
</li>
<li>Reporting</li>
CSS:
.nav-menu li
{
width: 150px;
float: left;
}
.nav-menu li ul
{
display: none;
}
.nav-menu li:hover ul
{
display: block;
}
.nav-menu li:hover ul
an unordered list
which is a descendant of a hovered list item
which is a descendant of an element that is a member of the nav-meny class
.nav-menu li ul:hover
a hovered unordered list
which is a descendant of a list item
which is a descendant of an element that is a member of the nav-meny class
You'd be unlikely to notice any practical difference with your specific HTML since the only list items you have that contain an unordered list contain nothing except a single unordered list.
First rule: .nav-menu li:hover ul apply css to ul once you hover parent li.
Second rule: .nav-menu li ul:hover apply css to ul once you hover ul element.
Related
#cssmenu ul li.hover,
#cssmenu ul li:hover {position: relative; z-index: 599; cursor: default;}
#cssmenu ul ul {visibility: hidden; position: absolute; top: 100%; left: 0; z-index: 598; width: 100%;}
#cssmenu ul ul li {float: none;}
1) what is the difference between "li.hover" and "li:hover"?
2) what does "ul ul li" even mean? why are there 2 "ul" elements?
li.hover is targeting an li element that also has a class of hover, for example:
<li class="hover"></li>
li:hover is targeting the hovered state of any li element.
ul ul li is targeting any li elements that reside in a ul element that resides inside another ul element, like so:
<ul>
<li>
<ul>
<li>This is the element that would be targeted</li>
</ul>
</li>
</ul>
.hover is a class identifier
:hover denotes the action of mouseOver
1)
li.hover is a defined class. You can use it like <li class="hover">.
li:hover defines the hover state. It will appear if you hover an element with your cursor.
2)
ul ul li : The second ul styles a ul in an available ul. It can be used for sublists.
<ul>
<li>
<ul>
<li></li>
</ul>
</li>
</ul>
1)
li.hover li element which have class hover exp ..
li:hover li element which are being hovered.
2)
ul ul li only li element which have at least ul as ancestors exp:
<ul>
<li>
<ul>
<li>
ME
</li>
</ul>
</li>
</ul>
I have a list with some nested lists inside it like this:
<ul class="menuSports">
<li>
<ul>
<li>
<ul>
<li>
<li>
</ul>
</li>
</ul>
</li>
<ul>
and am using a before element to create an arrow so that the items are displayed like a dropwdown list:
#menuSports li ul li:before { content: '\25BA'; position:absolute; color:#cecece; padding-left: 5px; padding-top:5px;}
The problem is the before element is being applied to all li elements from the one specified onwards, kind of like this:
#menuSports li ul li:before { content: '\25BA'; position:absolute; color:#cecece; padding-left: 5px; padding-top:5px;}
#menuSports li ul li ul li:before { content: '\25BA'; position:absolute; color:#cecece; padding-left: 5px; padding-top:5px;}
Is there a way to stop this from happening, so that only the li specified in the first selector is given the element?
P.S I can not change the html code or use javascript, using css is my only option.
ul li { margin: 0 0 5px 0; }
ul > li { margin: 0 0 5px 0; }
The first selector above is a decendant selector. It will select any list items that are anywhere underneath an unordered list in the markup structure. The list item could be buried three levels deep within other nested lists, and this selector will still match it.
The second selector above is a child combinator selector. This means it will only select list items that are direct children of an unordered list. In otherwords, it only looks one level down the markup structure, no deeper. So if there was another unordered list nested deeper, the list item children of it will not be targeted by this selector.
For more information try this link
You can specify level(s) of LI using descendant selector.
So,
#menuSports > li {/* only first level LIs */}
#menuSports > li > ul > li {/* only second level LIs */}
#menuSports > li > ul > li > ul > li {/* only third level LIs */}
Alternative is to reset styles for next levels
#menuSports li li:before {content: 'content'; /* second and each nest level LIs */}
#menuSports li li li li:before {content: ''; /* fourth and each next are reseted */}
I have a vertical navigation menu and I want to show different levels of the menu upon hovering of certain elements. The problem is that the method I used is not working and I do not understand why. When I hover over "Product", I expect to see a sub-menu expand, but nothing happens. Why?
HTML:
<nav>
<ul>
<li>Home</li>
<li>About</li>
<li>Product</li>
<ul>
<li>Blueberries</li>
<li>Rasberries</li>
<li>Strawberries</li>
</ul>
<li>Contact</li>
</ul>
</nav>
CSS:
nav {
border:1px solid red;
}
nav ul ul {
display:none;
}
nav ul li:hover > ul {
display:block;
}
Your code:
nav ul li:hover > ul {
display:block;
}
Means "Make any ul within a hovered li display:block". Your submenu is not within the LI, it's after it. Here's a working version of what you were trying to do.
Working HTML:
<li>Product
<ul>
<li>Blueberries</li>
<li>Rasberries</li>
<li>Strawberries</li>
</ul>
</li>
Working CSS:
nav ul li ul {
display:none;
}
nav ul li:hover ul {
display:block;
}
Also
nav ul ul {
display:none;
}
should be
nav ul li ul {
display:none;
}
Try this for your html:
<nav>
<ul>
<li>Home</li>
<li>About</li>
<li>Product
<ul>
<li>Blueberries</li>
<li>Rasberries</li>
<li>Strawberries</li>
</ul>
</li>
<li>Contact</li>
</ul>
</nav>
You have two ways of changing this; you can either update the HTML or you can update the CSS.
There are pros and cons to changing code and in a vacuum I can't recommend one approach over the other.
Without changing your HTML you can make the CSS work like this:
nav ul li:hover + ul {
display: block;
}
Note that rather than using the descendant selector this uses the adjacent selector and applies the style to the element that immediately follows the hovered LI.
Alternatively, the HTML change mentioned above does work equally well.
This link http://net.tutsplus.com/tutorials/html-css-techniques/the-30-css-selectors-you-must-memorize/ provides a fantastic resource.
I am trying to create a second level dropdown. I successfully created first level dropdown but bit stuck in making it level 2. Please assist me to complete it..
and also please explain me what mistake I am doing that I cant get the second level dropdown even the css part is good (I think so)
EDIT: I know there are many tutorials on dropdown css. But I want to know why this is not working.
Here is the link to jsbin
HTML
<ul id="nav">
<li>Home</li>
<li>Details
<ul id="subNav">
<li>x details<li>
<li>y details</li>
</ul></li>
<li>About Us
<ul id="xSubNav">
<li>About company
<ul>
<li>full information</li>
<li>summary</li>
</ul></li>
<li>About Author</li>
</ul></li>
</ul>
CSS
*{font-family:consolas;}
li{line-height:20px;}
ul#nav>li{float:left;width:100px;list-style:none;
cursor:hand;cursor:pointer;}
ul#nav li li
{display:none;width:150px;}
ul#nav li ul
{padding:0;margin:0;}
ul#nav>li:hover>ul>li
{display:block;}
ul#nav>li:hover{color:grey;}
ul li li{color:black;}
ul li li:hover
{color:cornflowerblue;}
ul li li:hover li /* level 2 dropdown part */
{display:block;margin-left:150px;width:300px;}
Here is solution with your code
Just add the below css:
ul ul li { position:relative;}
ul ul li ul { position:absolute; display:none; left:0px; top:0px;}
ul ul li:hover ul { display:block;}
ul#nav li li li {display:block;}
Check this working fiddle
The problem is the specificity of CSS rules. Just add #nav to the last three rules, to not get overridden by the first ones.
ul#nav li li{color:black;}
ul#nav li li:hover
{color:cornflowerblue;}
ul#nav li li:hover li
{display:block;margin-left:150px;width:300px;}
And I think some other tuning is needed, but that's the idea.
I'm trying to target the first and last anchor within a list-item of an unordered list:
<ul>
<li>HOME</li>
<li>LINK</li>
<li>LINK</li>
<li>LINK</li>
<li>LINK</li>
</ul>
I have tried:
.menu ul .last a {}
.menu ul.last a {}
.menu ul li .last a {}
.menu ul li.last a {}
I need to target the anchor as I need to remove the border of the first and last anchor. I can't use (or at least I don't think I can) border on the <li>, as it needs some vertical padding so the separator border is not vertically flush.
If you don't need to worry about old browsers, use the :first-child and :last-child pseudo-classes on the list items, like so:
/* Because we are looking at the <li> children of your <ul> */
.menu ul li:first-child a {}
.menu ul li:last-child a {}
However, support for CSS3 :last-child is pretty poor right now, so a more browser-compatible alternative is to manually give the last list item a last class, like so (and doing the same for first):
<ul>
<li class="first">HOME</li>
<li>LINK</li>
<li>LINK</li>
<li>LINK</li>
<li class="last">LINK</li>
</ul>
Then, you can use these selectors:
.menu ul li.first a {}
.menu ul li.last a {}
You want the :first-child and :last-child pseudo-class selectors:
<style type="text/css">
.menu ul li:first-child a {
color: green;
}
.menu ul li:last-child a {
color: red;
}
</style>
<div class="menu">
<ul>
<li>apple</li>
<li>baker</li>
<li>charlie</li>
<li>delta</li>
</ul>
</div>
What I think you require are the :first-child and :last-child selectors.
.menu ul li:first-child a
.menu ul li:last-child a