CSS, only affect the top lis of a ul? - html

I have a nested UL navigation list, with ul's contained inside some other li elements. here's the mark up:
<ul class="navigation">
<li>No Chidren</li>
<li>With Chilren
<ul>
<li>Child 1</li>
<li>Child 2</li>
</ul>
</li>
</ul>
I tried styling it with some of the following CSS declarations:
.navigation {
//stylings
}
.navigation li{
//stylings
}
.navigation li a{
//stylings
}
.navigation li a:hover{
//stylings
}
but the .navigation li affects all of the list elements, including the children. is there a way to target the lis so that the styles are only applied to the top-level ones, and not the children?

As others have mentioned, the > selector will only select direct children. However, this doesn't work in IE 6.
If you need to support IE 6, you can add a class to child uls or lis, and use that to remove the styling cascading from the top li:
<ul class="navigation">
<li>No Chidren</li>
<li>With Chilren
<ul class="level1">
<li>Child 1</li>
<li>Child 2</li>
</ul>
</li>
</ul>
--
.navigation li{
background: url(bg.png);
}
.navigation .level1 li{
background: none;
}

Like this, the ">" states that the li must be a direct child of .navigation
.navigation {
//stylings
}
.navigation > li{
//stylings
}
.navigation > li a{
//stylings
}
.navigation > li a:hover{
//stylings
}

Yes, it is possible with child selectors.
.navigation>li>a{
//stylings
}
Code above will affect "No Chidren" and "With Chilren" link but not "child 1" element.
Here is working example: http://jsfiddle.net/VuNwX/
And here you can read more about selectors: http://css.maxdesign.com.au/selectutorial/index.htm

Related

Why ul > li (selector) doesn't work

ul > li (selector) doesn't work. What am I missing here?
/* Part 1 */
ul > li{
margin-top:30px;
}
/* Part 2 */
/* ul .test{
margin-top:30px;
} */
<ul>
<li class="test">item1</li>
<ul>
<li>subitem1</li>
<li>subitem2</li>
</ul>
<li class="test">item2</li>
<li class="test">item3</li>
</ul>
https://jsfiddle.net/gy5r3noh/
Shouldn't Part 1 and Part 2 in css be equal? But It isn't. ul > li should select all li children of ul (like class=test I created), but it doesn't work by ul > li.
Ignoring the fact that your HTML is invalid as j08691 has pointed out, and assuming your inner ul is intended to be wrapped in a li element:
ul > li selects any li element which is a child of any ul element.
ul .test selects any element with a class of "test" contained within any ul element.
One and two give different results with your HTML structure because your nested ul does not contain li elements with a class of "test". Example one applies to both the outer and inner ul elements, whereas example two only affects the li elements with a class of "test" (which there are none of within your nested ul).
you HTML is invalid, ul can't have ul as direct child
ul > .test {
margin-top: 30px
}
<ul>
<li class="test">item1
<ul>
<li>subitem1</li>
<li>subitem2</li>
</ul>
</li>
<li class="test">item2</li>
<li class="test">item3</li>
</ul>
/* Part 1 */
ul > li{
margin-top:30px;
}
/* Part 2 */
/* ul .test{
margin-top:30px;
} */
<ul>
<li class="test">item1</li>
<ul>
<li>subitem1</li>
<li>subitem2</li>
</ul>
<li class="test">item2</li>
<li class="test">item3</li>
</ul>
Here, Html Should be like,
<ul>
<li class="test">item1
<ul>
<li>subitem1</li>
<li>subitem2</li>
</ul>
</li>
<li class="test">item2</li>
<li class="test">item3</li>
</ul>

CSS Child Combinators

