Access the parent selector from within a SASS mixin

11,016

Solution 1

No, this is not possible. You could do something like this, though:

@mixin button($child: '.child') {
    font-size: 0px;
    //other stuff to make a pretty button

    #{$child} {
        display:inline-block;
        font-size: 1em;
    }
}

.parent{
    @include button();
}

Output:

.parent {
  font-size: 0px;
}
.parent .child {
  display: inline-block;
  font-size: 1em;
}

Solution 2

As of Sass 3.4 this is now possible.

@mixin parent {

  @each $selector in & {

    $l: length($selector);

    @if ($l == 1) {
      @error "Used parent mixin on a top-level selector";
    } @else {

      $parent: nth($selector,1);
      @for $i from 2 to $l {
        $parent: append($parent,nth($selector,$i));
      }

      @at-root #{$parent} {
        @content;
      }

    }
  }
}

// Use
.grandparent {
  .parent{
      .child {
        font-size: 1em;
          @include parent {
            font-size: 0px;
          }
      }
  }
}

// Result
.grandparent .parent .child {
  font-size: 1em;
}
.grandparent .parent {
  font-size: 0px;
}

// Errors:
.root {
  @include parent {
    content: "Won't work";
  }
}
.grandparent .parent, .root {
  @include parent {
    content: "Also won't work";
  }
}

Solution 3

There is a XXX! selector in the draft for the CSS 4 spec, which will act as the way you like. It announces the subject of the CSS style declarations, if the selectors match

So if you have this selector

.a > .b! > .c

It will match e.g. for this

<div class="a">
    <div class="b">
        <div class="c">
        </div>
    </div>
</div>

but the style declarations will not take effect on .c, but on .b, because I announced by the exclamation mark, that this element should be the subject of the style http://dev.w3.org/csswg/selectors4/#subject

You cannot use it right now out of the box. But there is one jQuery plugin, that is a polyfill for that. http://dev.w3.org/csswg/selectors4/

See also this stack: Is there a CSS parent selector?

How to apply? Well, I don't know exactly in SASS, but in LESS it would be

*! > & {
    /* ... */
}
Share:
11,016
MacBryce
Author by

MacBryce

Updated on June 20, 2022

Comments

  • MacBryce
    MacBryce almost 2 years

    I have set up a mixin for a button using display:inline-block. I am trying to get to the parent of whatever class that will eventually end up using the mixim, so I can add the font-size: 0px line there to make sure that I don't need to make adjustments to my HTML to avoid unwanted space between each button.

    Here's an example... I want the. parent class to receive the font-size: 0px line.

    @mixin button() {
        display:inline-block;
        font-size: 1em;
        //other stuff to make a pretty button
        && { font-size: 0px; }
    }
    
    .parent{
        .child {
            @include button();
        }
    }
    
  • MacBryce
    MacBryce about 11 years
    Thanks! Looking forward to CSS4.
  • Marc
    Marc almost 6 years
    Is all of this necessary to get the parent class to have a font size of 1px? If not, would you give a simpler example of just that?