Styling nested lists with any depth - css

I was wondering if it's possible to style nested unordered lists with CSS only, without using any scripts. The problem is that CSS needs to work for any depth of the list tree.
For example, I have a list:
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li class="holder">
<ul>
<li>Item 4</li>
<li>Item 5</li>
<li class="holder">
<ul>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
<li class="holder">
<ul>
<li>Item 9</li>
<li>Item 10</li>
<li>Item 11</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
And this is my CSS:
li{
background: gray;
border: 1px solid;
display: block;
margin: 2px;
}
.holder{
background: none;
border: none;
}
/*replace these styles*/
li > ul > li{
background: white;
}
li > ul > li > ul > li{
background: gray;
}
li > ul > li > ul > li > ul > li{
background: white;
}
If node's parent has background A, node should have background B. If node's parent has background B, node should have background A.
Please check : http://jsfiddle.net/bCU34/6/

CSS selectors allow you to select all named elements of a parent node by separating the named element from the parent element with a space. To select all unordered list elements, for example, you would do like below. Notice all ul elements at any depth inherit the style no bullets/margin/padding. In order do style nth layer for an element type, you need to use the parent selector >. See below. I used font color but you could set background images the same way. Note there is no decendant level selector at this time that I know of. This was addressed on another post CSS select nested elements up to N levels deep.
.container ul {
list-style-type: none;
margin: 0;
padding: 0;
}
.container > ul > li {
color: green;
}
.container > ul > li > ul > li {
color: red;
}
.container > ul > li > ul > li > ul > li {
color: blue;
}
<section class="container">
<h1>CSS Nested List Styling</h1>
<ul>
<li>
<h3>Section 1</h3>
<ul>
<li>
<h4>Foo</h4>
<ul>
<li>
<h5>Bar</h5>
</li>
<li>
<h5>Bar</h5>
</li>
</ul>
</li>
<li>
<h4>Foo Bar</h4>
<ul>
<li>
<h5>Bar</h5>
</li>
<li>
<h5>Bar</h5>
</li>
</ul>
</li>
</ul>
</li>
<li>
<h3>Section 2</h3>
<ul>
<li>
<h4>Hello</h4>
<ul>
<li>
<h5>World</h5>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</section>

There isn’t any specific way of doing this currently with Selectors level 3, and the current draft of Selectors level 4 doesn’t seem to add anything either. I had a dig through the www-style mailing list and came up with this post by Lachlan Hunt from April 2005 that suggests that an :nth-descendant() style selector had been considered but never specified.

Related

How strike through a bullet in list

We have eBook, in that one of the list has strike through the text as well as the bullet. i can able to strike the text using (text-decoration: line-through;). But i can strike through the bullet in the list, please help me to get a solution?
Here is one way to implement
with Order list
HTML :
<body>
This fiddle is used to demonstrate the list styling with CSS
<ol>
<li> Item 1 </li>
<li> Item 2 </li>
<li> Item 3 </li>
<li> Item 4 </li>
</ol>
</body>
and CSS :
ol li
{
list-style-type: none;
counter-increment: item;
text-decoration:line-through;
}
ol li::before
{
content:counter(item) ".";
text-decoration:line-through;
}
With unordered list, it is a little bit more complicated
HTML:
<body>
This fiddle is used to demonstrate the unordered list styling with CSS
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
</ul>
</body>
and CSS:
ul{
float:left;
}
li {
list-style: circle;
list-style-position: inside;
margin-top:8px;
}
li:after{
border-top:1px solid red;
display:block;
content:"";
margin-top:-8px;
}

how to combine the css selector using ":not"

how can i summarize the following css code? The current css code will display all li element as none.
ul.cmpro-accordion > li:not(.cid-2),
ul.cmpro-accordion > li:not(.cid-61){
display: none;
}
It's about specificity.
<ul class="cmpro-accordion">
<li>li text 1</li>
<li class="cid-2">li text 2</li>
<li class="cid-61">li text 3</li>
<li>li text 4</li>
<li>li text 5</li>
</ul>
Css:
ul.cmpro-accordion > li.cid-2,
ul.cmpro-accordion > li.cid-61 {
display: block
}
ul > li:not(.cid-2),
ul > li:not(.cid-61) {
display: none;
}
Example

