I am working on a tree view of undeterminable nestability, but would like to define some nested rules for styling. For example, I want the first level item to have a particular border. Nested items immediately underneath to have a different border. I have a working example, but it is static and verbose. I know there has to be a better way using selectors, but I can't seem to make it work. Here is my current solution-
.item {
border-left-color: #somecolor1;
}
.item > .item {
border-left-color: #somecolor2;
}
.item > .item > .item {
border-left-color: #somecolor3;
}
.item > .item > .item > .item {
border-left-color: #somecolor4;
}
.item > .item > .item > .item > .item {
border-left-color: #somecolor5;
}
So this works, but obviously it is kind of verbose. Is there a better way?
The :nth-child(n) selector matches every element that is the nth child of its parent. n can be a number, a keyword (odd or even), or a formula (like an + b). Tip: Look at the :nth-of-type() selector to select the element that is the nth child, of the same type (tag name), of its parent.
Direct Nesting. A style rule can be directly nested within another style rule if its selector is nest-prefixed. To be nest-prefixed , a nesting selector must be the first simple selector in the first compound selector of the selector.
The :nth-last-child(n) selector matches every element that is the nth child, regardless of type, of its parent, counting from the last child.
In CSS the selector string is largely describing the nesting structure, and there does not currently exist any generational skipping selectors such that you might theoretically do something like .item:nth-grandchild(4)
to replace your fifth example.
If reducing verbosity of your css is of high importance to you (lets say you have up 10 or even 100 levels of nesting you are switching on), then really you need to look into modifying the html itself in order to reduce the css needed. That can be done dynamically via server-side scripting (PHP, etc.), or client-side scripting (Javascript), or statically by you. Which way you choose will depend on a variety of factors.
The html modification can be in the form of more specific classes or direct style properties, but I recommend the former. Here are at least four ways css would be reduced:
#1 Multiple Classes, One Indicating Level
Sample HTML
<div class="item L-1">
<div class="item L-2">
<div class="item L-3">
</div>
</div>
</div>
Sample CSS
.item.L-1 {
border-left-color: #somecolor1;
}
.item.L-2 {
border-left-color: #somecolor2;
}
.item.L-3 {
border-left-color: #somecolor3;
}
#2 Multiple Classes, One Indicating Color
Sample HTML
<div class="item LBC-1">
<div class="item LBC-2">
<div class="item LBC-3">
</div>
</div>
</div>
Sample CSS
.item.LBC-1 {
border-left-color: #somecolor1;
}
.item.LBC-2 {
border-left-color: #somecolor2;
}
.item.LBC-3 {
border-left-color: #somecolor3;
}
#3 Single Class Name Indicating Level
Sample HTML
<div class="item-L1">
<div class="item-L2">
<div class="item-L3">
</div>
</div>
</div>
Sample CSS
[class *= "item-"] {
/* common css properties for the items goes here */
}
.item-L1 {
border-left-color: #somecolor1;
}
.item-L2 {
border-left-color: #somecolor2;
}
.item-L3 {
border-left-color: #somecolor3;
}
#4 Style Properties for Each Item
Sample HTML
<div class="item" style="border-left-color: #somecolor1">
<div class="item" style="border-left-color: #somecolor2">
<div class="item" style="border-left-color: #somecolor3">
</div>
</div>
</div>
Sample CSS
/* none to control color */
Often dynamic solutions end up producing html like that of #4, which ends up making the html very verbose, and I personally would not recommend it. However, those dynamic solutions do not need to do that, but could instead add class names like #1-3.
What is ultimately "best" depends a lot on what you are trying to achieve, how much control you have, and what other properties need changing as well. Personally, I would avoid #2 as well, because it begins to tie presentation too much to html by having a class name associated with the "left border color." To me, solution #1 or #3 would be best, as those are simply setting classes that help the css to know what "level" the .item
is at, which then allows for specific targeting to that level for anything you may need it for.
Of course, if you were really dealing with 100 nested levels, then even for solutions #1-3, you might want to look into some css preprocessor to generate the 100 levels of code needed. But the css output would still be far less than the long selector strings needed using the current method you are doing.
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