htmlcsssassfrontendrepeat

Using SASS, how can I have classes of a parent element also be applied to the direct children elements?


In order to avoid code repetition, ideally I would like to apply a class to a DOM element (for example "children") and have the rest of the classes applied to that element affect the direct children elements of that element. Here is an example to clarify the idea:

I have this piece of code:

<ul class="text-list tl-type-disc">
  <li class="text t-body t-light margin m-tiny m-vertical">some text</li>
  <li class="text t-body t-light margin m-tiny m-vertical">some text</li>
  <li class="text t-body t-light margin m-tiny m-vertical">some text</li>
  <li class="text t-body t-light margin m-tiny m-vertical">some text</li>
  <li class="text t-body t-light margin m-tiny m-vertical">some text</li>
</ul>

And I would like to turn it into something like this:

<ul class="text-list tl-type-disc children text t-body t-light margin m-tiny m-vertical">
  <li class="">some text</li>
  <li class="">some text</li>
  <li class="">some text</li>
  <li class="">some text</li>
  <li class="">some text</li>
</ul>

Any ideas on the matter? Is this even possible with SASS?

I thought of doing something like the following, but it did not work.

ul.text-list {
    li {
        @extend .text;
    }
}

I also thought of doing it via Javascript, but it feels a bit wrong, to be honest.

UPDATE:

Using the insight given in the answer given by Charles Lavalard, I have arrived to a solution that although it solves the repetition in the HTML, it introduces some more in the SCSS. I consider it useful enough though.

This was my text class:

.text {
    font-weight: $font-weight-normal;
    line-height: $line-height-medium;
    color: $grey-500;

    // Font weight
    &.t-light {
        font-weight: $font-weight-light;
    }
    &.t-semibold {
        font-weight: $font-weight-semibold;
    }
    &.t-bold {
        font-weight: $font-weight-bold;
    }
}

And this is the new class created that achieves what I wanted:

.text-children {
    & > * {
        @extend .text;
    }

    &.tc-light > * {
        @extend .t-light;
    }
    &.tc-semibold > * {
        @extend .t-semibold;
    }
    &.tc-bold > * {
        @extend .t-bold;
    }
}

I would've liked to avoid some of the repetition in the SCSS but I don't know if it can be much more improved.


Solution

  • You can use Child combinator > (Docs here) to select direct children of elements matched by the first

    CSS

    .text { 
      color:red; 
    }
    
    ul.text-list {
        &>li {
            @extend .text;
        }
    }
    

    will compile into

    .text, ul.text-list > li {
      color: red;
    }
    

    Exemple:here