Merging selectors from mixins

2020-01-25 11:34发布

问题:

I'm trying to contain general styles/tricks in a separate mixin file which can be applied to any project when they're needed. Some of these styles require multiple elements to work together in order to work.

For example:

_mixins.scss
====================
@mixin footer_flush_bottom {
    html {
        height: 100%;
    }

    body {
        min-height: 100%;
        position: relative;
    }

    #footer {
        position: absolute;
        bottom: 0;
    }
}

main.scss
====================
@import "mixins";

@include footer_flush_bottom;

html {
    background-color: $bg;
    //More stuff
}

body {
    margin: 0 auto;
    //More stuff
}

footer.scss
====================
#footer {
    height: 40px;
}

As it is, the mixin works but the generated css separates the mixin from the main code, even when their selectors are the same. The downside to this is ugly css and larger file size when I start including more of these.

/* line 14, ../../sass/modules/_mixins.scss */
html {
  height: 100%; }

/* line 18, ../../sass/modules/_mixins.scss */
body {
  min-height: 100%;
  position: relative; }

/* line 22, ../sass/modules/_mixins.scss */
#footer {
  position: absolute;
  bottom: 0; }

/* line 19, ../../sass/modules/main.scss */
html {
  overflow-y: scroll; }

/* line 37, ../../sass/modules/main.scss */
body {
  margin: 0 auto;

/* line 1, ../sass/modules/footer.scss */
#footer {
  height: 40px;

Is there anyway I can do this so that same selectors can be merged? Like this:

/* line 19, ../../sass/modules/main.scss */
html {
  height: 100%;
  overflow-y: scroll; }

/* line 37, ../../sass/modules/main.scss */
body {
  min-height: 100%;
  position: relative;
  margin: 0 auto;

/* line 1, ../sass/modules/footer.scss */
#footer {
  position: absolute;
  bottom: 0;
  height: 40px;}

回答1:

No. Sass has no way of merging selectors (this could be considered undesirable, as it would alter the ordering of the selectors).

The only thing you can really do is something like this (or write 2 separate mixins):

@mixin footer_flush_bottom {
    height: 100%;

    body {
        min-height: 100%;
        position: relative;
        @content;
    }
}

html {
    // additional html styles
    @include footer_flush_bottom {
        // additional body styles
    }
}