2

I have the following markup:

ul {
  list-style-type: none;
}

ul:not(.sub-menu) {
  padding: 0px;
}

ul li {
  padding-top: 10px;
}

ul li:first-child:not(.sub-menu) {
  margin-bottom: 30px;
}

.submenu {
  margin-left: 20px;
}
<ul>
  <li>test</li>
  <li>test</li>
  <li>test</li>
  <li>has submenu
    <ul class="submenu">
      <li>child</li>
      <li>child</li>
    </ul>
  </li>
</ul>

I want the li's which doesn't have a nested ul to have a margin-bottom of 30px. But with my current approach, it adds a margin to the nested ul li elements too.

I almost need to do ul li:first-child:not(.sub-menu li) but that's not possible. What's the workaround?

Freddy
  • 1,651
  • 2
  • 13
  • 40
  • Why don't you just give your first ul a class `first-ul` and style them like `ul.first-ul li { margin: 10px }`? – Roberto Zvjerković Jul 19 '19 at 11:36
  • 1
    You want to select `li` based on children so that would require https://developer.mozilla.org/en-US/docs/Web/CSS/:has which currently is not supported in css. – Nenad Vracar Jul 19 '19 at 11:40
  • @ritaj your answer still will select all `li` elements, you will need to change it to `ul.first-ul > li` – Kyle Alexander Jul 19 '19 at 11:48
  • To be more specific selector would look something like this `li:not(:has(> ul.submenu))` but this would also select nested li's so then you need to select based on parent `ul:not(.submenu) li:not(:has(> ul.submenu))` – Nenad Vracar Jul 19 '19 at 11:54

1 Answers1

0

This should work if you can't edit the html and don't need it to be dynamic

ul > li:not(:nth-of-type(4)){
    margin-bottom: 30px;
}

I've selected all direct child li elements of the parent ul, except the 4th

OR

If you need it to be dynamic you can use jQuery

$('ul li').each(function(){ // cycle through each li

    if(!$(this).parent().hasClass('submenu')){ // check if parent doesn't have class 'submenu'

        $(this).css('padding-bottom','30px'); // if not, add padding
    }

})