Search code examples
csscss-variablescssom

How to express a predictably repeating pattern of declarations in CSS?


Is there any elegant (ie. non-verbose) way to express the following CSS styles in a stylesheet?

.my-class ul li::after {left: 162px;}
.my-class ul ul li::after {left: 180px;}
.my-class ul ul ul li::after {left: 198px;}
.my-class ul ul ul ul li::after {left: 216px;}
.my-class ul ul ul ul ul li::after {left: 234px;}
.my-class ul ul ul ul ul ul li::after {left: 252px;}
.my-class ul ul ul ul ul ul ul li::after {left: 270px;}
.my-class ul ul ul ul ul ul ul ul li::after {left: 288px;}
.my-class ul ul ul ul ul ul ul ul ul li::after {left: 306px;}
.my-class ul ul ul ul ul ul ul ul ul ul li::after {left: 324px;}
.my-class ul ul ul ul ul ul ul ul ul ul ul li::after {left: 342px;}
.my-class ul ul ul ul ul ul ul ul ul ul ul ul li::after {left: 360px;}
.my-class ul ul ul ul ul ul ul ul ul ul ul ul ul li::after {left: 378px;}
.my-class ul ul ul ul ul ul ul ul ul ul ul ul ul ul li::after {left: 396px;}
.my-class ul ul ul ul ul ul ul ul ul ul ul ul ul ul ul li::after {left: 414px;}
.my-class ul ul ul ul ul ul ul ul ul ul ul ul ul ul ul ul li::after {left: 432px;}
.my-class ul ul ul ul ul ul ul ul ul ul ul ul ul ul ul ul ul li::after {left: 450px;}
.my-class ul ul ul ul ul ul ul ul ul ul ul ul ul ul ul ul ul ul li::after {left: 468px;}
.my-class ul ul ul ul ul ul ul ul ul ul ul ul ul ul ul ul ul ul ul li::after {left: 486px;}

I know that I can add the style rules above to the CSSOM computationally using the following loop in javascript:

for (var i = 1; i < 20; i++) {
    var nestedLists = 'ul ';
    var selector = 'left: ' + (144 + (18 * i)) + 'px;';
    var lastRule = document.styleSheets[0].cssRules.length;
    document.styleSheets[0].insertRule('.my-class ' + nestedLists.repeat(i) + ' li::after {' + selector + '}', lastRule);
}

but I am looking for some kind of concise CSS-native syntax to express the lines above, if that's possible.

eg. Can something clever be achieved using CSS Custom Properties?


Please no solutions using Less or Sass. Thanks.


Here is a screenshot displaying the absolutely-positioned ::after pseudo-elements:

enter image description here


Solution

  • As mentioned in the body of the question, one approach is to deploy some javascript to write the CSS Rules to the CSSOM, computationally:

    Working Example:

    for (var i = 1; i < 20; i++) {
        var nestedLists = 'ul ';
        var selector = 'left: ' + (144 + (18 * i)) + 'px;';
        var lastRule = document.styleSheets[0].cssRules.length;
        document.styleSheets[0].insertRule('.my-class ' + nestedLists.repeat(i) + ' li::after {' + selector + '}', lastRule);
        console.log(document.styleSheets[0].cssRules[lastRule].cssText);
    }