Sass extend with pseudo selectors

14,470

Solution 1

When you want to extend a pseudo class or pseudo element, you just want to extend the parent selector (ie. everything that comes before the colon).

%foo:before {
  color: red;
}

.bar {
  @extend %foo;
}

Generates:

.bar:before {
  color: red;
}

So for your instance, what you want to do is this:

.icon-ab-logo, {
    font: 100%/1 'icomoon'; // use the shorthand
    speak: none;
    text-transform: none;
    -webkit-font-smoothing: antialiased;
}

%foo:before, .icon-ab-logo:before { //i want to reuse this.
    content: "\e000";
}

@mixin icon( $icon ){
    font: 100%/1 'icomoon'; // use the shorthand
    speak: none;
    text-transform: none;
    -webkit-font-smoothing: antialiased;
    @extend #{$icon};
}

.bar {
    @include icon('%foo');
}

Be aware that your mixin generates a lot of styles, so it's not really suitable for extensive reuse. It would make a lot more sense to be extending that as well.

Solution 2

Seems like SASS doesn't work so well with pseudo elements in extends.

Work around the issue like this:

%before-icon
  color: red

.foo
  /* Some styles here */

  &:before
    @extend %before-icon

Result:

.foo:before {
  color: red;
}

.foo {
  /* Some styles here */
}

Also, it looks like you're overcomplicating things. You'll find your code difficult to grasp and maintain.

PS You should keep mixins in _mixins.scss.

Share:
14,470
Simon
Author by

Simon

Updated on June 18, 2022

Comments

  • Simon
    Simon almost 2 years

    I am using compass to manage some sass files on mac osx. I have these files:

    sass/
          screen.scss
                partials folder/
          ...
                _fonts.scss
                _functions.scss
          ...
    

    In fonts I have this rule which I would like to reuse @extend.

    //fonts.scss
    .icon-ab-logo, {
    font-family: 'icomoon';
    speak: none;
    font-style: normal;
    font-weight: normal;
    font-variant: normal;
    text-transform: none;
    line-height: 1;
    -webkit-font-smoothing: antialiased;
    }
    .icon-ab-logo:before { //i want to reuse this.
    content: "\e000";
    }
    

    In functions I have this screen.scss:

    .logo {
    position: absolute;
    top: 0;
    bottom: 0px;
    z-index: 500;
    width: 9.5em;
    background: $logo;
    @include transition(all 0.2s);
       &:after{
         @include icon( ".icon-ab-logo" );
       }
     }
    

    Finally in functions.scss I call this:

        @mixin icon( $icon ){
          font-family: 'icomoon';
          speak: none;
          font-style: normal;
          font-weight: normal;
          font-variant: normal;
          text-transform: none;
          line-height: 1;
          -webkit-font-smoothing: antialiased;
          @extend #{$icon}:before; //<- this is the problem, no errors just isn't parsed.
        }
    

    Is there a way to reference .icon-ab-logo:before using a mixin? Workarounds? Thanks for reading.