Explanation of three css lines - css

Can anybody explain for me the difference between these three:
1. ul li a:hover
2. #drop-nav ul li:hover , ul li ul
3. #drop-nav ul li:hover > ul
The most difficault part is when there are more than one ul and li. I dont understand what they mean. Ive tried to google it, and if you know any good articles on exactly this I would really appreciate that!

1- ul li a:hover target a hover-ed a element that is contained within a li element. This li element must in turn be contained in an ul element. In short, it target something like this:
<ul>
<li>
<a>This element satisfy "ul li a:hover"</a>
</li>
</ul>
Or this:
<ul>
<li>
<div>
<a>This element also satisfy "ul li a:hover"</a>
</div>
</li>
</ul>
Notice how in the second example the <a> tag is not a direct child of the <li> tag? As long as it's contained within a <li> tag the selector would still be satisfied.
2- #drop-nav ul li:hover , ul li ul is 2 different CSS selectors that target 2 different types of element. They share the same styles that are defined after. The 2 selectors are #drop-nav ul li:hover and ul li ul. The , selector group 2 group together and give them the same style.
#drop-nav ul li:hover targets hover-ed lis that are contained in an ul, which is contained within an element which have id="drop-nav".
ul li ul targets uls that are contained within a li, which is contained within another ul.
So either this:
<div id="drop-nav">
<ul>
<li>This element satisfy "#drop-nav ul li:hover", so it also satisfy "#drop-nav ul li:hover , ul li ul"</li>
</ul>
</div>
or this:
<ul>
<li>
<ul>This element satisfy "ul li ul", so it also satisfy "#drop-nav ul li:hover , ul li ul"</ul>
</li>
</ul>
Will satisfy your selector.
3- #drop-nav ul li:hover > ul: the > selector is a "direct child" selector. This whole thing target uls that is the direct child of a hover-ed li element, which is contained within an ul, which is contained within an element with id="drop-nav". Meaning the html is something like this:
<div id="drop-nav">
<ul>
<li>
<ul>This element satisfies "#drop-nav ul li:hover > ul"</ul>
</li>
</ul>
</div>
Note that this will not satisfy the rule this time:
<div id="drop-nav">
<ul>
<li>
<div>
<ul>This element does NOT satisfy "#drop-nav ul li:hover > ul"</ul>
</div>
</li>
</ul>
</div>
Because the ul is not a direct child of a li. Its direct parent is a <div>

1. ul li a:hover
It mean css work for element <a></a> when mouse over, inside element ul li
2. #drop-nav ul li:hover , ul li ul
It mean css work for element <li></li> when mouse over inside element with id drop-nav ul li and also work for element <ul></ul> inside ul li with same css
3. #drop-nav ul li:hover > ul
symbol > it mean css only work for ul which have 1 level below li:hover or inline with li:hover

ul li a:hover
This style takes place when you hover over this a element.
<ul>
<li>
This link will change on hover
</li>
</ul>
#drop-nav ul li:hover , ul li ul
The comma separates two different selectors. The first is this:
<div id="drop-nav">
<ul>
<li>This li will change on hover</li>
</ul>
</div>
The second is this:
<ul>
<li>
<ul>This is a nested unordered list</ul>
</li>
</ul>
#drop-nav ul li:hover > ul
This style only affects the immediate ul children of the selector.
<div id="drop-nav">
<ul>
<li>
<ul>This ul is affected when the li is hovered.</ul>
</li>
</ul>
</div>
<div id="drop-nav">
<ul>
<li>
<p>
<ul>This ul is NOT affected when the li is hovered.</ul>
</p>
</li>
</ul>
</div>

Works for links in unnumbered list elements only if cursor is over the <a> tag area
Applied for hovered list elements if list parent has id specified and for all unnumbered 2nd level lists
Appleid for 2nd level lists if parent element of first level list has specified id and cursor is over of first level (parent) list element
If you see more then one list it means the sublevel is present. Please use classes instead of id if it's possible.

Related

CSS Selector first of children, NOT siblings

