Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
426 views
in Technique[技术] by (71.8m points)

sass - Unexpected results when using @extend for themes

I'm refactoring some of my Sass code and I came across a weird issue. My code currently looks like this:

// household
$household_Sector: 'household';
$household_BaseColor: #ffc933;

// sports
$sports_Sector: 'sports';
$sports_BaseColor: #f7633e;


// the mixin to output all sector specific css
@mixin sector-css($sector_Sector,$sector_BaseColor) {

    .sector-#{$sector_Sector} {
        &%baseColor {
            background-color: $sector_BaseColor;
        }
    }

}

// execute the mixin for all sectors
@include sector-css($household_Sector, $household_BaseColor);
@include sector-css($sports_Sector, $sports_BaseColor);


.product-paging {
    h2 {
        @extend %baseColor;
    }
}

DEMO

The compiled result looks like this:

.product-paging h2.sector-household {
  background-color: #ffc933;
}

.product-paging h2.sector-sports {
  background-color: #f7633e;
}

But what I need is this:

.sector-household.product-paging h2 {
  background-color: #ffc933;
}

.sector-sports.product-paging h2 {
  background-color: #f7633e;
}

What I don't understand is why my placeholder (&%baseColor) isn't attached to the parent selector (&%baseColor) as I added the ampersand right in front of it? Is this maybe a bug when combining & and %? Is there another solution on how to achieve what I want?

EDIT

Alright I figured out why this isn't possible. Anyway is there a workaround for what I'd like to achieve?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Extends, as you've already discovered, can get rather messy. I would go about solving your problem by using an @content aware mixin in combination with global variables (this uses mappings, which are part of 3.3... you can do it with lists of lists, but it's a little less elegant):

$base-color: null; // don't touch
$accent-color: null; // don't touch

$sections:
    ( household:
        ( base-color: #ffc933
        , accent-color: white
        )
    , sports:
        ( base-color: #f7633e
        , accent-color: white
        )
    );


// the mixin to output all sector specific css
@mixin sector-css() {
    @each $sector, $colors in $sections {
        $base-color: map-get($colors, base-color) !global;
        $accent-color: map-get($colors, accent-color) !global;
        &.sector-#{$sector} {
            @content;
        }
    }
}

.product-paging {
    @include sector-css() {
        h2 {
            background-color: $base-color;
        }
    }
}

Output:

.product-paging.sector-household h2 {
  background-color: #ffc933;
}

.product-paging.sector-sports h2 {
  background-color: #f7633e;
}

Update: Since you want to guarantee that the sector class is always at the top, you just need to switch around a little.

@mixin sector-css() {
    @each $sector, $colors in $sections {
        $base-color: map-get($colors, base-color) !global;
        $accent-color: map-get($colors, accent-color) !global;
        .sector-#{$sector} {
            @content;
        }
    }
}

@include sector-css() {
    &.product-paging {
        h2 {
            background-color: $base-color;
        }

        h3 {
            background-color: #CCC;
        }

        h2, h3 {
            color: $accent-color;
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...