influxweb
8/31/2015 - 7:19 PM

grandparent_mixin.scss

@function up-to($list, $index) {
  $l: ();
  @each $e in $list {
    @if length($l) < $index {
      $l: append($l, $e, list-separator($list));
    }
  }
  @return $l;
}

@function parent($selector: null) {
  $selector: & !default;
  $selector: selector-parse($selector);
  $first-parent-selector: nth($selector, 1);
  @return nth($first-parent-selector, length($first-parent-selector));
}

@function without-parent($selector: null) {
  $selector: & !default;
  $selector: selector-parse($selector);
  $ancestors: ();
  @each $subselectors in $selector {
    $ancestors: append($ancestors, up-to($subselectors, length($subselectors) - 1), comma);
  }
  @debug $ancestors;
  @return $ancestors;
}

@function null-selector($selector) {
  @if not $selector {
    @return true;
  }
  @else if length($selector) > 0 and length(nth($selector, 1)) > 0 {
    @return false;
  }
  @else {
    @return true;
  }
}

@mixin grandparent($grandparents, $context: null) {
  $context: & !default;
  $grandparents: selector-parse($grandparents);
  $ancestors: without-parent($context);
  $selector: if(null-selector($ancestors), $grandparents, selector-nest($ancestors, $grandparents));
  $selector: selector-nest($selector, parent($context));
  @at-root #{$selector} {
    @content;
  }
}

// EXAMPLES

#context {
  .jumbotron {
    @include grandparent(".container, .container-fluid") {
      color: red;
    }
  }
}

.jumbotron {
  @include grandparent(".container, .container-fluid") {
    color: red;
  }
}

// Outputs:
// #context .container .jumbotron, #context .container-fluid .jumbotron {
//   color: red; }
// 
// .container .jumbotron, .container-fluid .jumbotron {
//   color: red; }