Dynamically creating variable names in SCSS - css

I'm trying to dynamically create a variable, but that doesn't seem to be possible in SCSS:
$res-mat-xs: 0;
$res-mat-sm: 600px;
$res-mat-md: 960px;
$res-mat-lg: 1280px;
$res-mat-xl: 1920px;
#mixin media-min($var) {
#media only screen and (min-width: $var) { #content; }
}
#mixin media-max($var) {
#media only screen and (max-width: $var - 1px) { #content; }
}
#mixin media-from-to($var1, $var2) {
#media only screen and (min-width: $var1) and (max-width: $var2 - 1px) { #content; }
}
$media: 'min', 'max', 'from-to';
$variants: 'very-small', 'small', 'default', 'large', 'very-large';
$breakpoints: 'xs', 'sm', 'md', 'lg', 'xl';
#each $breakpoint in $breakpoints {
.typo-style-#{$breakpoint}-#{$variants}-#{$breakpoint} {
#include media-min($res-mat-#{$breakpoint}) {
#include typo-style('default', 'important');
}
}
}
In addition, I am totally overwhelmed with the from-to ($media) and variants.
The class names for the from-to should look like this:
.typo-style-very-small-from-sm-to-md
.typo-style-large-from-sm-to-lg
How can I make these dynamic variables?

Related

can someone tell me what's the problem with this SASS code?

when entering the vale "xs", i get an error saying "(max-width: 575.98px) isn't a valid CSS value."
and when entering any other value i get the following error "This Breackpoint 'sm' isn't supported yet"
is it even possible to apply this idea with SASS ?
Here is my code:
$breakpoints: (
"xs": (max-width: 575.98px),
"sm": ((min-width: 576px) and (max-width: 767.98px)),
"md": ((min-width: 768px) and (max-width: 991.98px)),
"lg": ((min-width: 992px) and (max-width: 1199.98px)),
"xl": ((min-width: 1200px) and (max-width: 1399.98px)),
"xxl": (min-width: 1400px),
);
#mixin breakpoint($user-value) {
#each $size, $value in $breakpoints{
#if $user-value == $size {
#media #{$value} {
#content;
}
}#else {
#error "This Breackpoint '#{$user-value}' isn't supported yet";
}
}
};
body {
#include breakpoint(sm) {
background-color: blue;
}
}
i wanted to minimize the number of code i'm writing with this SASS mixin
so i figured something out, check out this edited code :
$breakpoints: (
"xs": "max-width: 575.98px",
"sm": "(min-width: 576px) and (max-width: 767.98px)",
"md": "(min-width: 768px) and (max-width: 991.98px)",
"lg": "(min-width: 992px) and (max-width: 1199.98px)",
"xl": "(min-width: 1200px) and (max-width: 1399.98px)",
"xxl": "min-width: 1400px",
);
#mixin breakpoint($user-value) {
$value: map-get($breakpoints, $user-value);
#if $value {
#media (#{$value}) {
#content;
}
}#else {
#warn "This Breackpoint '#{$user-value}' isn't supported yet";
}
};
body {
#include breakpoint(xxl) {
background-color: blue;
}
}

$variable doesn't work inside mixin in scss

I am trying to add breakpoint in the mixin. And declare the breakpoint value in the variable like "$wp-breakpoints-xl: 1280;". But mixin doesn't take the variable. I have tried with interpolation like #{$wp-breakpoints-xl} but that is also not working for me. Mixin code is attached below. If anybody can help me that will be very helpful for me
#mixin wpp-breakpoint($class) {
#if $class == wp-sm
{
#media (min-width: $wp-breakpoints-m) { #content; }
}
#else if $class == wp-md
{
#media (min-width: $wp-breakpoints-l) { #content; }
}
#else if $class == wp-lg
{
#media (min-width: $wp-breakpoints-xl) { #content; }
}
#else if $class == wp-xs-only
{
#media (max-width: $wp-breakpoints-s) { #content; }
}
#else if $class == wp-sm-only
{
#media (min-width: $wp-breakpoints-m) and (max-width: $wp-breakpoints-l - 1) { #content; }
}
#else if $class == wp-md-only
{
#media (min-width: $wp-breakpoints-l) and (max-width: $wp-breakpoints-xl - 1) { #content; }
}
#else if $class == wp-mbltoipad-only
{
#media (max-width: $wp-breakpoints-l - 1) { #content; }
}
#else
{
#warn "Breakpoint mixin supports: wp-sm, wp-md, wp-lg, wp-xs-only, wp-sm-only, wp-md-only, wp-mbltoipad-only";
}
}
And variables are attached below
$wp-breakpoints-s: 749;
$wp-breakpoints-m: 750;
$wp-breakpoints-l: 1024;
$wp-breakpoints-xl: 1280;

How to make a mixin helper responsive using breakpoints?

