Is there a cleaner way to write this SCSS code? - css

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

Related

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

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

Get posts all posts by Tag / URL Wordpress On Post / Pge

For take posts by tag and list post and pages.
add_action('the_content', 'shortCodeEasyFilter');
function shortCodeEasyFilter($content) {
if (is_single()) {
$finds = getInbetweenStrings($content);
if (count($finds) > 0) {
$content = "<style>
.shortlink {
margin: 4px;
font-size: 18px;
background-image: linear-gradient(to top,#0c6fb1,#0c6fb1);
color: #FFFFFF !important;
padding: 8px;
border-radius: 8px;
position: relative;
display: block;
margin-bottom: 0px;
}
.shortlink:hover {
color: #FFFFFF !important;
opacity: 0.8;
text-decoration: none
}
.shortlink * {
display: inline;
}
.shortlink h3 {
color: #FFFFFF;
margin: 0;
}
.shortlink a {
color: #FFFFFF;
margin: 0
}
</style>".$content;
}
foreach($finds as $code) {
foreach(explode(",", $code) as $codepart) {
$output = '';
query_posts(array(
"post_status" => "publish",
"tag_id" => $codepart
));
while(have_posts()) {
the_post();
$title = get_the_title();
$link = get_the_permalink();
$output .= "<h3 style='margin-bottom: 5px'><a class='shortlink' href='$link' title='$title'><i class='fas fa-long-arrow-alt-right'></i> $title</a></h3>";
}
wp_reset_query();
$content = str_replace("[etikonu]".$code."[/etikonu]", $output, $content);
}
}
}
return $content;
}
function getInbetweenStrings($str){
preg_match_all('%\[etiketlist\](.*?)\[/etiketlist\]%i', $str, $matches, PREG_PATTERN_ORDER);
return $matches[1];
}
?>
This code lists the last articles in the first place. I want to make the first articles in the first place and I want to make alphabetical listings too. So I have to make 3 different lists. Can you help me?
Thank you...

Using array of classes in SASS

Using SASS/SCSS. I have the following:
body:not(.sessions):not(.registrations):not(.home):not(.posts.new) {
padding-top: 4.5rem;
padding-bottom: 7rem;
}
This is not readable at all. How do I refactor this by using an array of classes:
$full-page-classes: .sessions .registrations .home .posts.new
If I understand you mean correctly, you may want to use the array like this:
$full-page-classes: '.sessions', '.registrations', '.home', '.posts.new';
#each $page-class in $full-page-classes {
body:not(#{$page-class}) {
padding-top: 4.5rem;
padding-bottom: 7rem;
}
}
Output:
body:not(.sessions) {
padding-top: 4.5rem;
padding-bottom: 7rem;
}
body:not(.registrations) {
padding-top: 4.5rem;
padding-bottom: 7rem;
}
body:not(.home) {
padding-top: 4.5rem;
padding-bottom: 7rem;
}
body:not(.posts.new) {
padding-top: 4.5rem;
padding-bottom: 7rem;
}
You can try it on sassmeister
Update:
If you want to generate inline CSS, you can try this:
$full-page-classes: '.sessions', '.registrations', '.home', '.posts.new';
$temp: '';
#each $page-class in $full-page-classes {
$temp: $temp + ':not(#{$page-class})';
}
#each $item in $temp {
body#{$item} {
padding-top: 4.5rem;
padding-bottom: 7rem;
}
}
Output:
body:not(.sessions):not(.registrations):not(.home):not(.posts.new) {
padding-top: 4.5rem;
padding-bottom: 7rem;
}
Update 2:
#function str-replace($string, $search, $replace: '') {
$index: str-index($string, $search);
#if $index {
#return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
}
#return $string;
}
$full-page-classes: ' .sessions, .registrations, .home, .posts.new,';
#each $x in str-replace(str-replace($full-page-classes, ' ', ':not('), ',', ')') {
body#{$x} {
padding-top: 4.5rem;
padding-bottom: 7rem;
}
}
Reference: str-replace function

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>

Automate pixel fallback using REM units throughout a project

I checked the following article in which it presented the following mixing:
rem font size with pixel fallback
#function calculateRem($size) {
$remSize: $size / 16px;
#return $remSize * 1rem;
}
#mixin font-size($size) {
font-size: $size;
font-size: calculateRem($size);
}
I feel very confortable using rem on my projects, after placing font-size: 62.5% on the html so 1rem = 10pixels.
But I would like to know if there is a mixing or a method to create a pixel fallback for any rem used in a whole project, as for example:
&:before{
color: white;
margin: 0 0.5rem 0 0;
left: 0;
text-align: center;
top: 0;
width: 3.2rem;
}
In this case the margin-right = 5pixels and width 32pixels. The issue with rem units is that IE8, Opera mini or Safari 3.2 is not supported. So the site would not be correctly visible from any of these browsers.
Is there a way to automate the pixel fallback using rem throughout a project?
Here is a solution so you can use the rem to px mixin for any property:
html {
font-size: 62.5%;
}
#function calculateRem($size) {
$remSize: $size / 10px;
#return #{$remSize}rem;
}
#mixin rem($propertie, $value) {
#{$propertie}: $value;
#{$propertie}: calculateRem($value);
}
p {
font-size: calculateRem(32px);
#include rem(width, 100px);
#include rem(margin, 50px);
}
OUTPUT
html {
font-size: 62.5%;
}
p {
font-size: 3.2rem;
width: 100px; /* Fallback */
width: 10rem;
margin: 50px; /* FallBack */
margin: 5rem;
}
An example: http://sassmeister.com/gist/e888e641925002b5895c
This solution will work with shortcut properties that contain mixed values.
// Global Var
$root-font-size: 16;
#mixin rem($property, $values) {
$pxvalues: null;
$remvalues: null;
#each $value in $values{
$pxvalue: null;
$remvalue: null;
#if type-of($value) == 'number'{
#if ($value > 0 or $value < 0){
$pxvalue: ($value)+px;
$remvalue: ($value / $root-font-size)+rem;
} #else {
$pxvalue: $value;
$remvalue: $value;
}
} #else {
$pxvalue: $value;
$remvalue: $value;
}
$pxvalues: append($pxvalues, $pxvalue);
$remvalues: append($remvalues, $remvalue);
}
#{$property}: $pxvalues;
#{$property}: $remvalues;
}
// Usage: pass pixel values without units
.foo{
#include rem(margin, 80 auto);
}
Output:
.foo{
margin: 80px auto;
margin: 5rem auto;
}

Resources