How to select the first level of children (li) from ul - html

Given the following structure, I want to select the first level of children (li) from the list (ul), but not the nested list.
ul.list > li {
background-color: red;
}
<ul id="list" class="list">
<li>first level</li>
<li>first level</li>
<li>
<h1></h1>
<div>
<ul>
<li>second level</li>
<li>second level</li>
</ul>
</div>
</li>
<li></li>
</ul>
(JSFiddle)
But that selects also the items (li) inside the div.
I want to select the first level of children (li) using only ONE css RULE. How?

css does not have a selector that would allow you to specify that all/none of the ancestor elements must match certain critieria (i.e. not be a list), you would need xpath for that.
but what you can do is the following:
ul > li {
// top level list item styles here
}
li ul > li {
all: initial;
// nested item styles here
}
See MDN all for documentation on resetting styles. You can also selectively unset specific properties.

you need to identify your first ul:
<ul class="my-list">
<li></li>
<li></li>
<li>
<h1></h1>
<div>
<ul>
<li></li>
<li></li>
</ul>
</div>
</li>
<li></li>
</ul>
then select it with ul.my-list>li

CSS
ul li div ul li {
/* Your styles here to override parent (if they are over 70% the same) */
}

You can add a class to the <li>s which contain second-level content and then exclude them from the main CSS query using the :not pseudo-class
ul.list > li:not(.level2) {
background-color: red;
}
<ul class="list">
<li>first level</li>
<li>first level</li>
<li class="level2"> first level with nested content
<h1>some title</h1>
<div>
<ul>
<li>second level</li>
<li>second level</li>
</ul>
</div>
</li>
<li>first level</li>
</ul>

What you have does work, you just need to style the inner li's too, as their background by default is transparent.
Note though, that some properties are inherited by default and will be picked up by the inner li's and needs to be set explicit, like the font color.
ul.list > li li {
background-color: black;
}
ul.list > li {
background-color: red;
color: blue;
}
ul.list2 > li li {
background-color: black;
color: yellow;
}
ul.list2 > li {
background-color: red;
color: blue;
}
<div>Sample 1</div>
<ul id="list" class="list">
<li>first level</li>
<li>first level</li>
<li>
<h1></h1>
<div>
<ul>
<li>second level</li>
<li>second level</li>
</ul>
</div>
</li>
<li></li>
</ul>
<hr>
<div>Sample 2</div>
<ul id="list2" class="list2">
<li>first level</li>
<li>first level</li>
<li>
<h1></h1>
<div>
<ul>
<li>second level</li>
<li>second level</li>
</ul>
</div>
</li>
<li></li>
</ul>

in your case the problem is background-color, the color is only applied on .list>li but childrens show parent's background.
to separate color, you need to add element (for example div or span)
.list>li>span{
background-color: red;
}
<ul id="list" class="list">
<li><span>first level</span></li>
<li><span>first level</span></li>
<li>
<h1></h1>
<div>
<ul>
<li>second level</li>
<li>second level</li>
</ul>
</div>
</li>
<li></li>
</ul>

Related

Selecting last child of recursive list structure with CSS

I Want to select last Element of div.container <ul> inside last <li> with css.
The ul of nested will goes n level so please suggest to me if it possible with jquery also.
ul {
list-style: none;
margin: 0;
padding: 0;
}
<div class="container">
<ul>
<li>
<ul>
<li>Nested Item</li>
<li>
<ul>
<li>Nested Item</li>
<li>
<ul>
<li>Nested Item</li>
<li>
<ul>
<li>Nested Item</li>
<li>
<ul>
<li>Nested Item</li>
<li>Want to select list with css</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
view the image that i want to select with css
You can use some tricks to make it.
If you are looking for last element then you can use of :nth-last-child(n) selector, this matches on every element in the nth child and it doesn't look for type or its parent.
This is achieved as it counts from the last child.
.container ul li:nth-last-child(1)
{
color: red;
font-size:22px;
}
.container li li {
color: green;
font-size:12px;
}
Look at here:
MyFiddel

Style link in a li

