An Efficient Way of Creating Viewport-Specific CSS classes using SASS/SCSS
Tags: css
Published: 2020-02-03 06:51:07

After building the initial version of First Circle Design System, I’ve noticed that some visual properties or classes only makes sense on a specific viewport.

Since our web app is responsive, currently divided on 2 viewport sizes, mobile-to-tablet `(max-width:767px;)` then tablet-to-infinity `(min-width:768px;)`. I have to make some classes that will render specific properties on specific either mobile only or from tablet view onwards.

You may ask, why not specify these kind of adjustments on css, that what media queries are for right?

Yes and I did that. Like how `flex-direction: column;` should be applied on containers by default for on mobile view to stack everything within that container and `flex-direction: row;` for desktop view to create columns.

However there will be cases that some visual properties is only applicable for a specific use and viewport, and making it a default behavior will make it your code harder to maintain and scale.

I’ll use `<buttons>` as an example. There will be times that rendering them full-width for both mobile and desktop view is okay. I have a specific modifier class for that, adding `--full` or `-—block` will make it full width, but then again, that’s applied for both mobile and desktop view.

What if you only want `--block` class to be applied on mobile view?

You can say that we can do something like this:

```
.--block {
  margin: 0;
  width: 100%;

}
.--block-mobileOnly {
  @include viewpoint-max(mobile){
    margin: 0;
    width: 100%;
  }
}
```

As you can see, the only difference between the two is the enclosure. This is okay, if that’s the only class that needs that modifier, which in our case isn’t.

So I’ve thought of creating a mixin that will accept properties, and create a mobile and desktop specific class without rewriting the same properties.

```
@mixin class-extend { 
  @content    
    &-mobileViewOnly {
    @include viewpoint-max(mobile) {
      @content
    }
  }  &-fromTabletView {
    @include viewpoint-min(tablet) {
      @content
    }
  }
}
```

If you’re not yet familiar with what `@content` is, it just take all declared properties within the mixin curly braces.

Now, going back to my example above, If I use this mixin within a class, I only have to declare properties once to create 3 classes that will do the same thing only added viewport specificity.

```
.--block {
  @include class-extend {
    margin: 0;
    width: 100%;
  }
}
```

once compiled, it will render into this css:

```
.--block {
  margin:0;
  width: 100%;
}

@media (max-width: 767px) {
  .--block-mobileViewOnly {
    margin:0;
    width: 100%;
  }
}

@media (min-width: 768px {
  .--block-fromTabletView {
    margin:0;
    width: 100%
  }
}
```

With this approach, it will be easier to update, scale and maintain your code.

There are a lot of things that you can do with mixins, one of these things is to stop repeating yourself / DRY.

I was able to use mixins to set dynamic padding, margin, font-sizes even colors which changes base on the screen size.

Yes, again you can do it thru media queries, but if you want these properties to be consistent, that also means that you have to update all similar properties declared, instead of having to update just one.

How about you? Do you have other mixin recipes that you would like to share? Would love to hear your thoughts and I really hope that you’ll find this helpful and powerful as well!

Thank you for reading!