3

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/

gradosevic
  • 4,809
  • 2
  • 36
  • 51
  • 2
    IMO it's not possible to select nested list elements frequently. One possible solution is adding `.odd` and `.even` classes to the nested list elements (`
      `s) and apply the desired styles this way.
    – Hashem Qolami Mar 08 '14 at 14:24
  • 2
    since an li can only exist as a child of a ul, you don't need the ul in the selectors. And you can put several levels of li in one selector, separated by a comma. This simplifies the total CSS down to `li li, li li li li, li li li li li li {...` etc. See http://jsfiddle.net/MrLister/bCU34/8/ – Mr Lister Mar 08 '14 at 15:12
  • @MrLister This is nice improvement, thanks! – gradosevic Mar 08 '14 at 16:07
  • @MrLister: Well... it can also exist as a child of an `ol` ;) – ScottS Mar 11 '14 at 19:28
  • @ScottS and `menu` and `dir`. But then you'll say those are deprecated! And I'll counter with "not `menu`, not in HTML5!", to which you'll reply that `menu` is no longer a list, etc. – Mr Lister Mar 11 '14 at 19:52
  • @MrList please reply with your answer as an answer! Putting answers in the comments is not what the comments are for. – Fernker Mar 13 '14 at 20:26
  • @Fernker It was not an answer; not even a workaround. There is no answer to the question AFAIK. I merely mentioned some possible improvements to the OP's current setup, as a consolation prize. – Mr Lister Mar 13 '14 at 21:08
  • @Fernker: It is the "any depth" part that at present makes a pure CSS solution (as asked for) currently impossible, and why Mr. Lister's answer is not really an "answer". – ScottS Mar 14 '14 at 16:52

2 Answers2

2

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>
Ronnie Royston
  • 16,778
  • 6
  • 77
  • 91
0

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.

Robin Whittleton
  • 6,159
  • 4
  • 40
  • 67