Dean James
Dean James

Reputation: 2623

Extending in a media query in Sass and Bootstrap 4

I am updating to the new Bootstrap version 4 which now uses Sass over Less, and my application that uses Bootstrap used the Less files directly rather than the fully compiled css distribution.

But now I've hit a snag - I understand that Sass doesn't allow you to use an @extend within a @media query, but what I don't understand is how I get around the simple problem of overloading a style on a larger screen.

For example, a stripped down version of my Sass looks like:

.box {
  //mobile styles
  background: green;
  
  .logout-button {
    //mobile styles for logout button
    background: red;
  }
}

//everything over 767px
@media (min-width: 768px) {
  .box {
    .logout-button {
      @extend .btn-link; //bring in the Bootstrap button link style here
    }
  }
}

In this example, I want the .logout-button to use the .btn-link style from Bootstrap. But because you can't @extend like this, I'm totally confused as to how to achieve this.

Is there a completely different approach required in Sass compared to Less? Less allows you to do this so I'd be surprised if this was a limitation considering Bootstrap's recent switch.

Thanks in advance!

Upvotes: 2

Views: 2915

Answers (1)

Matěj Kříž
Matěj Kříž

Reputation: 1228

You are right, you can not @extend like this. But you can @include some @mixin.

There is unfortunately no @mixin to create .btn-link variant by default in Bootstrap 4.
If you wanted some other variant, you could use these @mixins which are part of Bootstrap 4:

@include button-variant($background, $border, $active-background: darken($background, 7.5%), $active-border: darken($border, 10%))

or this

@include button-outline-variant($color, $color-hover: #fff)

(Useful list of Boostrap 4 mixins)

But if you need .btn-link you have to make your own @mixin. Something like this (it's copy/paste style of .btn-link in to new mixin):

//
// Link buttons
//
// Make a button look and behave like a link
@mixin btn-link() {

    font-weight: $font-weight-normal;
    color: $link-color;
    background-color: transparent;

    @include hover {
        color: $link-hover-color;
        text-decoration: $link-hover-decoration;
        background-color: transparent;
        border-color: transparent;
    }

    &:focus,
    &.focus {
        text-decoration: $link-hover-decoration;
        border-color: transparent;
        box-shadow: none;
    }

    &:disabled,
    &.disabled {
        color: $btn-link-disabled-color;
        pointer-events: none;
    }

    // No need for an active state here

} 

And then you can use it as you wish:

//everything over 767px
@media (min-width: 768px) {
    .box {
        .logout-button {
            @include btn-link;
        }
    }
}

Nice article about this: SCSS - Extending Classes Within Media Queries

Upvotes: 1

Related Questions