How to select immediate next element after nested elements?

Viewed 345

I'd need to apply a style to paragraphs that are immediately after two nested unordered lists. I know the way to apply the style to a paragraph immediately after one ul would be:

.class ul+p 

But I can't figure out how to narrow that down to only be in effect after two nested ul's? This is how I tried to do it, but it does not work:

.class ul ul + p 

Code example:

.class ul + p {
  color:red;
}

.class ul ul {
  color:purple;
}

/* This is just an example of what I tried, does not work */
.class ul ul + p { 
  color:green;
}
<div class="class">
  <ul>
    <li>Item a</li>
    <li>Item b
      <ul>
        <li>Item c (Nested list, CSS for this works fine)</li>
        <li>Iten d (should be purple)</li>
      </ul>
    </li>
  </ul>
  <p>Paragraph after nested ul, this is the one I can't get to work, 
  what kind of CSS would I need? (should be green)</p>
  <ul>
      <li>item e</li>
      <li>item f</li>
  </ul>
  <p>Paragraph after single ul, CSS for this works fine (should be red)</p>
</div>

3 Answers

ul ul + p doesn't work because the paragraph is a sibling of the first ul.

The nested ul, being a descendant of the first ul, is not a sibling of the p. So the next sibling combinator (+) cannot function as you expect.

<ul><!-- top level ul; sibling of the parapraph element -->
  <li>Item a</li>
  <li>Item b
    <ul><!-- nested ul; not a sibling of the parapraph element -->
      <li>Item c (Nested list, CSS for this works fine)</li>
      <li>Iten d (should be purple)</li>
    </ul>
  </li>
</ul>
<p>Paragraph after nested ul, this is the one I can't get to work, 
 what CSS would I need? (should be green)</p><!-- sibling of the top level ul -->

For a pure CSS solution you need something like the :has() pseudo class. The selector might look like this:

ul:has(> ul) + p

Unfortunately, :has() is not yet supported by any major browsers.

So, try JavaScript.

Your code says you want to target the adjacent paragraph inside the nested unordered list item (blue) and I put in an example that is the adjacent paragraph to the parent ul (red), so which one you use depends on the effect you're going for (you didn't post your HTML).

The trouble here is CSS works inwards because of the global cascade, not outwards, so to do this another way would require JavaScript.

(EDIT: I've edited the code to show the adjacent paragraph to the nested ul in green)

ul ul + p {
color: blue;
}

ul + p {
color: red;
}

.ul-nested--class + p {
color: green;
}
<ul class="ul-nested--class">
<li>List thing</li>
<li>List thing</li>
<li>List thing</li>
<li>
<ul>
<li>List thing</li>
<li>List thing</li>
<li>List thing</li>
<li>List thing</li>
</ul>
<p>This does validate</p>
<p>This does validate</p>
<p>This does validate</p>
<p>This does validate</p>
</li>
</ul>
<p>Next paragraph</p>
<p>Next paragraph</p>
<p>Next paragraph</p>
<p>Next paragraph</p>
<p>Next paragraph</p>

You can achieve that by giving an id or class to the parent ul element and using + selector to target paragraph. Like this :

#idname/.classname + p {
//Do whatever you want
}
Related