I have this list in HTML
<div id="sideMenu">
<li class="current_page_parent">
Category 1
<ul class="children">
<li>Sub</li>
<li>Sub</li>
<li>Sub</li>
<li>Sub</li>
</ul>
</li>
<li></li>
<li></li>
</div>
I want to put a background-color to my first link : 'Category 1' without affecting others links
Here's my CSS
.current_page_parent li:not(.children) a {
display: block;
padding: 5px 15px;
background-color: #d6205c;
}
You can use first-of-type combined with a > combinator selector
The :first-of-type CSS pseudo-class represents the first sibling of
its type in the list of children of its parent element.
The > combinator separates two selectors and matches only those
elements matched by the second selector that are direct children of
elements matched by the first.
li.current_page_parent:first-of-type > a{
display: block;
padding: 5px 15px;
background-color: #d6205c;
}
li.current_page_parent:first-of-type > a {
display: block;
padding: 5px 15px;
background-color: #d6205c;
}
<div id="sideMenu">
<li class="current_page_parent">
Category 1
<ul class="children">
<li>Sub
</li>
<li>Sub
</li>
<li>Sub
</li>
<li>Sub
</li>
</ul>
</li>
<li></li>
<li></li>
</div>
You can add class propery to the particular <a> and directly select the particular attribute by their class name
Here's example:
HTML:
<div id="sideMenu">
<li class="current_page_parent">
<a class="notInULChildren" href="#">Category 1</a>
<ul class="children">
<li>Sub</li>
<li>Sub</li>
<li>Sub</li>
<li>Sub</li>
</ul>
</li>
<li></li>
<li></li>
</div>
CSS:
.notInULChildren{
display: block;
padding: 5px 15px;
background-color: #d6205c;
}
FIDDLE

How to hover only the current li in nested ul?

