This
A function that reliably gets the current scoped selector - similar to Javascript’s usage of this.
Install
npm install seed-this --save
About
The this() function was inspired by the $this/self coding patterns seen in jQuery/Javascript. It’s a simple (and reliable) way to reference your current selector.
An example of the $this variable pattern can be seen in this bit of jQuery code:
example.js$('.menu-items').each(function() {
var $this = $(this);
if ($this.hasClass('old')) {
$this.hide();
}
else {
$this.addClass('active');
}
});
Problem
With native Sass, we have to rely on & to reference the current selector. Although & does reference the current selector, it also references all the selectors that come before it. It also doesn’t allow you to re-use the same selector again in recursive nesting situations (e.g. a .menu within a .menu).
In the following bit of Sass, we’re attemping to keep our code DRY by referencing .menu by using &:
example.scss.nav {
.menu {
background: blue;
& {
margin-left: 10px;
}
}
}
The ideal (and maybe expected) CSS should look like this:
example.css.nav .menu {
background: blue;
}
.nav .menu .menu {
margin-left: 10px;
}
But what we actually get is this:
example.css.nav .menu {
background: blue;
}
.nav .menu {
margin-left: 10px;
}
Workarounds
A common work-aroud to this issue is to variablize & and use the variable as your selector (similar to jQuery’s $this or $self):
example.scss.nav {
.menu {
$this: &;
background: blue;
#{$this} {
margin-left: 10px;
}
}
}
However, this only works if the selector that & is refering to is one level deep. Because .menu is nested under .nav, the compiled CSS results in a doubling of .nav .menu:
example.css.nav .menu {
background: blue; }
.nav .menu .nav .menu {
margin-left: 10px; }
Solution
Using the this() function instead of & will give us the results we want:
example.scss.nav {
.menu {
$this: this(); // Replace & with this()
background: blue;
#{$this} {
margin-left: 10px;
}
}
}
example.css.nav .menu {
background: blue; }
.nav .menu .menu {
margin-left: 10px; }
Usage
this
Reliably gets the most current selector.
this()
Returns: A selector (e.g. .menu)
Example
example.scss.nav {
.menu {
$this: this(); // Replace & with this()
background: blue;
#{$this} {
margin-left: 10px;
}
}
}
example.css.nav .menu {
background: blue; }
.nav .menu .menu {
margin-left: 10px; }