matt
matt

Reputation: 44393

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?

Upvotes: 485

Views: 530054

Answers (6)

Christoph
Christoph

Reputation: 51241

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.

Upvotes: 806

user2299879
user2299879

Reputation: 41

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;
    }
}

Upvotes: 4

Jon
Jon

Reputation: 2128

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;
  }
}

Upvotes: 0

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!

Upvotes: 3

Pavel Levin
Pavel Levin

Reputation: 746

Use &

SCSS

.container {
    background:red;
    color:white;

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

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

Upvotes: 6

matuselah
matuselah

Reputation: 371

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

Upvotes: 32

Related Questions