Skip to content

Issue with rulesets and scope #2156

@Rayraz

Description

@Rayraz

I ran into what seems to be a bug with scoping and passing around detached rulesets. I've tried to narrow the problem down to it's essentials. Lets say we start off with setting and calculating a few variables:

@mobile:  ~"only screen and (max-width: 639px)";
@desktop: ~"only screen and (min-width: 640px)";

.mobile-vars() {
    @font-size: 16px;
    @button-height: 24px;
}
.desktop-vars() {
    @font-size: 14px;
    @button-height: 30px;
}
.button-vars(@responsive-vars) {
    @responsive-vars();
    @padding-lr: @font-size;
    @padding-tb: (@button-height - @font-size) / 2;
}

Now I'd like to generate some mobile styles and alter them for use on desktop computers:

.mobile-vars();
.button-vars({
    .mobile-vars()
});
.button {
    font-size: @font-size;
    height: @button-height;
    padding: @padding-tb @padding-lr;
}
@media @desktop {
    .desktop-vars();
    .button-vars({
        .desktop-vars()
    });
    .button {
        font-size: @font-size;
        height: @button-height;
        padding: @padding-tb @padding-lr;
    }
}

This less code compiles to the following:

.button {
  font-size: 16px;
  height: 24px;
  padding: 4px 16px;
}
@media only screen and (min-width: 640px) {
  .button {
    font-size: 14px;
    height: 30px;
    padding: 4px 16px;
  }
}

As you can see, the padding on the button has not changed for desktop styles, despite explicitly passing the desktop variables into the .button-vars() mixin.

However, if I change my less code such that the original mobile styles are scoped within a media query, everything works as expected:

@media @mobile {
    .mobile();
    .button {
        font-size: @font-size;
        height: @button-height;
        padding: @padding-tb @padding-lr;
    }
}
@media @desktop {
    .desktop();
    .button {
        font-size: @font-size;
        height: @button-height;
        padding: @padding-tb @padding-lr;
    }
}

Compiles to:

@media only screen and (max-width: 639px) {
  .button {
    font-size: 16px;
    height: 24px;
    padding: 4px 16px;
  }
}
@media only screen and (min-width: 640px) {
  .button {
    font-size: 14px;
    height: 30px;
    padding: 8px 14px;
  }
}

Same goes for using an empty parent selector:

& {
    .mobile();
    .button {
        font-size: @font-size;
        height: @button-height;
        padding: @padding-tb @padding-lr;
    }
}
@media @desktop {
    .desktop();
    .button {
        font-size: @font-size;
        height: @button-height;
        padding: @padding-tb @padding-lr;
    }
}

Compiles to:

.button {
  font-size: 16px;
  height: 24px;
  padding: 4px 16px;
}
@media only screen and (min-width: 640px) {
  .button {
    font-size: 14px;
    height: 30px;
    padding: 8px 14px;
  }
}

I'm experiening these errors using: lessc 1.7.4 (Less Compiler) [JavaScript]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions