DEV Community

subbiah chandru
subbiah chandru

Posted on

SCSS mixins for reusable media query and style scoping

Let’s start with a simple SCSS. In this I will be using BEM modal css naming. Reference (http://getbem.com/naming/)

.as-facts {
  &-header {
    align-items: center;
    display: flex;
    flex-direction: column;

    &-image {
      display: flex;
      height: 200px;
      width: 200px;
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

This SCSS would be converted to below CSS

.as-facts-header {
  align-items: center;
  display: flex;
  flex-direction: column;
}
.as-facts-header-image {
  display: flex;
  height: 200px;
  width: 200px;
}
Enter fullscreen mode Exit fullscreen mode

Now there comes a use case where you need to hide image for mobile and landscapePhone screens. Let’s use untilMediatype mixin

.as-facts {
  &-header {
    align-items: center;
    display: flex;
    flex-direction: column;

    &-image {
      display: flex;
      height: 200px;
      width: 200px;

      @include untilMediaType("landscapePhone") {
        display: none;
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

This would be converted into

.as-facts-header {
  align-items: center;
  display: flex;
  flex-direction: column;
}
.as-facts-header-image {
  display: flex;
  height: 200px;
  width: 200px;
}
@media only screen and (max-width: 576px) {
  .as-facts-header-image {
    display: none;
  }
}
Enter fullscreen mode Exit fullscreen mode

Now .as-facts-header-image will be added to all the element that has the class “as-facts-header-image“. Lets say there is a use case where you need as-facts-header-image to be applied only to elements inside .as-facts. Let’s scope it, using scope mixin.

.as-facts {
  @include scope() {
    &-header {
      align-items: center;
      display: flex;
      flex-direction: column;

      &-image {
        display: flex;
        height: 200px;
        width: 200px;

        @include untilMediaType("landscapePhone") {
          display: none;
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

This would be rendered into

.as-facts .as-facts-header {
  align-items: center;
  display: flex;
  flex-direction: column;
}
.as-facts .as-facts-header-image {
  display: flex;
  height: 200px;
  width: 200px;
}
@media only screen and (max-width: 576px) {
  .as-facts .as-facts-header-image {
    display: none;
  }
}
Enter fullscreen mode Exit fullscreen mode

Now we don’t need to worry about styles getting applied to all components with this mixin @scope it will be scoped to .as-facts.

Now let’s see the reusable mixins.

@use 'sass:map';

$breakpoints: (
  "phone": 320px,
  "landscapePhone": 576px,
  "tablet": 768px,
  "desktop": 992px,
  "largeDesktop": 1200px,
  "xlDesktop": 1400px,
);

@mixin untilMediaType($type) {
  @media only screen and (max-width: map.get($breakpoints, $type)) {
    @content;
  }
}

@mixin scope() {
  & & {
    @content;
  }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)