I guess I am not getting css child combinators.
I am trying to target just the first level on the li's with the following:
ul > li { color: green; }
<ul>
<li>Home</li>
<li>
Products
<ul>
<li>Product 1 </li>
<li>Product 2</li>
<li>Product 3</li>
</ul>
</li>
<li>Contact</li>
<li>News</li>
</ul>
http://jsfiddle.net/5vB3h/
NOTE: I also tried removing the spaces between >, with no luck.
You're using them fine, but all (properly marked-up) <li>s are children of <ul>s. You can specify the parent (in your jsFiddle, body):
body > ul > li
Or reverse the styles with the more specific case:
li ul > li {
color: black;
}
In the case of color, you need to use the second option anyways, because color is inherited. Here's the updated jsFiddle.
Your rule targets the child list items of any list. What you can do is create a second rule to recolor the other sub list items. For example:
ul > li {
color: green;
}
li li {
color:black
}
jsFiddle example
ul will match all the <ul> elements. Since every <li> is a child of one of the <ul>sā€¦
You need to be more specific about which <ul> you mean. Perhaps add a class to it.
ul > li will select all the li elements in your document because they are all the children of ul elements.
If you apply a class to the parent like <ul class="top">, then you can use ul.top > li.
Add a class
li {color: blue;}
/* ^ added because maybe initial property is color: inherit;
If not, someone correct me */
ul.a > li { color: red; }
After this, add class to ul like <ul class="a" ...
http://jsfiddle.net/5vB3h/7/
EDIT (worked it out):
Okay so I ballsed up. Below is wrong.
ul:first-child > li { color: green; }
I found that when applying:
div>ul>li{color:green}
all lis went green... turns out that the li magically inherit the color of the li (odd behaviour as I assume the content had color:#000)
anyway... You need to explicitly set the color: to soemthing other than green to see the style working.
fiddle here
//html
<div>
<ul>
<li>Home</li>
<li>
Products
<ul>
<li>Product 1</li>
<li>Product 2</li>
<li>Product 3</li>
</ul>
</li>
<li>Contact</li>
<li>News</li>
</ul>
</div>
//css
li {color:black} //you have to have this (or something like * {color:black} OR body/html {color:black} as li seem to automatically inherit parent li color property
div>ul>li{ color: green; } //have to have parent.

How do i style a list within a list?

I have a list within a list, but I don't want the inner list to receive the outer list's styles. This is my code:
CSS:
li {
background-color:red;
}
#sections li {
color:blue;
}
HTML:
<ol id="sections">
<li>Item 1</li>
<li>Item 2</li>
<li>
<ol><li>Item A</li>
<li>Item C</li>
</ol>
</ol>
I could just set color to whatever my default is, but that's sort of a hack, and in the future if i add something to the #sections li style it could mess with the inner list style, so I presume this is bad coding form.
How do i make the inner list be unaffected by the outer list?
May want to instead do a new style for nested lists, like this:
ol ol li,
ol ul li,
ul ol li,
ul ul li
{
/* Nested list styles */
background: #FFF;
color: #000;
}
You could also use the > child selector to just target top level <li>s:
ol#selections > li
{
color: blue;
}
I believe what you want is
ul li {color:blue}
ul li li {color:white;}
just change the second color

CSS Direct Decedent Li

In css how would I change on hover the color of test 1 but not color of list 1, 2,3?
<ul>
<li>
test 1
<ul>
<li> List 1</li>
<li> List 2</li>
<li> List 3</li>
</ul>
</li>
</ul>
One way is to specify the "default" color:
li:hover {
color:#f00;
}
li, li:hover li {
color:#000;
}ā€‹
http://jsfiddle.net/D8dwt/1/
Another (cheat?) is to use more markup to wrap the content you want styled on hover:
li:hover span {
color:#f00;
}ā€‹
<ul>
<li>
<span>test 1</span>
<ul>
<li> List 1</li>
<li> List 2</li>
<li> List 3</li>
</ul>
</li>
</ul>ā€‹
This is one way to go:
ul > li {
color: red;
}
ul > li:hover {
color: blue;
}
ul > li:hover > ul > li {
color: red;
}
Add test1 into a div element so that it is in a separate leaf.
css:
div:hover {
color: blue;
}
Although there may be a way to do this without modifiying the html..
Give it it's own class and define it in your CSS file.
<li class="yourclass">
Or put it in tags and define the link in your CSS
li.yourclass a:hover {
text-decoration: underline ;
}

Showing Div via CSS selector within a UL

I want to build CSS drop down menus.
I want to solve the problem of too long drop down items in UL. So I want to use DIV within a UL.
If you run this example, heading 3 will show you drop down UL items. I want the same for Heading 2 link. Because I put that UL in a DIV. So how can I do it?
CSS Code:
li{
list-style: none;
float: left;
}
li ul {
display: none;
background-color: #69f;
}
li:hover > div#mDiv {
display: block;
}
.menuDiv{
display: none;
}
li:hover > ul {
display: block;
}
Markup:
<ul>
<li>Heading 1</li>
<li>Heading 2
<div class = "menuDiv" id = "mDiv">
<ul>
<li>Subitem 1</li>
<li>Subitem 2</li>
<li>Subitem 3</li>
</ul>
</div>
</li>
<li>Heading 3
<ul>
<li>Subitem 4</li>
<li>Subitem 5</li>
<li>Subitem 6</li>
</ul>
</li>
</ul>
Get rid of the > combinator so the inner uls get picked up whether they're in a containing div or not:
li:hover ul {
display: block;
}
If the > in your rules is required change this rule:
li:hover > div ul, li:hover > ul {
display: block;
}
Your problem is that because of your css, the div is shown on :hover, but the inner ul is not.
So you can use #BoltClock's solution or change:
li ul {
display: none;
background-color: #69f;
}
to:
li ul {
background-color: #69f;
}
li > ul {
display: none;
}