Keming
Keming

Reputation: 253

How to overwrite Referencing Parent Selector using Mixin in SCSS

I had a common used component and its scss is like this:

.component {
    margin-right: 12px;

    &.specified-use-case {
        margin-right: 30px;

        &:nth-child(odd) {
            margin-right: 70px
        }
    }
}

Now I want everything has same style in mobile view

.component {
    margin-right: 12px;

    // some predefined mixin
    @include viewport(mobile) {
        margin-right: 0px;
        margin-bottom: 14px;
    }

    &.specified-use-case {
        margin-right: 30px;

        &:nth-child(odd) {
            margin-right: 70px
        }
    }
}

But this can't change style for "specified-use-case" in mobile view. In order to do it I have to

.component {
    margin-right: 12px;

    // some predefined mixin
    @include viewport(mobile) {
        margin-right: 0px;
        margin-bottom: 14px;
    }

    &.specified-use-case {
        margin-right: 30px;

        @include viewport(mobile) {
            margin-right: 0px;
            margin-bottom: 14px;
        }

        &:nth-child(odd) {
            margin-right: 70px

            @include viewport(mobile) {
                margin-right: 0px;
                margin-bottom: 14px;
            }
        }
    }
}

Which just doesn't seem right to me. Is there a better way to define mobile view css just for once?

Upvotes: 3

Views: 596

Answers (3)

kunambi
kunambi

Reputation: 772

According to CSS' specificity rules (try this calculator) you unfortunately need to repeat yourself. What your SCSS interpreter does is just compiling what you've written to standard CSS, which will look something akin to:

.component {
 margin-right:12px
}
@media (max-width:768px) {
 .component {
  margin-right:0px;
  margin-bottom:14px
 }
}
.component.specified-use-case {
 margin-right:30px
}
@media (max-width:768px) {
 .component.specified-use-case {
  margin-right:0px;
  margin-bottom:14px
 }
}
.component.specified-use-case:nth-child(odd) {
 margin-right:70px
}
@media (max-width:768px) {
 .component.specified-use-case:nth-child(odd) {
  margin-right:0px;
  margin-bottom:14px
 }
}

As you can see, you're overriding each class with a @media ruleset just after it has been declared. And since I'm a big proponent to never use !important (because you'll open a pandoras box), the only way you can shorten your SCSS is doing:

.component {
    margin-right: 12px;

    // some predefined mixin
    @include viewport(mobile) {
        margin-right: 0px;
        margin-bottom: 14px;  // only need to define margin-bottom once, here.
    }

    &.specified-use-case {
        margin-right: 30px;

        @include viewport(mobile) {
            margin-right: 0px;
            //margin-bottom: 14px;, remove this
        }

        &:nth-child(odd) {
            margin-right: 70px

            @include viewport(mobile) {
                margin-right: 0px;
                //margin-bottom: 14px;, remove this
            }
        }
    }
}

Hope this helps!

Upvotes: 2

Who Me Dunno Mate
Who Me Dunno Mate

Reputation: 540

seems like sass is wrong because you specify margins above a breakpoint, try this:

.component {
    margin-right: 12px;

&.specified-use-case {
    margin-right: 30px;

    &:nth-child(odd) {
        margin-right: 70px
    }
  }
 // some predefined mixin
@include viewport(mobile) {
    margin-right: 0px;
    margin-bottom: 14px;
}
}

Upvotes: 1

musicnothing
musicnothing

Reputation: 3985

You can put the rules inside of the media query:

@include viewport(mobile) {
    margin-right: 0px;
    margin-bottom: 14px;

    &.specified-use-case {
        margin-right: 0px;
        margin-bottom: 14px;
    }
}

Upvotes: 1

Related Questions