third level of CSS dropdown menu not appearing in two-column format

I have constructed a three-level dropdown using CSS. It works until I add this to the CSS:
columns: 2;
-webkit-columns: 2;
-moz-columns: 2;
The HTML is basically just two unordered lists (by the way, the "feelings" list and the "needs" list have the same content -- that will change eventually -- this is just for experimenting!):
<div class="feelings">
<ul class="nav feelings">
<li class="feelings" id="feelings"> FEELINGS
<ul>
<li>AFRAID
<ul>
<li>apprehensive</li>
<li>dread</li>
<li>foreboding</li>
<li>frightened</li>
<li>mistrustful</li>
<li>panicked</li>
<li>petrified</li>
<li>scared</li>
<li>suspicious</li>
<li>terrified</li>
<li>wary</li>
<li>worried</li>
</ul>
</li>
<li>ANNOYED
<ul>
<li>aggravated</li>
<li>dismayed</li>
<li>disgruntled</li>
<li>displeased</li>
<li>exasperated</li>
<li>frustrated</li>
<li>impatient</li>
<li>irritated</li>
<li>irked</li>
</ul>
</li>
<li>ANGRY
<ul>
<li>enraged</li>
<li>furious</li>
<li>incensed</li>
<li>indignant</li>
<li>irate</li>
<li>livid</li>
<li>outraged</li>
<li>resentful</li>
</ul>
</li>
<li>AVERSION
<ul>
<li>animosity</li>
<li>appalled</li>
<li>contempt</li>
<li>disgusted</li>
<li>dislike</li>
<li>hate</li>
<li>horrified</li>
<li>hostile</li>
<li>repulsed</li>
</ul>
</li>
<li>CONFUSED
<ul>
<li>ambivalent</li>
<li>baffled</li>
<li>bewildered</li>
<li>dazed</li>
<li>hesitant</li>
<li>lost</li>
<li>mystified</li>
<li>perplexed</li>
<li>puzzled</li>
<li>torn</li>
</ul>
</li>
<li>DISCONNECTED
<ul>
<li>alienated</li>
<li>aloof</li>
<li>apathetic</li>
<li>bored</li>
<li>cold</li>
<li>detached</li>
<li>distant</li>
<li>distracted</li>
<li>indifferent</li>
<li>numb</li>
<li>removed</li>
<li>uninterested</li>
<li>withdrawn</li>
</ul>
</li>
<li>DISQUIET
<ul>
<li>agitated</li>
<li>alarmed</li>
<li>discombobulated</li>
<li>disconcerted</li>
<li>disturbed</li>
<li>perturbed</li>
<li>rattled</li>
<li>restless</li>
<li>shocked</li>
<li>startled</li>
<li>surprised</li>
<li>troubled</li>
<li>turbulent</li>
<li>turmoil</li>
<li>uncomfortable</li>
<li>uneasy</li>
<li>unnerved</li>
<li>unsettled</li>
<li>upset</li>
</ul>
</li>
<li>EMBARRASSED
<ul>
<li>ashamed</li>
<li>chagrined</li>
<li>flustered</li>
<li>guilty</li>
<li>mortified</li>
<li>self-conscious</li>
</ul>
</li>
<li>FATIGUE
<ul>
<li>beat</li>
<li>burnt out</li>
<li>depleted</li>
<li>exhausted</li>
<li>lethargic</li>
<li>listless</li>
<li>sleepy</li>
<li>tired</li>
<li>weary</li>
<li>worn out</li>
</ul>
</li>
<li>PAIN
<ul>
<li>agony</li>
<li>anguished</li>
<li>bereaved</li>
<li>devastated</li>
<li>grief</li>
<li>heartbroken</li>
<li>hurt</li>
<li>lonely</li>
<li>miserable</li>
<li>regretful</li>
<li>remorseful</li>
</ul>
</li>
<li>SAD
<ul>
<li>depressed</li>
<li>dejected</li>
<li>despair</li>
<li>despondent</li>
<li>disappointed</li>
<li>discouraged</li>
<li>disheartened</li>
<li>forlorn</li>
<li>gloomy</li>
<li>heavy hearted</li>
<li>hopeless</li>
<li>melancholy</li>
<li>unhappy</li>
<li>wretched</li>
</ul>
</li>
<li>TENSE
<ul>
<li>anxious</li>
<li>cranky</li>
<li>distressed</li>
<li>distraught</li>
<li>edgy</li>
<li>fidgety</li>
<li>frazzled</li>
<li>irritable</li>
<li>jittery</li>
<li>nervous</li>
<li>overwhelmed</li>
<li>restless</li>
<li>stressed out</li>
</ul>
</li>
<li>VULNERABLE
<ul>
<li>fragile</li>
<li>guarded</li>
<li>helpless</li>
<li>insecure</li>
<li>leery</li>
<li>reserved</li>
<li>sensitive</li>
<li>shaky</li>
</ul>
</li>
<li>YEARNING
<ul>
<li>envious</li>
<li>jealous</li>
<li>longing</li>
<li>nostalgic</li>
<li>pining</li>
<li>wistful</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<div class="needs">
<ul class="nav needs">
<li class="feelings" id="needs"> NEEDS
<ul>
<li>AFRAID
<ul>
<li>apprehensive</li>
<li>dread</li>
<li>foreboding</li>
<li>frightened</li>
<li>mistrustful</li>
<li>panicked</li>
<li>petrified</li>
<li>scared</li>
<li>suspicious</li>
<li>terrified</li>
<li>wary</li>
<li>worried</li>
</ul>
</li>
<li>ANNOYED
<ul>
<li>aggravated</li>
<li>dismayed</li>
<li>disgruntled</li>
<li>displeased</li>
<li>exasperated</li>
<li>frustrated</li>
<li>impatient</li>
<li>irritated</li>
<li>irked</li>
</ul>
</li>
<li>ANGRY
<ul>
<li>enraged</li>
<li>furious</li>
<li>incensed</li>
<li>indignant</li>
<li>irate</li>
<li>livid</li>
<li>outraged</li>
<li>resentful</li>
</ul>
</li>
<li>AVERSION
<ul>
<li>animosity</li>
<li>appalled</li>
<li>contempt</li>
<li>disgusted</li>
<li>dislike</li>
<li>hate</li>
<li>horrified</li>
<li>hostile</li>
<li>repulsed</li>
</ul>
</li>
<li>CONFUSED
<ul>
<li>ambivalent</li>
<li>baffled</li>
<li>bewildered</li>
<li>dazed</li>
<li>hesitant</li>
<li>lost</li>
<li>mystified</li>
<li>perplexed</li>
<li>puzzled</li>
<li>torn</li>
</ul>
</li>
<li>DISCONNECTED
<ul>
<li>alienated</li>
<li>aloof</li>
<li>apathetic</li>
<li>bored</li>
<li>cold</li>
<li>detached</li>
<li>distant</li>
<li>distracted</li>
<li>indifferent</li>
<li>numb</li>
<li>removed</li>
<li>uninterested</li>
<li>withdrawn</li>
</ul>
</li>
<li>DISQUIET
<ul>
<li>agitated</li>
<li>alarmed</li>
<li>discombobulated</li>
<li>disconcerted</li>
<li>disturbed</li>
<li>perturbed</li>
<li>rattled</li>
<li>restless</li>
<li>shocked</li>
<li>startled</li>
<li>surprised</li>
<li>troubled</li>
<li>turbulent</li>
<li>turmoil</li>
<li>uncomfortable</li>
<li>uneasy</li>
<li>unnerved</li>
<li>unsettled</li>
<li>upset</li>
</ul>
</li>
<li>EMBARRASSED
<ul>
<li>ashamed</li>
<li>chagrined</li>
<li>flustered</li>
<li>guilty</li>
<li>mortified</li>
<li>self-conscious</li>
</ul>
</li>
<li>FATIGUE
<ul>
<li>beat</li>
<li>burnt out</li>
<li>depleted</li>
<li>exhausted</li>
<li>lethargic</li>
<li>listless</li>
<li>sleepy</li>
<li>tired</li>
<li>weary</li>
<li>worn out</li>
</ul>
</li>
<li>PAIN
<ul>
<li>agony</li>
<li>anguished</li>
<li>bereaved</li>
<li>devastated</li>
<li>grief</li>
<li>heartbroken</li>
<li>hurt</li>
<li>lonely</li>
<li>miserable</li>
<li>regretful</li>
<li>remorseful</li>
</ul>
</li>
<li>SAD
<ul>
<li>depressed</li>
<li>dejected</li>
<li>despair</li>
<li>despondent</li>
<li>disappointed</li>
<li>discouraged</li>
<li>disheartened</li>
<li>forlorn</li>
<li>gloomy</li>
<li>heavy hearted</li>
<li>hopeless</li>
<li>melancholy</li>
<li>unhappy</li>
<li>wretched</li>
</ul>
</li>
<li>TENSE
<ul>
<li>anxious</li>
<li>cranky</li>
<li>distressed</li>
<li>distraught</li>
<li>edgy</li>
<li>fidgety</li>
<li>frazzled</li>
<li>irritable</li>
<li>jittery</li>
<li>nervous</li>
<li>overwhelmed</li>
<li>restless</li>
<li>stressed out</li>
</ul>
</li>
<li>VULNERABLE
<ul>
<li>fragile</li>
<li>guarded</li>
<li>helpless</li>
<li>insecure</li>
<li>leery</li>
<li>reserved</li>
<li>sensitive</li>
<li>shaky</li>
</ul>
</li>
<li>YEARNING
<ul>
<li>envious</li>
<li>jealous</li>
<li>longing</li>
<li>nostalgic</li>
<li>pining</li>
<li>wistful</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
Here is the CSS:
#charset "UTF-8";
/* CSS Document */
ul ul, ul ul ul {
columns: 2;
-webkit-columns: 2;
-moz-columns: 2;
}
.nav feelings needs {
padding-left: 10px;
padding-right: 10px;
width: 200px;
color:#ff0000;
background-color:#ffffff;
}
.nav{
height: 39px;
border-radius: 3px;
min-width:500px;
border:1px solid #ddd;
background-color:#ffffff;
}
.nav li, .nav li li {
list-style: none;
display: block;
float: left;
height: 40px;
position: relative;
background-color:#ffffff;
}
.nav a {
width: 200px;
overflow:hidden;
}
.nav li a{
display: block;
}
.nav ul {
display: none;
visibility:hidden;
position: absolute;
top: 40px;
}
.nav ul ul {
top: 0px;
left:170px;
display: none;
visibility:hidden;
border: 1px solid #DDDDDD;
position: relative;
}
.nav ul li {
display: block;
visibility:visible;
}
.nav li:hover > ul, nav li:hover * {
display: block;
visibility:visible;
z-index:1;
}
If I eliminate the first CSS item (setting the menu to two columns), the last level of the menu appears (the items in small letters as opposed to all caps). With the two-column CSS in place, the third level doesn't appear.
Here is a fiddle:
http://jsfiddle.net/Lq7NK/2/
Interestingly, on the fiddle, the third level does seem to be trying to appear a bit, but it's certainly not working the way I'd like it to, which is the third level appearing in a vertical column to the right of the second level item.
Any thoughts will be appreciated!
/* image below was added after original question, in response to a request for a picture */
The top screenshot in this picture shows what comes up now when I hover over the first feeling, AFRAID -- and it is actually pretty much what I want (though obviously it needs some prettifying): two sets of two-column dropdowns, namely, the one in all caps and the one in all small letters. (This is basically with the code shown above, but with one change, namely, removing ul ul to leave only ul ul ul as suggested by user3369554.) However, when I move the cursor, stuff starts jumping all over the place; the screenshot on the bottom shows one state, but things just jump all over in a very disconcerting way. For instance, I would like to be able to just move the cursor over to where ANGRY is at the top of the second column. But if I try to do that, it jumps to somewhere else. And if I go to that place, it jumps to still another location. If the both sets of emotions (all caps and all small letters) would hold still in the configuration shown at the top, and let me click on them, I'd be happy.
I don't know if I'm understanding well, but you can get the third level in a 2 column format to the right of the second level, if you replace:
ul ul, ul ul ul
for
ul ul ul
Demo: http://jsfiddle.net/QKkg4/
Is that what your're after?

