469

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?

Jordi Castilla
  • 26,609
  • 8
  • 70
  • 109
matt
  • 42,713
  • 103
  • 264
  • 397
  • 1
    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 https://kolosek.com/nesting-in-less-and-sass – Nesha Zoric Feb 21 '18 at 08:18

6 Answers6

775

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.

Christoph
  • 50,121
  • 21
  • 99
  • 128
  • 20
    Just a side note, a common use of `&` is when using pseudo-elements and pseudo-classes. For example: `&:hover`. – crush Dec 01 '14 at 18:30
  • 2
    @crush For completeness' sake I added this to my answer. Thank you for the comment. – Christoph Dec 01 '14 at 22:34
  • 2
    Thanks. I thought I was being stupid as it isn't mentioned in the basics guide! BTW the docs has moved URL to: http://sass-lang.com/documentation/file.SASS_REFERENCE.html#parent-selector – scipilot Aug 01 '15 at 06:51
  • 2
    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` – Kate Miller Aug 23 '16 at 21:41
  • scss-lint suggests to use "&::hover" (double colones) – Marcel Lange Nov 09 '18 at 12:58
  • 1
    @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. – Christoph Nov 13 '18 at 21:13
  • 1
    and use in html : `
    ...
    `
    – Azade Apr 14 '21 at 20:54
32

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

matuselah
  • 371
  • 3
  • 4
  • 6
    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. – Stavm Dec 19 '19 at 13:03
4

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;
    }
}
engineersmnky
  • 25,495
  • 2
  • 36
  • 52
3

Use &

SCSS

.container {
    background:red;
    color:white;

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

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

Pavel Levin
  • 646
  • 8
  • 7
2

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!

Dmitry S.
  • 1,544
  • 2
  • 13
  • 22
0

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;
  }
}
Jonathan DS
  • 2,050
  • 5
  • 25
  • 48