Dynamic variable for class name in sass - css

Im creating for my project helper-class as margins, font-sizes etc and I got problem.
I want to define a class name, where property in class name should be assigned as "placeholder".
Currently as you can see it generates m-r-(amount) by range loop and it has huge limitation (time for compiling and range).
Is there any possibility to make $value variable act like
placeholder?
If not, how can I increase compile time in gulp?
Here is link for codepen http://codepen.io/anon/pen/NAmVVj
$break-small: 320px;
$break-medium: 768px;
$break-large: 1024px;
$break-extra: 1280px;
$baseSizes: (s: 1.5vw, m: 0.7vw, l: 5px, x: 5px);
$fontSizes: (s: 4.7vw, m: 2.08vw, l: 16px, x: 16px);
#mixin respond-to($media) {
#if $media == s {
#media (max-width: $break-medium) {
#content;
}
}
#else if $media == m {
#media (min-width: $break-medium) and (max-width: $break-large) {
#content;
}
}
#else if $media == l {
#media (min-width: $break-large) and (max-width: $break-extra) {
#content;
}
}
#else if $media == x {
#media (min-width: $break-extra) {
#content;
}
}
}
$range: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
$properties: (m: "margin", p: "padding", b: "border");
$directions: (t: "top", b: "bottom", l: "left", r: "right", a: "all");
#each $value in $range {
#each $breakpoint, $size in $baseSizes {
#each $aliasProp, $propValue in $properties {
#each $aliasFrom, $fromValue in $directions {
#if $aliasFrom == a {
.#{$aliasProp}-#{$aliasFrom}-#{$value} {
$final: calc((#{$value} * #{$size}) * 2);
#{$propValue}: $final;
}
}
#if $aliasFrom != a {
.#{$aliasProp}-#{$aliasFrom}-#{$value} {
$final: calc((#{$value} * #{$size}) * 2);
#{$propValue}-#{$fromValue}: $final;
&-#{$breakpoint} {
#include respond-to($breakpoint) {
$final: calc((#{$value} * #{$size}) * 2);
#{$propValue}-#{$fromValue}: $final !important;
}
}
}
}
}
}
}
}
Thanks for answers!

I solved it by processing my library through node-sass as it takes ~ 0.2s while gulp-sass is ~ 23sec, but I'm still curious about question no1.

Related

Dynamically creating variable names in SCSS

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?

I have an issue with my logic in this SASS for loop using two lists.... the error I'm getting says "index out of bounds for `nth($list, $n)`"

Here's my code:
$responsive-adjust-amounts: (
2.5, //phone
2, //tablet
1.5, //laptop
1.25 //desktop
);
$responsive-devices: ("#{$phone}", "#{$tablet}", "#{$laptop}", "#{$desktop}");
#each $device in $responsive-devices {
#media #{$device} {
#for $i from 1 through length($responsive-adjust-amounts) {
#media #{$device} {
#{nth($responsive-adjust-amounts, $i)} {
#include font-adjustments(nth($responsive-adjust-amounts, $i));
}
}
$i: $i + 1;
}
}
}
Ultimately, I'm wanting it to create this end result:
#media #{$phone} {
#include font-adjustments(nth($responsive-adjust-amounts, 1));
}
#media #{$tablet} {
#include font-adjustments(nth($responsive-adjust-amounts, 2));
}
#media #{$laptop} {
#include font-adjustments(nth($responsive-adjust-amounts, 3));
}
#media #{$desktop} {
#include font-adjustments(nth($responsive-adjust-amounts, 4));
}
Could anyone provide any assistance where I'm getting stuck? Thank you in advance!
Excitedly, I've solved my own problem just now. Here's how:
#each $device in $responsive-devices {
$i: index($responsive-devices, #{$device});
#media #{$device} {
#include font-adjustments(nth($responsive-adjust-amounts, $i))
}
}
Additionally, I forgot to include the font-adjustments mixin in the original post. So here is that for anyone's review if needed in the future:
#mixin font-adjustments($amount) {
body {font-size: ($body-base * $amount)}
h4 {font-size: ($subhead-base * $amount)}
h1 {font-size: ($h1-base * $amount)}
}

$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;

SCSS helper classes #mixin with dashes issue

I'm building a bunch of my own helper classes and for most CSS properties/values they are one word so my SCSS code below works fine but for something like justify-content: flex-start I've hit the wall.
I was using str-slice to take the first letter from the property and value but now I need to extend that if the property value uses a dash.
Any thoughts?
$positions: ('relative', 'absolute', 'fixed', 'sticky');
$flexPositions: ('flex-start', 'center', 'flex-end');
#mixin positionHelpers($breakpoint) {
#each $position in $positions {
.p\:#{str-slice($position, 0, 1)}\##{$breakpoint} {
position: #{$position} !important;
}
}
#each $position in $flexPositions {
.jc\:#{str-slice($position, 0, 1)}\##{$breakpoint} {
justify-content: #{$position} !important;
}
}
}
Added the following for more context:
$defaultBreakpoints: (
'xs': 'screen and (max-width: 767px)',
'sm': 'screen and (min-width:768px)',
'md': 'screen and (min-width:1024px)',
'lg': 'screen and (min-width:1201px)'
);
#each $breakpoint, $query in $defaultBreakpoints {
#if $breakpoint == 'xs' {
#include positionHelpers(#{$breakpoint})
} #else {
#media #{$query} {
#include positionHelpers(#{$breakpoint})
}
}
}
I created a function to split your string in 2 parts when there is a dash - in it.
#function split($string, $separator:"-") {
$index : str-index($string, $separator);
$newString:"";
#if($index!= null){
$str-1 : #{str-slice(str-slice($string, 1, $index - 1), 0, 1)};
$str-2 : #{str-slice(str-slice($string, $index + 1), 0, 1)};
$newString: $str-1 + $str-2
} #else{
$newString: str-slice($string, 0, 1);
}
#return $newString;
}
Then you can call it in your #each $position in $flexPositions {...}:
$positions: ('relative', 'absolute', 'fixed', 'sticky');
$flexPositions: ('flex-start', 'center', 'flex-end');
#mixin positionHelpers($breakpoint) {
#each $position in $positions {
.p\:#{str-slice($position, 0, 1)}\##{$breakpoint} {
position: #{$position} !important;
}
}
#each $position in $flexPositions {
$string: split($position); /*here you create a new string*/
.jc\:#{$string}\##{$breakpoint} {
justify-content: #{$position} !important;
}
}
}

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