Sass3.4 変更点・追加点を眺めた

[changelog](https://github.com/sass/sass/blob/stable/doc-src/SASS_CHANGELOG.md#340-18-august-2014) 眺めて、あまり実例が思い浮かばないのもあるけど、一通り試してみた。

## parent selector(&) に関して

### unquoteなリストを返却するようになった

3.3 ではエラーになっていたけど以下のようにできる

```scss
.hoge.fuga .hi.ciao, .yo.hey {
  $unquoted-selector: &;
  content: $unquoted-selector;
}
```
```css
.hoge.fuga .hi.ciao, .yo.hey {
  content: .hoge.fuga .hi.ciao, .yo.hey;
}
```

BEMっぽいことも

```scss
$separator: __; 
 
@mixin b($block) {
   .#{$block} {
       @content; 
   }
}
@mixin e($element) {
    @at-root {
      @each $e in & {
        #{$e}#{$separator+$element} {
          @content;
        }
      }
    }
}

.hoge, .huga, .moge {
    background: red;
    @include e(subelement) { 
      background: gray;
    }
}
```

```css
.hoge, .huga, .moge {
  background: red;
}
.hoge__subelement {
  background: gray;
}

.huga__subelement {
  background: gray;
}

.moge__subelement {
  background: gray;
}
```

---

### 該当の親セレクタがない場合 ```null```を返す。

こちらも3.3ではエラーでしたが、可能になりました。

```scss
@mixin does-parent-exist {
  @if & {
    &:hover {
      color: red;
    }
  } @else {
    a {
      color: red;
    }
  }
}
/* parent exist */
a > .parent-exist {
  @include does-parent-exist;
}
 /* parent not exist */
a.parent-not-exist {
  @include does-parent-exist;
}
```

```css
a > .parent-exist:hover {
  color: red;
}

/* parent not exist */
a.parent-not-exist:hover {
  color: red;
}
```

---

## 追加されたselector function

### selector-nest($selectors...)

selectorをネストさせる

```scss
@mixin nested-context($nested) {
  @at-root #{selector-nest(&, $nested)} {
    @content;
  }
}

.header, .footer {
  .nav a {
    @include nested-context('.text') {
      color: red;
    }
  }
}
```

```css
.header .nav a .text,
.footer .nav a .text {
  color: red;
}
```

---

### selector-append($selectors...)

$selecorsのリスト順に追加していく

```scss
@mixin append-context($context) {
  @at-root {
    #{selector-append(&, $context)} {
      @content;
    }
  }
}

.foo, .bar {
  color: blue;
  @include append-context(':hover') {
    color: red;
  }
}
```

```css
.foo, .bar {
  color: blue;
}
.foo:hover, .bar:hover {
  color: red;
}

```

また単純に

```scss
#{selector-append('.a', '.b', '.c', '.d')} {
  content: '.a.b.c.d';
}
```

とすると順番に追加するだけなので

```css
.a.b.c.d {
  content: '.a.b.c.d';
}
```

となる。

---

### selector-extend($selectors, $extendee, $extender)

- $selectors selectorリスト
- $extendee extendされるselector
- $extender extendするselector

```scss
@mixin extend-context($extendee, $extender) {
  @at-root {
    #{selector-extend(&,$extendee, $extender)} {
      @content;
    }
  }
}

.contet {
  .holder {
    .show {
      color: green;
      @include extend-context('.show', '.edit .content-area') {
        background-color: black;
      }
    }
  }
}
```

とかとすると、

```css
.contet .holder .show {
  color: green;
}
.contet .holder .show,
.contet .holder .edit .content-area,
.edit .contet .holder .content-area {
  background-color: black;
}
```

となり。```.show```を継承もととして、```.edit .content-area```が追加されたセレクターが返却されるっぽい感じなのがわかる。

---

### selector-replace($selector, $original, $replacement)

これはそのまま、$selectorの$originalを$replacementに置換。

```scss
@mixin replace-context($original, $replace) {
  @at-root {
    #{selector-replace(&, $original, $replace)} {
      @content;
    }
  }
}

.header{
  .nav .blank {
    color: green;
    @include replace-context('.header', '.footer') {
      color: red;
    }
  }
}
```

この場合は、```.header```を```.footer```に置換するので

```css
.header .nav .blank {
  color: green;
}
.footer .nav .blank {
  color: red;
}
```

---

### selector-unify($selector1, $selector2)

二つのセレクターの組み合わせたセレクターを返す

selctor1とselector2からできる組み合わせをすべて返すので例えば

```scss
@mixin unify-context($selector) {
  @at-root {
    #{selector-unify(&, $selector)} {
      @content;
    }
  }
}

.note {
  input, textarea{
    color: black;
    @include unify-context('.error') {
      color: red;
    }
  }
}
```

などとすると

```css
.note input,
.note textarea {
  color: black;
}
.note input.error,
.note textarea.error {
  color: red;
}
```

と、全パターンを返してくれる。パターン生成が楽になりそう。

---

### is-superselector($super, $sub)

```$super``` が ```$sub``` の親要素かどうかを返してくれる


```scss
$selectors: '.complete' '.error' '.done';
@each $selector in $selectors {
  body#{$selector} {
    @if is-superselector(".error", &) {
      color: red;
    }
    @else {
      color: gray;
    }
  }
}
```

```css
body.complete {
  color: gray;
}

body.error {
  color: red;
}

body.done {
  color: gray;
}
```

という具合にできるっぽい。これまでより柔軟に分岐できそう。


---

### selector-parse($selector)

string型の変数から簡単にcssを生成できる。

```scss
@mixin parse-context($selector, $nth: false) {
  @at-root {
    @if $nth != false {
      #{& nth(selector-parse($selector), $nth)} {
        @content;
      }
    }
    @else {
      #{& selector-parse($selector)} {
        @content;
      }
    }
  }
}

```

```css
body .foo .bar .baz, .hoge .moge {
  color: brown;
}

.content .hoge .moge {
  color: gray;
}
```

---

うまい実用例が思い浮かばなかったけど、とりあえず。