SASS/SCSS remove hyphen(-) if map has key called null? - css

I want to remove hyphen(-) if map $spacers has key called null.
means it return only the className is this case it called m without hyphen(-).
$spacers: (
0: 0,
1: 1px,
2: 2px,
null: 3px,
4: 4px,
8: 8px
) !default;
#each $prop, $abbrev in (margin: m) {
#each $size, $length in $spacers {
.#{$abbrev}-#{$size} {
#{$prop}: $length !important;
}
}
}
the result that I get after compiling :
.m-0 {
margin: 0 !important;
}
.m-1 {
margin: 1px !important;
}
.m-2 {
margin: 2px !important;
}
// hyphen(-) shouldn't be here
.m- {
margin: 3px !important;
}
.m-4 {
margin: 4px !important;
}
.m-8 {
margin: 8px !important;
}

Use #if and #else.
#each $prop, $abbrev in (margin: m) {
#each $size, $length in $spacers {
#if $size {
.#{$abbrev}-#{$size} {
#{$prop}: $length !important;
}
} #else {
.#{$abbrev} {
#{$prop}: $length !important;
}
}
}
}

Related

Looping through Breakpoints via SCSS

Current I have the below, but it would be great to easily loop through the break points if possible.
#for $i from 1 through 200 {
.m-#{$i}px {
margin: 1px * $i !important;
&-sm {
#include media-breakpoint-up(sm) {
margin: 1px * $i !important;
}
}
&-md {
#include media-breakpoint-up(md) {
margin: 1px * $i !important;
}
}
&-lg {
#include media-breakpoint-up(lg) {
margin: 1px * $i !important;
}
}
&-xl {
#include media-breakpoint-up(xl) {
margin: 1px * $i !important;
}
}
&-xxl {
#include media-breakpoint-up(xxl) {
margin: 1px * $i !important;
}
}
}
}
There is more of this code to cover:
mt
mx
my
mr
ml
Plus I have something similar setup for padding and a few other elements, it would be great to reduce the code as it is taking a fair while to generate the code.
Any help would be great.
You can store your breakpoints in a list and use a #each loop:
$breakpoints: sm, md, lg, xl, xxl;
#for $i from 1 through 200 {
.m-#{$i}px {
margin: 1px * $i !important;
#each $breakpoint in $breakpoints {
&-#{$breakpoint} {
#include media-breakpoint-up($breakpoint) {
margin: 1px * $i !important;
}
}
}
}
}

Is there a cleaner way to write this SCSS code?

I'm building a Saleor Site and I'm relatively new to Django and SASS.
I'm currently making my own styling rules in my SCSS files where there's some duplicated code and I feel like there's probably a way of reducing the amount of that duplicated code. Couldn't find any style guides in regards to SCSS.
Can I get some suggestions on a better way of doing this code?
.p {
&-around {
&_none {
padding: $none;
}
&_x-small {
padding: $x-small;
}
&_small {
padding: $small;
}
&_medium {
padding: $medium;
}
&_large {
padding: $large;
}
&_x-large {
padding: $x-large;
}
}
&-top {
/* only real difference is just "padding-top" instead of "padding" */
&_none {
padding-top: $none;
}
&_x-small {
padding-top: $x-small;
}
&_small {
padding-top: $small;
}
&_medium {
padding-top: $medium;
}
&_large {
padding-top: $large;
}
&_x-large {
padding-top: $x-large;
}
}
/* There's more with right, bottom, vertical, horizontal padding as well */
}
All input is welcome.
Edit:
This is the resulting code, thank you so much Jakob for making this much cleaner.
#each $size, $value in (
'none' : $none,
'x-small': $x-small,
'small' : $small,
'medium' : $medium,
'large' : $large,
'x-large': $x-large
){
.p {
&-around_#{$size} { padding: $value; }
&-vertical_#{$size} { padding-top: $value; padding-bottom: $value; }
&-horizontal_#{$size} { padding-left: $value; padding-right: $value; }
&-top_#{$size} { padding-top: $value; }
&-bottom_#{$size} { padding-bottom: $value; }
&-right_#{$size} { padding-right: $value; }
&-left_#{$size} { padding-left: $value; }
}
.m {
&-around_#{$size} { margin: $value; }
&-vertical_#{$size} { margin-top: $value; margin-bottom: $value; }
&-horizontal_#{$size} { margin-left: $value; margin-right: $value; }
&-top_#{$size} { margin-top: $value; }
&-bottom_#{$size} { margin-bottom: $value; }
&-right_#{$size} { margin-right: $value; }
&-left_#{$size} { margin-left: $value; }
}
}
I think I would use map, #each loop and interpolation #{}- like:
$padding: (
'none' : none,
'x-small': 1px,
'small' : 2px,
'medium' : 3px,
'large' : 4px,
'x-large': 5px
);
.p {
#each $size, $value in $padding {
&-around_#{$size} { padding: $value; }
&-top_#{$size} { padding-top: $value; }
&-right_#{$size} { padding-right: $value; }
&-bottom_#{$size} { padding-bottom: $value; }
&-left_#{$size} { padding-left: $value; }
}
}
If you like to keep the variables you can do:
.p {
#each $size, $value in (
'none' : $none,
'x-small': $x-small,
'small' : $small,
'medium' : $medium,
'large' : $large,
'x-large': $x-large
){
&-around_#{$size} { padding: $value; }
&-top_#{$size} { padding-top: $value; }
&-right_#{$size} { padding-right: $value; }
&-bottom_#{$size} { padding-bottom: $value; }
&-left_#{$size} { padding-left: $value; }
}
}
I guess this would be the best way to do it.
.p {
&-around, &-top {
&_none {
padding: $none;
}
&_x-small {
padding: $x-small;
}
&_small {
padding: $small;
}
&_medium {
padding: $medium;
}
&_large {
padding: $large;
}
&_x-large {
padding: $x-large;
}
}
}