Creating simple CSS multilevel menu

I am trying to make a webpage with a navigation functionality EXACTLY like this one: http://www.rex-ny.com/ where you click a list item and its children items appear and stay.
I can do it with hover, but I can't figure out how to make it stay when not hovering.
It seems like the most simple thing is the most difficult to do.
<ul id="menu">
<li>Menu 1
<ul>
<li>Item A</li>
<li>Item B</li>
<li>Item C</li>
</ul>
</li>
<li>Menu 2
<ul>
<li>Item A</li>
<li>Item B</li>
<li>Item C</li>
</ul>
</li>
<li>Menu 3
<ul>
<li>Item A</li>
<li>Item B</li>
<li>Item C</li>
</ul>
</li>
</ul>
Thanks
Here is a jsfiddle http://jsfiddle.net/phzuC/
Here is a CSS only solution as the OP requested, using tabindex
DEMO http://jsfiddle.net/kevinPHPkevin/phzuC/2/
#menu li > ul {
display:none;
}
#menu li:focus > ul {
display:block;
}
li {
outline: 0;
}
EDITED
Here is a jQuery solution should you ever need it. It keeps the submenus open and it's simple to implement. 11 lines of code.
DEMO http://jsfiddle.net/kevinPHPkevin/phzuC/5/
$(document).ready(function() {
$(".nav-top > li").click(function(e) {
if($(this).find('ul').hasClass('expanded')) {
$(this).find('ul').removeClass('expanded').hide();
} else {
$(this).find('ul').addClass('expanded').show();
}
});
$('.nav-top a').click(function(e){
e.preventDefault();
});
});
Here is another CSS only solution that uses either:
Checkboxes if you want the menus to toggle on click
radio buttons if you want the menus to auto close when another is selected
Reference:
CSSTricks: Stuff you can do with the “Checkbox Hack”
The CSS Ninja: CSS Tree
Demo
Basic behavior CSS (the demo has more styling to remove the default list indentation/bullets):
.sideMenu input[type='radio'],
.sideMenu input[type='checkbox'] {
display: none;
}
.sideMenu input[type='radio'] + ul,
.sideMenu input[type='checkbox'] + ul {
position: relative;
display: none;
}
.sideMenu input[type='radio']:checked + ul,
.sideMenu input[type='checkbox']:checked + ul {
display: block;
}
HTML (can be arbitrarily deep):
<nav class="sideMenu">
<ul>
<li>
<label for="menu1">Menu 1</label>
<input id="menu1" type="checkbox" name="menu1">
<ul>
<li>Item A</li>
<li>Item B</li>
<li>Item C</li>
</ul>
</li>
<!-- repeat -->
</ul>
</nav>

target first submenu of parent ul

I need to target css for the first level ul submenu in a parent ul.
CSS:
#menu li:hover > ul.sub_menu { ...some styles }
..but this will ofcourse do it for all the sub_menu's, I only want this particular style for the first sub_menu relative to the parent when you hover over the parent list item.
HTML:
<ul id="menu">
<li>Item
<ul class="sub_menu"><!-- target only this one -->
<li>Item
<ul class="sub_menu">etc...</ul><!-- do not do for this one and so on-->
</li>
</ul>
</li>
<li>Item
<ul class="sub_menu"><!-- target only this one -->
<li>Item
<ul class="sub_menu">etc...</ul><!-- do not do for this one and so on-->
</li>
</ul>
</li>
</ul>
Thanks for any feedback...
You can use the :first-child selector:
#menu > li:first-child > ul.sub_menu {
color: red;
}
And then use the descendant selector to revert the changes for the other elements:
#menu > li:first-child > ul.sub_menu ul {
color: black;
}
Demo: http://jsfiddle.net/6y4Sb/

Resources