Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use the ampersand in SASS to reference specific tags with the parent class? [duplicate]

Tags:

sass

I have a class semantic which I apply to many different elements. Depending on which html tag the class is applied to, I would like it to apply a different style. This is how I tried to do it:

.semantic {
    &ul {
        padding: 0;
        margin: 0;
    }
    &p {
        margin: 0;
    }
}

This doesn't work. Of course I could write it like this, but it wouldn't be very "DRY":

 .semantic ul {
    padding: 0;
    margin: 0;
 }

 .semantic p {
     margin: 0;
 }

Is this possible?

Edit: For clarification, here is an example of what my HTML looks like:

<ul class='semantic'>
    <li>An Item</li>
</ul>

<p class='semantic'>This text is semantically a paragraph, but should not be displayed as such</p>
like image 596
Jordan Eldredge Avatar asked Apr 03 '13 19:04

Jordan Eldredge


People also ask

What does ampersand mean in Sass?

In Sass, the ampersand (&) symbol is used to reference the parent selector in a nested rule.

Which symbol is used to refer parent selector in Sass?

Sass lets you reference the parent selector of a nested rule using the ampersand (&) symbol –– it's one of Sass' most useful features!

What is the use of & in SCSS?

The & is a special selector invented by SCSS which is used in nested selectors to refer to the outer selector . It simply means that it will be replaced with the outer selector when compiling to CSS.

How do you target a parent element in Sass?

sass Nesting The parent selector (&)Create a new selector that requires both the parent selector and another on the same element by placing the new selector directly after a parent selector. Have the parent appear after a nested selector in the compiled CSS by placing the parent selector after the nested selector.


2 Answers

On Sass 3.4:

.semantic {
    @at-root {
      ul#{&} {
        padding: 0;
        margin: 0;
      }
      p#{&} {
        margin: 0;
      }
    }
}

Generates:

ul.semantic {
  padding: 0;
  margin: 0;
}

p.semantic {
  margin: 0;
}

@at-root moves the block to the top-level. This has several uses (see link) but here it's being used to keep take advantage of the & syntax without implying that the rules are child selectors of .semantic.

like image 118
jruz Avatar answered Oct 24 '22 09:10

jruz


What you're wanting for would in theory look like this:

.semantic {
    ul& {
        padding: 0;
        margin: 0;
    }
    p& {
        margin: 0;
    }
}

This is not possible because the & must be first. You're just going to have to deal with the fact that it isn't DRY and write it out by hand:

ul.semantic {
    padding: 0;
    margin: 0;
}

p.semantic {
    margin: 0;
}

As of Sass 3.3 or 3.4, it is possible using this syntax:

.semantic {
    ul#{&} {
        padding: 0;
        margin: 0;
    }
    p#{&} {
        margin: 0;
    }
}
like image 31
cimmanon Avatar answered Oct 24 '22 10:10

cimmanon