How do I select only the first instance of an element without the selector triggering for any children? Children as in descendants, not siblings.
In example ul:first-of-type would select the first unordered list though any submenus (ul ul, ul li ul and ul ul ul ul ul) would also be selected. I only want to select the first instance of a ul element within #menu.
I could do the following though it's pointlessly convoluted.
#menu ul:not(ul ul):not(ul ul ul):not(ul ul ul ul) {property: value;}
No, I also can not do #menu > ul as the number of elements between #menu and ul varies.
<nav id="menu">/* display: flex; justify-content: space-between; */
<div>
<ul>/* Primary, select THIS ul (no > in selector!) */
<li>Menu</li>
<li>Menu</li>
<li>Menu
<ul>/* Secondary menu. */
<li>Menu</li>
<li>Menu
<ul>/* Tertiary menu. */
<li>Menu</li>
<li>Menu</li>
<li>Menu</li>
</ul>
</li>
<li>Menu</li>
</ul>
</li>
<li>Menu</li>
</ul>
</div>
<div>
/* Auxiliary menu items on right side of menu bar, may contain ul (do not select these either). */
</div>
</nav>
At least at the time of this post and having gone through some extensive lists of selectors it at least appears that all type selectors are based on siblings, not descendants. So in order to make the first ul element in the menu have height: 100% without effecting secondary and tertiary ul elements I added a second selector.
#menu ul, #menu ul > li, #menu ul > li > a {align-items: center; display: flex; height: 100%;}
#menu ul ul {height: initial;}
This in part allows me to have drop down menus always horizontally centered beneath primary menus in combination with CSS variables for the total height of the primary header (in which the menu is a descendant of).
Because I work on a platform I can not add CSS classes as I please thus I must utilize what selectors are available.
Hopefully in the future CSS selectors will continue to expand to include descendant selectors in addition to the sibling selectors.

list styling applying to nested list elements in css

when i apply width as 100% to list elements,the nested list elements will also get the same width! i dont want that to happen..how to make not applicable to listed elements.
for ex:html structure
<ul>
<li>
<ul>
<li></li>
<li></li>
</ul>
</li>
</ul>
css structure: ul li{width:100%;}
but this applies to nested elements also! i.e "ul li ul li" too gets the width as 100%..i dont want this to happen! any solution?
When you use ul li it targets all li elements which are child of ul so logically, all the li nested under ul gets affected. If you want to target only 1st level of li elements you can use
body > ul > li {
width: 100%;
}
The above selector selects li element which is directly nested under ul which is further directly nested to body. This way it won't select the nested ul element as it is not a direct child of the body element.
Replace body if you have any parent wrapper with a class or an id. Make sure you just don't use ul > li because this way it will again select the nested li as well.
You can use the > selector where ul > li means select all li whose parent is ul. You can further refine the parent-child relationship by indicating additional levels.
ul > li {
width: 100%;
background-color: yellow;
}
ul > ul > li {
width: 25%;
background-color: red;
}
<ul>
<li>A</li>
<li>B</li>
<ul>
<li>1</li>
<li>2</li>
</ul>
</ul>
By the way, if you put a list (ul) in a list item (li), you may get bullet styles you don't want like this:
A
B
1
2

ul li:last-child affects the last li in the second ul

JsFiddle
My problem is that when using the pseudo code :last-child I expect the li containing E to be affected by the style but it's the last li in .subNav which is affected.
I've tried those(below), but nothing works.
nav ul:first-child li:last-child {border: none;padding-right: 0;}
nav ul:not(.subNav) li:last-child {border: none;padding-right: 0;}
How to get the main ul's last li affected?
There is a div after the last li. Therefore, it isn't the last child. You could use :last-of-type to target the last li :
nav ul li:last-of-type {border: none;padding-right: 0;}
DEMO
Remove the div which is inside ul. Adding any tags directly inside ul is not valid.
Place it inside li or remove it if not really necessary.
Otherwise your css selector is just fine.
<nav>
<ul>
<li>A</li>
<li class="B">
B
<ul class="subNav">
<li>F</li>
<li>G</li>
<li>H</li>
<li>I</li>
</ul>
</li>
<li>C</li>
<li>D</li>
<li>E</li>
</ul>
</nav>
DEMO
That's not the last child, you can use nth-last-child:
nav ul > :nth-last-child(2)
Or, use last-of-type:
nav ul > li:last-of-type
But I would recommend you to use as #Sowmya answer which is symantically correct.
Your selector is logically correct, but the problem is that the li is not the last child of its parent ul, because there's that div.clear
<ul>
<li>A</li>
<li class="B">B
<ul class="subNav">
...
</ul>
</li>
<li>C</li>
<li>D</li>
<li>E</li>
<div class="clear"></div>
</ul>
In this case nav ul li:last-child doesn't match anything because the li is not the last child. You should use nav ul li:last-of-type to match the last li element.
Note that uls only allow li as children, so having a div contained in an ul is wrong. If you remove that div.clear your code will work.
The pseudo class :last-child only triggers if the element is the last child in the parent.
In your case, there is a div within your ul which is not allowed anyway. Remove it and use a clearfix of some kind on the parent ul.

Is ul#Content not the same as #Content ul?

I'm debugging my css code as my ul are not coming out with indents and bullets as expected.
I've got a lot of UL's in my css but I've written them in various ways. I've tried to make them uniform, i.e. ul after the div name, but they behave differently. Can someone help me understand the difference as I want to write these statements in one uniform way.
ul#Content li {// do something}
#Content ul li {// do something}
They note diffeerent things:
ul#Content li {// do something}
all li elements inside elements of type ul with the ul having the id 'Content'
#Content ul li {// do something}
all li elements inside an ul element that is inside some container with id 'Content'
So the question is: is 'Content' the id if the ul or of its container ?
No, ul#content li matches any li contained in a ul which has id="content", example:
<ul id="content">
<li></li>
</ul>
#content ul li matches any li contained in a ul, contained in another element which has id="content". Example:
<div id="content>
<ul>
<li></li>
</ul>
</div>

