Problem:
I'm making a nav CSS module. I'm wanting submenus to have a different background color than their parent menu. However, if there is a submenu within a submenu, I need that submenu to have the same background color as it's parent's parent. I know I could do this fairly verbosely if I set a limit on the number of submenus that would be allowed but I would prefer the option to have as many nested menus as needed and have them colored appropriately. Is there some CSS trickery that can do this or am I relegated to JS for this?
I've looked into :nth-child
and :nth-of-type
but these only apply to sibling elements within a parent node as far as I know.
Code:
ul.nav {
list-style: none;
}
ul.nav.dropdown {
height: 0;
overflow: hidden;
}
ul.nav.dropdown.show {
height: auto;
}
ul.nav li {
background-color: #44499f;
}
ul.nav ul li {
background-color: #b6ff00;
}
<ul class="nav">
<li><a>Test link</a></li>
<li><a>Test link</a></li>
<li><a>Test link</a></li>
<li>
<a class="dropdown-toggle">Test dropdown</a>
<ul class="nav dropdown">
<li><a>Test link</a></li>
<li><a>Test link</a></li>
<li><a>Test link</a></li>
<li>
<a class="dropdown-toggle">Test dropdown</a>
<ul class="nav dropdown">
<li><a>Test link</a></li>
<li><a>Test link</a></li>
<li><a>Test link</a></li>
</ul>
</li>
</ul>
</li>
</ul>
Here is an idea based on my previous answer where I will rely on a recursive behavior of CSS variables and gradient coloration. The trick is to increment the variable on each level and at the same time move the background and we will alternate between both colors:
:root {
--x:0;
}
ul.nav {
list-style: none;
position: relative;
border:1px solid;
background:
linear-gradient(yellow 50%,pink 0) 0 calc(var(--x)*100%)/100% 200%;
--y: calc(var(--x) + 1);
}
ul.nav li {
--x: calc(var(--y));
}
<ul class="nav">
<li><a>Test link</a></li>
<li><a>Test link</a></li>
<li><a>Test link</a></li>
<li>
<a class="dropdown-toggle">Test dropdown</a>
<ul class="nav dropdown">
<li>
<a class="dropdown-toggle">Test dropdown</a>
<ul class="nav dropdown">
<li><a>Test link</a></li>
<li><a>Test link</a></li>
<li>
<a class="dropdown-toggle">Test dropdown</a>
<ul class="nav dropdown">
<li><a>Test link</a></li>
<li><a>Test link</a></li>
<li><a>Test link</a></li>
</ul>
</li>
</ul>
</li>
<li><a>Test link</a></li>
<li><a>Test link</a></li>
<li>
<a class="dropdown-toggle">Test dropdown</a>
<ul class="nav dropdown">
<li><a>Test link</a></li>
<li><a>Test link</a></li>
<li><a>Test link</a></li>
</ul>
</li>
</ul>
</li>
</ul>
You can also do with 3 colors
:root {
--x:0;
}
ul.nav {
list-style: none;
position: relative;
border:1px solid;
background:
linear-gradient(lightblue 33.33%,yellow 33.33% 66.66%,pink 0) 0 calc(var(--x)*100%)/100% 300%;
--y: calc(var(--x) + 1);
}
ul.nav li {
--x: calc(var(--y));
}
<ul class="nav">
<li><a>Test link</a></li>
<li><a>Test link</a></li>
<li><a>Test link</a></li>
<li>
<a class="dropdown-toggle">Test dropdown</a>
<ul class="nav dropdown">
<li>
<a class="dropdown-toggle">Test dropdown</a>
<ul class="nav dropdown">
<li><a>Test link</a></li>
<li><a>Test link</a></li>
<li>
<a class="dropdown-toggle">Test dropdown</a>
<ul class="nav dropdown">
<li><a>Test link</a></li>
<li><a>Test link</a></li>
<li><a>Test link</a></li>
</ul>
</li>
</ul>
</li>
<li><a>Test link</a></li>
<li><a>Test link</a></li>
<li>
<a class="dropdown-toggle">Test dropdown</a>
<ul class="nav dropdown">
<li><a>Test link</a></li>
<li><a>Test link</a></li>
<li><a>Test link</a></li>
</ul>
</li>
</ul>
</li>
</ul>
You can easily increase to any number of colors. Simply make the background size to be n*100%
with n
number of colors and split the color inside the gradient so each one will have the same proportion 100%/n
Related question to understand the calculation behind the background values:
Using percentage values with background-position on a linear gradient
Though my answer is very obvious I've used classnames,
.oddNav{
background: red;
}
.evenNav{
background: blue;
}
<ul class="nav1 oddNav">
<li>firstlist</li>
<li>
<ul class="nav2 evenNav">
<li>SecondList</li>
<li>
<ul class="nav3 oddNav">
<li>ThirdList</li>
<li>
<ul class="nav4 evenNav">
<li>FourthList</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With