Consider the following SASS code. I want to make sure that if the screen is above 1250px
then the margin-top
should be 750px
and then it should change depending on size. However SASS does not allow me to update the variables inside the strings.
// Above 1250px
$pageTemplateMargin:750px;
// Below 1250px
@media screen and (max-width:1250px){
$pageTemplateMargin:550px;
}
// Below 950px
@media screen and (max-width:950px){
$pageTemplateMargin:450px;
}
@media screen and (max-width:850px){
$pageTemplateMargin:150px;
}
@media screen and (max-width:750px){
$pageTemplateMargin:250px;
}
// Render the correct code
.page-template {margin-top:$pageTemplateMargin}
Is there a better way for this, as it does not work and page-template
stays at 750px
.
Thanks
I agree with the accepted answer that it's better to use maps
in this case but I want to point out a couple of things.
Variables can actually be updated inside of media queries. The problem is that a variable defined outside of a block is a global variable while one defined within a block is a local variable. You can let sass treat a variable within a block as a global variable using the !global keyword.
$pageTemplateMargin:750px;
@media screen and (max-width:1250px){
$pageTemplateMargin: 550px !global;
}
.page-template {
margin-top: $pageTemplateMargin //will use 550px instead of 750px
}
Just want to clarify that it is possible albeit it is not appropriate in this use case.
I also suggest using a loop
for your code which will prove helpful especially if you add more screen widths and margin properties so you don't need to further write more media queries.
$breakpoints: (
1200px: 10px,
1000px: 15px,
800px: 20px,
);
@each $width, $margin in $breakpoints {
@media screen and (max-width: $width) {
.element {
margin-top: $margin;
}
}
}
Hope this helps.
No, you can't (in this situation, as pointed out in the other answer).
I'd suggest using mixins
to work with this:
@mixin pageTemplateMargin($px) {
margin-top: $px
}
@media screen and (max-width:1250px) {
.element { @include pageTemplateMargin(10px);}
}
@media screen and (max-width:1000px) {
.element { @include pageTemplateMargin(15px);}
}
@media screen and (max-width:800px) {
.element { @include pageTemplateMargin(20px);}
}
There's also a way of mapping through sass objects, such as:
$breakpoints: (
1200: 10px,
1000: 15px,
800: 20px,
);
@media screen and (max-width:1200px) {
.element { margin-top: map-get($breakpoints, 1200);}
}
@media screen and (max-width:1000px) {
.element { margin-top: map-get($breakpoints, 1000);}
}
@media screen and (max-width:800px) {
.element { margin-top: map-get($breakpoints, 800);}
}
This would allow you to globally change the margin by adjusting 1 variable.
Working codepen example
I have tried this then i fixed my issue. It will calculate all media-breakpoint automatically by given rate (base-size/rate-size)
$base-size: 16;
$rate-size-xl: 24;
// set default size for all cases;
:root {
--size: #{$base-size};
}
// if it's smaller then LG it will set size rate to 16/16;
// example: if size set to 14px, it will be 14px * 16 / 16 = 14px
@include media-breakpoint-down(lg) {
:root {
--size: #{$base-size};
}
}
// if it is bigger then XL it will set size rate to 24/16;
// example: if size set to 14px, it will be 14px * 24 / 16 = 21px
@include media-breakpoint-up(xl) {
:root {
--size: #{$rate-size-xl};
}
}
@function size($px) {
@return calc(#{$px} / $base-size * var(--size));
}
div {
font-size: size(14px);
width: size(150px);
}