Dynamic margin/padding with sass

Is it possible to simplify and make this more easily maintained with sass?
.padding-8 { padding: 8px !important; }
.padding-10 { padding: 10px !important; }
.padding-top-0 { padding-top: 0 !important; }
.padding-top-3 { padding-top: 3px !important; }
.padding-bottom-0 { padding-bottom: 0 !important; }
.padding-bottom-3 { padding-bottom: 3px !important; }
.padding-bottom-5 { padding-bottom: 5px !important; }
.margin-top-0 { margin-top: 0 !important; }
.margin-top-5 { margin-top: 5px !important; }
.margin-bottom-0 { margin-bottom: 0 !important; }
.margin-bottom-5 { margin-bottom: 5px !important; }
etc..
Is it also possible to write something like .padding-$dir-$value { padding-$dir: $value px !important; } so you can use a class with f.ex padding-left-13?
Make two maps with the properties you want to mix.
For each combination create a placeholder class. I think it's appropiate if you don't want to create a full list of classes that maybe you won't use. This is the modular-friendly use.
Extend the class in your element.
$paddingDirection:('right','left','top','bottom');
$paddingLength:(15,30,45,50);
#each $dir in $paddingDirection{
#each $len in $paddingLength{
%padding-#{$dir}-#{$len}{ padding-#{$dir}: #{$len}px;}
}
}
.any-class{
#extend %padding-right-30;
}
/*output*/
.any-class {
padding-right: 30px;
}
Original answer here
you can use this: (enhanced the above solution)
$paddingDirection:('right','left','top','bottom');
$paddingLength:(15,30,45,50);
// if you only wants to use "padding" without postfix
#each $len in $paddingLength {
.padding-#{$len} { padding: #{$len}px;}
}
// if you want to use padding-left, padding-right etc.
#each $dir in $paddingDirection {
#each $len in $paddingLength {
.padding-#{$dir}-#{$len} { padding-#{$dir}: #{$len}px;}
}
}
usage:
<div class="padding-15"></div>
<div class="padding-left-15 padding-top-15"></div>

Composing CSS shorthand value Sass

I wonder if there is a way to compose/decompose CSS shorthand with Sass. For example, I have:
$standardPadding: 4px 2px 1px 2px;
and I want to have:
$someSpecificPadding: doSomething($standardPadding, top, 2px);
then the final value of $someSpecificPadding is 2px 2px 1px 2px.
Is there existing any doSomething in Sass (scss) or Less ?
You could use this code to achieve your desired result
#function do_something($list, $args...) {
#each $mini-list in $args {
$value: nth($mini-list, 2);
$position: nth($mini-list, 1);
#if $position == top {
$list: set-nth($list, 1, $value);
}
#else if $position == right {
$list: set-nth($list, 2, $value);
}
#else if $position == bottom {
$list: set-nth($list, 3, $value);
}
#else if $position == left {
$list: set-nth($list, 4, $value);
}
}
#return $list;
}
The function can be used to change single or multiple positions in the shorthand value as shown below
$standardPadding: 4px 2px 1px 2px;
//change both top and bottom values
$standardPadding: do_something($standardPadding, top 18px, bottom 15px);
h2 {
border-width: $standardPadding; //returns 18px 2px 15px 2px
}
h3 {
//changes only top value
border-width: do_something($standardPadding, top 12px); //returns 12px 2px 15px 2px
}
Hope this helps.
You can use a mixin somewhat like this
#mixin padding($top, $left: $top, $bottom: $top, $right: $left){
padding-top: $top;
padding-left: $left;
padding-bottom: $bottom;
padding-right: $right;
}

SCSS calculation with multiple values

SCSS
#function space($parent-width, $width...) {
#return $width + $parent-width;
}
CSS
.box {
padding: space(2px, 25px 40px 50px 60px);
}
Result
.box {
padding: 25px 40px 50px 60px2px;
}
I wanted to create a simple function that execute the below result:
Expected result
.box {
padding: 27px 42px 52px 62px;
}
Your function should be:
#function space($parent-width, $width...) {
$result: ();
#for $i from 1 through length($width) {
$result: append($result, nth($width, $i)+$parent-width);
}
#return $result;
}
See live example.

Resources