Changing variable value based on media query
Asked Answered
C

6

22

I'd like to use the same variable for different media queries. Something like this:

$avatar_size: 200px;

@media (#{$tablet_size}) {
  $avatar_size: 150px;
}
@media (#{$mobile_size}) {
  $avatar_size: 100px;
}

The objective is to be able to use this variable in multiple places, so I can just reference the variable and not have to throw in the media queries every time. Like so:

.font-awesome-icon {
  font-size: $avatar_size;
}
img {
  width: $avatar_size;
  height: $avatar_size;
}
.img-wrapper {
  height: $avatar_size;
}

Any way to do this?

Chump answered 21/1, 2018 at 21:41 Comment(0)
C
11

This is impossible, variables are assigned values when the Sass is compiled to CSS.

what you can do is this:

$avatar_size: 200px;
$avatar_tablet: 150px;
$avatar_mobile: 100px;

@media (#{$tablet_size}) {
  img {
    width: $avatar_tablet;
    height: $avatar_tablet;
  }
}

@media (#{$mobile_size}) {
  img {
    width: $avatar_mobile;
    height: $avatar_mobile;
  }
}
Calyptrogen answered 21/1, 2018 at 21:49 Comment(1)
It is not correct. You can use scss (Sass) variables as property. See this answerAncy
R
14

Try using CSS custom properties instead of SASS variables.

@media (min-width: 300px) {
  :root {
    --width: 250px;
  }
}

@media (min-width: 600px) {
  :root {
    --width: 450px;
  }
}

svg {
  width: var(--width);
}

This will change the width of a svg element dependent on the screen size.

Just experiment with it using this JSFiddle.

Note: If you want to use CSS custom properties with SASS expressions, you have to wrap them in #{}. Read more about CSS custom property support in SASS.

@media (min-width: 300px) {
  :root {
    --width: #{$small-width};
  }
}

@media (min-width: 600px) {
  :root {
    --width: #{$wide-width};
  }
}

svg {
  width: var(--width);
}
Rotz answered 8/1, 2021 at 18:5 Comment(1)
var > $ 👌🏻 Works nicely, I wonder if there’s any objection to using it in implementing responsiveness.Capps
C
11

This is impossible, variables are assigned values when the Sass is compiled to CSS.

what you can do is this:

$avatar_size: 200px;
$avatar_tablet: 150px;
$avatar_mobile: 100px;

@media (#{$tablet_size}) {
  img {
    width: $avatar_tablet;
    height: $avatar_tablet;
  }
}

@media (#{$mobile_size}) {
  img {
    width: $avatar_mobile;
    height: $avatar_mobile;
  }
}
Calyptrogen answered 21/1, 2018 at 21:49 Comment(1)
It is not correct. You can use scss (Sass) variables as property. See this answerAncy
C
6

If the sizes are fixed like that, you can create a mixin where the property value is the input:

@mixin avatar_size($prop) {
  #{$prop}: 200px;
  @media (#{$tablet_size}) {
    #{$prop}: 150px;
  }
  @media (#{$mobile_size}) {
    #{$prop}: 100px;
  }
}

.font-awesome-icon {
  @include avatar_size('font-size');
}
img {
  @include avatar_size('width');
  @include avatar_size('height');
}
.img-wrapper {
  @include avatar_size('height');
}

I'm guessing you're not really going to use the same value for font-size as for width/height, but since you showed that like that in your question, my answer shows that as well.

Croquet answered 22/1, 2018 at 14:45 Comment(0)
A
1

Try to use utility class, instead of using variables.

.avatar-size {
  @media (your-breakpoint) { width: width-depends-your-situation }
}
Arrival answered 11/11, 2022 at 17:13 Comment(0)
O
0

CSS variables (and SASS variables) cannot be assigned as properties, only values.

The whole point of setting up a variable is to be able to modify the variable and have the changes reflected in multiple places. Considering the variable is designed to change, it makes no sense to give it different values in different scenarios (such as media queries). In such, a situation, you would be looking to define multiple variables.

In terms of SASS, you need to define the standard CSS property, and then your custom variable (which gets used as the value):

$colour: red;

.a {
  color: $colour;
}

.b {
  background-color: $colour;
}

This will evaluate to:

.a {
  color: red;
}

.b {
  background-color: red;
}

This can be seen working in this JSFiddle.

Note that this can also be achieved with raw CSS. This is done with CSS variables, which are denoted with a double hyphen prefix in the :root selector:

:root {
  --colour: red;
}

.a {
  color: var(--colour);
}

.b {
  background-color: var(--colour);
}
<div class="a">One</div>
<div class="b">Two</div>

Hope this helps :)

Oast answered 21/1, 2018 at 21:52 Comment(2)
How does this relate to the question?Alteration
@Sam -- By providing an answer to it? If you disagree, feel free to add your own answer. I love how people like you are so quick to criticise, yet rarely seem to offer an alternative solution to the "wrong" answer.Oast
P
0

In case of using postcss try this: https://github.com/postcss/postcss-custom-media

@custom-media --small-viewport (max-width: 30em);

@media (--small-viewport) {
  /* styles for small viewport */
}

/* becomes */

@media (max-width: 30em) {
  /* styles for small viewport */
}
Patency answered 25/3, 2020 at 11:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.