I want to make this mixin responsive means it generate the media queries
based on breakpoints.
Here is my SCSS Code :
$grid-breakpoints: (
xs: 0,
sm: 576px,
md: 768px,
lg: 992px,
xl: 1200px,
xxl: 1400px
) !default;
#mixin overscroll-behavior-auto() {
-ms-scroll-chaining: chained;
overscroll-behavior: auto;
}
#mixin overscroll-behavior-contain() {
-ms-scroll-chaining: none;
overscroll-behavior: contain;
}
#mixin overscroll-behavior-none() {
-ms-scroll-chaining: none;
overscroll-behavior: none;
}
.overscroll-auto {
#include overscroll-behavior-auto();
}
.overscroll-contain {
#include overscroll-behavior-contain();
}
.overscroll-none {
#include overscroll-behavior-none();
}
#each $breakpoint in map-keys($grid-breakpoints) {
#include media-breakpoint-up($breakpoint) {}
}
I include my sass code thank you guys
Codepen
I made some modifications to the syntax of overscroll-behavior(). Mainly that its not overscroll-behavior-auto(), overscroll-behavior-contain() etc. any longer, but:
overscroll-behavior($behavior, $breakpoint);
This was necessary to not write the same code three times, since you can't generate mixins.
$overscrollBehavior: (
"auto": ["chained", "none" ],
"contain": ["none", "contain"],
"none": ["none", "none" ],
)!default;
$breakpoints: (
"xs": 0px,
"sm": 576px,
"md": 768px,
"lg": 992px,
"xl": 1200px,
"xxl": 1400px,
) !default;
#mixin overscroll-behavior($behavior, $breakpoint) {
$map: $overscrollBehavior;
#for $i from 1 through length($map) {
$label: nth(nth($map, $i), 1);
$values: nth(nth($map, $i), 2);
#if $behavior == $label {
$map: $breakpoints;
#for $i from 1 through length($map) {
$bp: nth(nth($map, $i), 1);
$bpValue: nth(nth($map, $i), 2);
#if $breakpoint == $bp {
#media (min-width: #{$bpValue}) {
-ms-scroll-chaining: unquote(nth($values, 1));
overscroll-behavior: unquote(nth($values, 2));
}
}
}
}
}
}
body {
#include overscroll-behavior(none, xs);
}
#media (min-width: 0px) {
body {
-ms-scroll-chaining: none;
overscroll-behavior: none;
}
}
If that's not quite what your looking for, let me know!

How to solve SassError: Invalid parent selector "*"?

I have an Angular 9 app and when I use this snippet SCSS it returns this error:
SassError: Invalid parent selector "*"
╷
52 │ &#{$value} {
│ ^^^^^^^^^^^^^^^
╵
This is the snippet:
$values: (
"":"",
one: one,
two: two,
);
#mixin gen() {
#each $value, $key in $values {
#media (min-width: 300px) {
&#{$value} {
#content
}
}
}
}
#mixin display {
display: block;
}
.display > * {
#include gen() {
#include display();
}
}
I want in output classes for each value like: display > *, display-one > *, display-two > *and so on.
1. You want to select * after the value >, means you should add it in the mixin
2. You want select -#{$value} and not just &#{$value}. So A- you have to add the -, and B- for $value="" the - is not exist. so probably you should give it special attention.
Shortly, change the scss to
$values: (
one: one,
two: two,
);
#mixin gen() {
#media (min-width: 300px) {
> * {
#content
}
}
#each $value, $key in $values {
#media (min-width: 300px) {
&-#{$value} > * {
#content
}
}
}
}
#mixin display {
display: block;
}
.display {
#include gen() {
#include display();
}
}
Output:
#media (min-width: 300px) {
.display > * {
display: block;
}
}
#media (min-width: 300px) {
.display-one > * {
display: block;
}
}
#media (min-width: 300px) {
.display-two > * {
display: block;
}
}
What #Yosef describes is correct – however, there are a few things to consider
When using #each loops on maps the order is $key, $value.
To minimize the CSS output move the #each loop inside the media query – like:
#media (min-width: 300px) {
// move loop here
#each $key, $value in $values {
...
}
}
// CSS output without redundant media queries
#media (min-width: 300px) {
.display > * {
display: block;
}
.display-one > * {
display: block;
}
.display-two > * {
display: block;
}
}
Last but not least consider not doing this at all – use an attribute selector instead – this way you can handle everything in one selector :-)
#media (min-width: 300px) {
[class|=display] > * { display: block; }
}
// This will match
.display > *, .display-one > *, .display-two > *, .display-xxx > * etc.

Generate a grid columns in scss, with media breakpoint particle at the end

I want to generate media queries grids having the below format:
I use a first large/desktop approach, with floats. It is intentional used instead of mobile-first approach.
#media (max-width: 36em) {
.col-1#sm {
width: 25%; }
.col-2#sm {
width: 50%; }
.col-3#sm {
width: 75%; }
.col-4#sm {
width: 100%; }
}
starting from the following grid-config map:
$grid-config: (
lg: (
width: em(960px),
columns: 16,
gutter-horizontal: rem(8px)
),
md: (
width: em(768px),
columns: 8,
gutter-horizontal: rem(8px)
),
sm: (
width: em(568px),
columns: 4,
gutter-horizontal: rem(8px)
),
);
For the first element in the map(lg) I don't want to add a media query.
The first element can change, so I don't want to do a string check (if bp !=='lg') if possible(not like in my code)
I have the following mixin to generate media-query:
#mixin media-breakpoint($bp) {
$columns: get-grid($bp, columns) !global;
#if $bp != 'lg2' {
#media (max-width: get-grid($bp, width)) {
#content
}
} #else {
#content
}
}
and another mixin to generate grid:
#mixin grid-generator {
#each $key, $value in $grid-config {
$bp: $key !global;
&--#{$key} {
#content;
}
}
}
Then I use:
.col {
#include grid-generator {
#include media-breakpoint($bp) {
$grid-columns: get-grid($bp, 'columns');
#for $i from 1 through $grid-columns {
&-#{$i} {
width: 100%/$grid-columns * $i;
}
}
}
}
}
but this generates the following format col--sm-1 and not col-1#sm.
The problems I have:
keep the cols inside media queryset, and add the media at the end.
compare to first in grid-config dynamic, check if $bp == first in map, instead of lg

Resources