I have a nested list:
li:hover {
background-color: lightgray;
}
ul li ul li:hover {
font-weight: bold;
}
<ul>
<li>fnord
<ul>
<li>baz</li>
<li>foo
<ul>
<li>baz</li>
<li>foo</li>
</ul>
</li>
</ul>
</li>
<li>gnarf
<ul>
<li>baz</li>
<li>foo
<ul>
<li>baz</li>
<li>yolo</li>
</ul>
</li>
</ul>
</li>
</ul>
Problem is, hovering "foo" will also hover "fnord" and all of its li elements. How do I hover only the li my mouse is actually hovering over?
The nesting is variable and can, in theory, be endless.
I have setup a JSFiddle.
A solution for subitems and also for parents is possible without JavaScript, when you will add some inline element, which will trigger hover state.
li>span:hover {
background-color: lightgray;
font-weight: bold;
}
<ul>
<li><span>fnord</span>
<ul>
<li><span>baz</span></li>
<li><span>foo</span>
<ul>
<li><span>baz</span></li>
<li><span>foo</span></li>
</ul>
</li>
</ul>
</li>
</ul>
JSFiddle here.
I believe the closest you can get with just CSS is to remove the hover styling from the children of the hovered elements... which doesn't help the parents.
li:hover {
background-color: lightgray;
}
li:hover {
font-weight: bold;
}
li:hover ul {
background-color: white;
font-weight: normal;
}
<ul>
<li>fnord
<ul>
<li>baz</li>
<li>foo
<ul>
<li>baz</li>
<li>foo</li>
</ul>
</li>
</ul>
</li>
<li>gnarf
<ul>
<li>baz</li>
<li>foo
<ul>
<li>baz</li>
<li>foo</li>
</ul>
</li>
</ul>
</li>
</ul>
JSFiddle
The accepted answer on the duplicate you found is the best way I've seen to do this with JavaScript, using e.stopPropagation: Cascading <li>-hover effect using CSS. You'll want to be more specific than 'all lis' in that selector though:
$('li').mouseover(function(e)
{
e.stopPropagation();
$(this).addClass('currentHover');
});
$('li').mouseout(function()
{
$(this).removeClass('currentHover');
});
.currentHover {
background-color: red;
}
li.currentHover ul {
background-color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="container">
<li>fnord
<ul>
<li>baz</li>
<li>foo
<ul>
<li>baz</li>
<li>foo</li>
</ul>
</li>
</ul>
</li>
<li>gnarf
<ul>
<li>baz</li>
<li>foo
<ul>
<li>baz</li>
<li>foo</li>
</ul>
</li>
</ul>
</li>
</ul>
JSFiddle of the answer from there.
So you just want to directly target an li? Try this:
ul li ul li:hover{
background-color: red;
}
Demo here
Edit
I also added another EXAMPLE of where the menu could indeed keep on expanding.
Use this selector to hover
ul ul li:hover {}
it can style only element with foo
In 2023 it is now possible with plain CSS and no modification to HTML by using :has() and :not() pseudo-selectors for Chromium-based browsers, but unfortunately :has is not fully supported in Firefox as of January 2023 (users need to opt-in via layout.css.has-selector.enabled flag, and there are relevant features not yet implemented). For up-to-date status see https://caniuse.com/css-has
li:not(:has(li:hover)):hover {
background-color: lightgray;
}
<ul>
<li>fnord
<ul>
<li>baz</li>
<li>foo
<ul>
<li>baz</li>
<li>foo</li>
</ul>
</li>
</ul>
</li>
<li>gnarf
<ul>
<li>baz</li>
<li>foo
<ul>
<li>baz</li>
<li>yolo</li>
</ul>
</li>
</ul>
</li>
</ul>

Struggling to get correct css formatting on nest ul list

I'm struggling with this, I'd like my first li to have a round bullet and then the nested li's to have an indented square bullet. My CSS trying to do this is below, default styling of my page is not putting any bullets in place.
Can someone help?
<ul>
<li>Simplification of a complex purchase category
<ul>
<li>Meet local regulatory compliance </li>
<li>Subitem 2</li>
</ul>
</li>
<li>Final list item</li>
</ul>
CSS
ul:first-child {
list-style-type:circle;
}
li:first-child {
list-style-type:square;
}
li:nth-child(2) {
list-style-type:square;
}
try this:
li {
list-style-type:circle;
}
li li {
list-style-type:square;
}
you could use classes on your tags to set the list-style-type.
HTML
<ul class="round">
<li>Simplification of a complex purchase category
<ul class="square">
<li>Meet local regulatory compliance </li>
<li>Subitem 2</li>
</ul>
</li>
<li>Final list item</li>
</ul>
CSS:
.round {
list-style-type:bullet;
}
.square {
list-style-type:square;
}
http://jsfiddle.net/8H9JA/

Select the li in the list

List:
<ul>
<li>
Item 1
<ul>
<li>
Item 1-1
<ul>
<li>Item 1-1-1</li>
<li>
Item 1-1-2
<ul>
<li><a href="#">Item 1-1-2-1</li>
</ul>
</li>
</ul>
</li>
<li>Item 1-2</li>
<li>Item 1-2</li>
</ul>
</li>
<li>Item 2</li>
</ul>
Here's some relevant CSS
#nav ul ul {
display: none;
}
#nav ul li:hover > ul {
display: block;
}
The first one will hide every drop down item. The second will match any ul that is a children of the parent #nav ul li:hover, if so display:block and the drop down is visible.
Now because when hovering a item, the items within will simply be listed below, this is not what I am looking to achieve. I want to move the Item 1-1-1 and Item 1-1-2 to be on the right of Item 1-1, the Item 1-1-1 needs to be on the right, Item 1-1-2 will be below it (acting as a drop-down list). I am not sure how I select that element.
Example: http://line25.com/wp-content/uploads/2012/css-menu/demo/index.html
Here's what I got so far:
http://jsfiddle.net/Gq8C2/
I tried with first-child, such as:
#nav ul li:hover > ul li:first-child {
display: block;
}
I also tried using position absolute and relative, It almost gave me the result I wanted, but I wasn't able to grab the first item...
There must be a better way of doing this...
How do I select it? And how do I make a similar behavior to that I've been describing above?
Why don't you just use the css/html of the page you linked to instead of trying to reinvent it?
HTML:
<nav>
<ul>
<li>Home</li>
<li>Tutorials
<ul>
<li>Photoshop</li>
<li>Illustrator</li>
<li>Web Design
<ul>
<li>HTML</li>
<li>CSS</li>
</ul>
</li>
</ul>
</li>
<li>Articles
<ul>
<li>Web Design</li>
<li>User Experience</li>
</ul>
</li>
<li>Inspiration</li>
</ul>
</nav>
CSS
Review this Fiddle http://jsfiddle.net/Gq8C2/10/
I use position:absolute for the sub-sub menu :
#nav ul li ul li ul {
position:absolute;
top:0;
left:100%;
}
In order to upgrade your code you can assign a class for each level of the menu like
<ul class="Third_level">