SCSS declaring Mixins with breakpoints

76 views Asked by At

Is it possible to use SCSS to write Mixins that also change properties based on media queries. Take this that changes the font-size and line-height based on breakpoint declaration map. Is this possible?

$breakpoints: (
  min: 312px,
  mid: 680px,
  max: 1020px,
);

@mixin fontsize($size) {
  @if ($size == "xsmall") {
    font-size: 13px;
    line-height: 18px;
    @media only screen and (min-width: map-get($breakpoints, "mid")) {
      font-size: 15px;
      line-height: 20px;
    }
    @media only screen and (min-width: map-get($breakpoints, "max")) {
      font-size: 18px;
      line-height: 26px;
    }
  }
}

p {
  @include fontsize("xsmall");
  margin: 1em 0;
}

This should mean that a paragraph has a variable font size and line height. But before refactoring vast quantities of css variables I wanted to know if this would actually work?

From what I can see it does work but in terms of correct syntax and browser compatibility is this approach correct?

https://codepen.io/Walrus117/pen/RwdKmoX

1

There are 1 answers

1
Martin On

Your approach is totally fine.

Taking the web projects I have participated in as my sample, I conclude that wrapping @media queries in specialized @mixins is a well established approach to UI responsiveness in web apps utilizing SASS / SCSS.

SASS handles the nesting when compiling it and produces syntactically valid CSS. You can see what it outputs by pasting your snippet into https://www.sassmeister.com/:

p {
  font-size: 13px;
  line-height: 18px;
  margin: 1em 0;
}
@media only screen and (min-width: 680px) {
  p {
    font-size: 15px;
    line-height: 20px;
  }
}
@media only screen and (min-width: 1020px) {
  p {
    font-size: 18px;
    line-height: 26px;
  }
}

Regarding browser compatibility of CSS3 Media Queries: @media is supported by all major browsers caniuse

If you only target browsers that support custom css variables (i.e. all modern browsers, no IE caniuse), you might want to also explore the possibilities of having responsive variables: (Disclaimer: I haven't tried that out yet in any real project. It may well be that this results in a rather inflexible mess)

$mid: 680px;
$max: 1020px;
:root {
  --responsive-font-size-sm: 13px;
  --responsive-line-height-sm: 18px;
  @media only screen and (min-width: $mid) {
    --responsive-font-size-sm: 15px;
    --responsive-line-height-sm: 20px;
  }
  @media only screen and (min-width: $max) {
    --responsive-font-size-sm: 18px;
    --responsive-line-height-sm: 26px;
  }
}

p {
  font-size: var(--responsive-font-size-sm);
  line-height: var(--responsive-line-height-sm);
  margin: 1em 0;
}