Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Extending a %placeholder containing a parent reference produce incorrect output #1063

Closed
timschoch opened this issue Apr 7, 2015 · 5 comments

Comments

@timschoch
Copy link

Hello
I'm not sure if this problem is new or related to a known one. & Selectors within a placeholder get ignored when the parent selector is generated on the fly. This is a simplyfied version of what we use to generate navigations. (eg. first level horizontally, second megamenu, third vertically, ...)

%submenu {
  &:hover > ul { display: block; }
}

ul.root {
  $nested: unquote( '' );
  @for $level from 1 through 3 {
    @if length( $nested ) > 1 {
      #{$nested} {
        > li { @extend %submenu; } 
      }
    } @else {
      > li { @extend %submenu; }
    }
    $nested: append( $nested, unquote( ' > li > ul' ) );
  }
}

This is what libsass renders

ul.root > li:hover > ul {
  display: block;
}

And in comparission the sass output as I would expect it

ul.root > li:hover > ul,
ul.root > li > ul > li:hover > ul,
ul.root > li > ul > li > ul > li:hover > ul {
  display: block;
}

Interestingly the behaviour changes when we add a class inside the loop

@for $level from 1 through 3 {
  @if length( $nested ) > 1 {
    #{$nested}.level#{$level} { // <- added level specific class
      > li { @extend %submenu; } 
     }
  } @else {
    > li { @extend %submenu; }
  }
   $nested: append( $nested, unquote( ' > li > ul' ) );
}

// renderes as expected
ul.root > li:hover > ul,
ul.root > li > ul.level2 > li:hover > ul,
ul.root > li > ul > li > ul.level3 > li:hover > ul {
  display: block;
}

And it's only the & Selector thats broken. If I add another selector to the placeholder the new one works.

%submenu {
  > a { color: blue; }
  &:hover > ul { display: block; }
}

// > a works
ul.root > li > a,
ul.root > li > ul > li > a,
ul.root > li > ul > li > ul > li > a {
  color: blue;
}
// &:hover doensn't
ul.root > li:hover > ul {
  display: block;
}
@xzyfer
Copy link
Contributor

xzyfer commented Apr 7, 2015

I can confirm this issue is present in Libsass 3.2.0-beta.5

@mgreter
Copy link
Contributor

mgreter commented Apr 7, 2015

You can test for regressions with http://sassmeister.com/ (this one is a plain bug)

@xzyfer
Copy link
Contributor

xzyfer commented Apr 11, 2015

Spec added sass/sass-spec#320

@xzyfer
Copy link
Contributor

xzyfer commented Apr 11, 2015

This appears to be a problem with deduping selectors during extending. This test case can be simplified to

%foo {
  & > x { display: block; }
}

a {
  > b { @extend %foo; }
  > b > c { @extend %foo; }
}

Given this code we appear to be incorrectly deduping a > b and a > b > c down to a > b

@xzyfer xzyfer changed the title & Selector doesn't work inside a placeholder that gets extended in a @for loop Extending a %placeholder containing a parent reference produce incorrect output Apr 11, 2015
@xzyfer xzyfer modified the milestones: 3.2.2, 3.3 May 1, 2015
@franzheidl
Copy link

This issue with the & parent selector appears not only when extending placeholders, it seems to also happen when the parent selector is generated on the fly and using @at-root:

I have this source:

@mixin outer($name) {
    .#{$name} {
        @content;
    }
}

@mixin inner($name) {
    @at-root {
        &#{$name} {
            @content;
        }
    }
}

@include outer('peter') {
    color: red;
    @include inner('paul') {
        color: green;
    }
}

The expected output should be (and what Ruby Sass 3.4.13 gives me):

.peter {
  color: red; 
}
.peterpaul {
   color: green; 
}

But the result is:

.peter {
  color: red; 
}
 paul {
    color: green; 
}

# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

No branches or pull requests

4 participants