CSS Menu Navigation

I cannot understand what this codes means -
1) .main ul ul,
2) .main ul li:hover ul ul
3) .main ul li:hover ul
4) .main ul ul li:hover ul
These codes are applied to hide or display menus & sub-menus .Those who are aware of CSS knows well of these codes. I thought much but cannot clearly understand!!
This is because the above codes are applied in this way-
.main ul ul,
.main ul li:hover ul ul
{display: none;}
Then again -
.main ul li:hover ul,
.main ul ul li:hover ul
{display:block;}
My question is,in case of 2 ul's we just use ".main ul ul" & then in the next line we use hover.
But without hovering over how can we get 2 ul's?
I mean it should be ul:hover ul in the first line,isn't it?
Also if the first 2 lines(i.e.- .main ul ul,
.main ul li:hover ul ul )are used for display:none ,then why the same 2 lines are not used for display:block???Because they should imply the same submenus?
Here .main is a div class like this-
<div class="main">
<ul>
<li>..</li>
<li>..</li>
<li>..</li>
<ul>
<li>sub-menu1</li>
<li>sub-menu2</li>
.
.
.
</ul> etc etc...
<div>
Actually this is a type of vertical list menu with submenus.
Hope you all get me.In simple words, my question what does the first 4 code lines at the very beginning of this question means?
Pls explain in details.
Thanks in advance
1) .main ul ul refers to:
<div class="main">
<ul>
<li>
**<ul>** ... **</ul>**
**<ul>** ... **</ul>**
</li>
</ul>
...
</div>
2) .main ul li:hover ul ul refers to the following, ONLY when the mouse is over the first level <li> (marked with 1 asterick), notice how this <ul> is another level deeper form the last example
<div class="main">
<ul>
*<li>*
<ul>
<li>
**<ul>**...**</ul>**
**<ul>**...**</ul>**
</li>
</ul>
<ul> ... </ul>
*</li>*
</ul>
...
</div>
3) .main ul li:hover ul refers to the **<ul>** when your mouse is over the *<li>*
<div class="main">
<ul>
*<li>*
**<ul>**
.
.
.
**</ul>**
**<ul>** ... **</ul>**
*</li>*
</ul>
...
</div>
4) .main ul ul li:hover ul refers to the **<ul>** when your mouse is over the *<li>* in this last example, notice how a level deeper <li> is now the responding to afocus of your mouse:
<div class="main">
<ul>
<li>
<ul>
*<li>*
**<ul>**...**</ul>**
**<ul>**...**</ul>**
*</li> *
</ul>
<ul> ... </ul>
</li>
</ul>
...
</div>
Edit: Thank you for editing your original post - I will try to answer a few more of your questions:
Question:
in case of 2 ul's we just use ".main ul ul" & then in the next line we
use hover. But without hovering over how can we get 2 ul's?
You want to know why the hover property is being called only on the second unordered list (UL), and how the second ul can even be displayed without the hover property being on the first ul. The answer is that these unordered lists are visible by default. Therefore, they will both be displayed when the page is loaded. The hover property just tells your page how to react when the user hovers over the second list.
I'm not completey sure of your queustion, and what it's asking. If you would like to know about what each CSS property is doing I can help to explain that. Your DIV container has a class name of .main.
1) .main ul ul - this is calling what seems to be an unordered list inside of another unordered list which is part of the ".main" class.
2) .main ul li:hover - This is calling the hover property of one of the list items within the first unordered list.
So, basically each of the top lines is referring to either a different item, or a different property within an item (all within the .main DIV).
Step by step. Let's first examine
.main ul ul, .main ul li:hover ul ul {display: none;}
what it does, it hides all nested lists. Please be aware, that something like thisd" may exists:
<ul id="first">
<li>
<ul id="second">
<li>
<ul id="third">
...
the "third" list also satisfies "ul ul". Can you see, that "third" is inside "second" ? it does not matter this is in the beginning. It is the same as you type
div{ ... }
it will apply to every div, no matter if it is inside any other element.
div div{ ... } would apply to all elements in such structure:
<any number of any tags>
<div>
<optional any number of any tags>
<div class="applied">
<div class="applied">
....
<div class="applied">
Ok that was easy.
Now, .main ul li:hover ul ul follows the same pattern, but it starts counting from li:hover. Imagine you have 5 level menu and you hover li inside third level. Then what this formula does is simple hiding the fifth level.

Resources