ChatGPT解决这个技术问题 Extra ChatGPT

Sass .scss: Nesting and multiple classes?

I'm using Sass (.scss) for my current project.

Following example:

HTML

<div class="container desc">
    <div class="hello">
        Hello World
    </div>
</div>

SCSS

.container {
    background:red;
    color:white;

    .hello {
        padding-left:50px;
    }
}

This works great.

Can I handle multiple classes while using nested styles.

In the sample above I'm talking about this:

CSS

.container.desc {
    background:blue;
}

In this case all div.container would normally be red but div.container.desc would be blue.

How can I nest this inside container with Sass?

You should use a double class selector. This problem is a perfect example of nesting option in Sass. You can read all about that here kolosek.com/nesting-in-less-and-sass

C
Christoph

You can use the parent selector reference &, it will be replaced by the parent selector after compilation:

For your example:

.container {
    background:red;
    &.desc{
       background:blue;
    }
}

/* compiles to: */
.container {
    background: red;
}
.container.desc {
    background: blue;
}

The & will completely resolve, so if your parent selector is nested itself, the nesting will be resolved before replacing the &.

This notation is most often used to write pseudo-elements and -classes:

.element{
    &:hover{ ... }
    &:nth-child(1){ ... }
}

However, you can place the & at virtually any position you like*, so the following is possible too:

.container {
    background:red;
    #id &{
       background:blue;
    }
}

/* compiles to: */
.container {
    background: red;
}
#id .container {
    background: blue;
}

However be aware, that this somehow breaks your nesting structure and thus may increase the effort of finding a specific rule in your stylesheet.

*: No other characters than whitespaces are allowed in front of the &. So you cannot do a direct concatenation of selector+& - #id& would throw an error.


Just a side note, a common use of & is when using pseudo-elements and pseudo-classes. For example: &:hover.
@crush For completeness' sake I added this to my answer. Thank you for the comment.
Thanks. I thought I was being stupid as it isn't mentioned in the basics guide! BTW the docs has moved URL to: sass-lang.com/documentation/…
If & is used at the end of a line, it puts that line at the beginning of the rest of the classes at all the other levels. You can combine elements by doing &.desc under .container, which would append .desc to it, resulting in .container.desc
@MarcelLange That looks like an error to me. :: is used for pseude elements. hover however is pseudo-class and thus only addressed with a single colon.
M
Murdock Helscream

If that is the case, I think you need to use a better way of creating a class name or a class name convention. For example, like you said you want the .container class to have different color according to a specific usage or appearance. You can do this:

SCSS

.container {
  background: red;

  &--desc {
    background: blue;
  }

  // or you can do a more specific name
  &--blue {
    background: blue;
  }

  &--red {
    background: red;
  }
}

CSS

.container {
  background: red;
}

.container--desc {
  background: blue;
}

.container--blue {
  background: blue;
}

.container--red {
  background: red;
}

The code above is based on BEM Methodology in class naming conventions. You can check this link: BEM — Block Element Modifier Methodology


notice this sounds nice, but should be avoided at all costs. you will thank me in the future when you'll try to search your project for .container--desc and end up with no results.
e
engineersmnky

Christoph's answer is perfect. Sometimes however you may want to go more classes up than one. In this case you could try the @at-root and #{} css features which would enable two root classes to sit next to each other using &.

This wouldn't work (due to the nothing before & rule):

container {
    background:red;
    color:white;
    
    .desc& {
      background: blue;
    }

    .hello {
        padding-left:50px;
    }
}

But this would (using @at-root plus #{&}):

container {
    background:red;
    color:white;
    
    @at-root .desc#{&} {
      background: blue;
    }

    .hello {
        padding-left:50px;
    }
}

P
Pavel Levin

Use &

SCSS

.container {
    background:red;
    color:white;

    &.hello {
        padding-left:50px;
    }
}

https://sass-lang.com/documentation/style-rules/parent-selector


D
Dmitry S.

In addition to Cristoph's answer, if you want to be more specific in your declaration you can refer to all children of a container class component. This can be done with:

.container {
// ...
  #{&}.hello {
     padding-left: 50px;
  }
}

This compiles to:

.container .container.hello {
   padding-left: 50px;
}

I hope this be helpful to you!


J
Jonathan DS

this worked for me

<div class="container">
  <div class="desc">
    desc
  </div>
  <div class="asc">
    asc
  </div>
</div>

.container{
  &.desc {
    background: blue;
  }
  &.asc {
    background: red;
  }
}