Skip to content

Allow @extend across media queries #1050

@Snugug

Description

@Snugug

Edit: The current plan here is to allow @extend across media queries by duplicating the queries the current @extend is in and unifying them with any media queries the extendee is in. For example:

.a {w: x}
@media (min-width: 500px) {
  .b {@extend .a}
  .c {y: z}
}

would produce

.a {w: x}
@media (min-width: 500px) {
  .b {w: x}
}

@media (min-width: 500px) {
  .c {y: z}
}

and

@media screen {
  .a {w: x}
}

@media (min-width: 500px) {
  .b {@extend .a}
  .c {y: z}
}

would produce

@media screen {
  .a {w: x}
}
@media screen and (min-width: 500px) {
  .b {w: x}
}

@media (min-width: 500px) {
  .c {y: z}
}

Original issue follows:


As originally brought up in #456, one way to allow extending across media queries would be to have a flag for @extend to explicitly tell Sass that you're OK with creating a duplicate context in a similar fashion to how the !optional flag currently works.

The syntax as currently proposed would look/work something like the following:

%full {
  width: 100%;
  float: left;
  clear: both;
}

%half {
  width: 50%;
  float: left;
}

.sidebar-1 {
  @extend %full;
  background: blue;
  @media (min-width: 500px) {
    @extend %half !duplicate; // A new extend context will be created here for the all, min-width: 500px media context and extension will work as normal.
    background: red;
  }
}

.sidebar-2 {
  @extend %full;
  background: green;
  @media (min-width: 500px) {
    @extend %half !duplicate; // Because a context for this exact media query already exists, it will extend that one instead of creating a duplicate context
    background: orange;
  }
}

.content {
  @extend %half;
  background: purple;
}

would compile to

.sidebar-1, .sidebar-2 {
  width: 100%;
  float: left;
  clear: both;
}

.content {
  width: 50%;
  float: left;
}

.sidebar-1 {
  background: blue;
}

@media (min-width: 500px) {
  .sidebar-1, .sidebar-2 {
    width: 50%;
    float: left;
  }

  .sidebar-1 {
    background: red;
  }
}

.sidebar-2 {
  background: green;
}

@media (min-width: 500px) {
  .sidebar-2 {
    background: orange;
  }
}

.content {
  background: purple;
}

Of course the optimization around this would be difficult, needing to ensure that the matching only happens for identical @media contexts (but include ones in or chains) and a decision would need to be made as to if the selectors should be moved to the first or last item as the normal @extend pattern of "all" doesn't quite make sense here, but because it is an explicit call, a user will understand that they're changing how it works.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestplannedWe would like to add this feature at some point

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions