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
Related
I Want to convert below mentioned CSS format to SCSS using variables or methods. Please suggest how to achieve.
CSS Format is:
.section-1-1{
margin-left:0;
}
.section-1-1 + .section-1-2 {
margin-left: 15px;
}
.section-1-1 + .section-1-3 {
margin-left: 15px;
}
.section-2-1{
margin-left:0;
}
.section-2-1 + .section-2-2 {
margin-left: 15px;
}
.section-2-1 + .section-2-3 {
margin-left: 15px;
}
Note: I may have to write more like .section-3-1, .section-4-1.... vice versa.
With sass you can clean up your code like this, no need to create variables.
.section-1-1 {
margin-left: 0;
+ {
.section-1-2 {
margin-left: 15px;
}
.section-1-3 {
margin-left: 15px;
}
.section-x { } ...
}
}
.section-2-1 { .... }
If you have a lot of classes, you can create classes in a loop.
#for $i from 1 through 3 {
.section-#{$i}-1 {
margin-left: 0px;
}
#for $j from 1 through 3 {
.section-#{$i}-1 + .section-#{$i}-#{$j} {
margin-left: 15px;
}
}
}
This will generate the following CSS.
.section-1-1 {
margin-left: 0px;
}
.section-1-1 + .section-1-1 {
margin-left: 15px;
}
.section-1-1 + .section-1-2 {
margin-left: 15px;
}
.section-1-1 + .section-1-3 {
margin-left: 15px;
}
.section-2-1 {
margin-left: 0px;
}
.section-2-1 + .section-2-1 {
margin-left: 15px;
}
.section-2-1 + .section-2-2 {
margin-left: 15px;
}
.section-2-1 + .section-2-3 {
margin-left: 15px;
}
.section-3-1 {
margin-left: 0px;
}
.section-3-1 + .section-3-1 {
margin-left: 15px;
}
.section-3-1 + .section-3-2 {
margin-left: 15px;
}
.section-3-1 + .section-3-3 {
margin-left: 15px;
}
Use CSS to SCSS converter: https://beautifytools.com/css-to-scss-converter.php
Here's the converter's output for your CSS:
.section-1-1 {
margin-left: 0;
+ {
.section-1-2 {
margin-left: 15px;
}
.section-1-3 {
margin-left: 15px;
}
}
}
.section-2-1 {
margin-left: 0;
+ {
.section-2-2 {
margin-left: 15px;
}
.section-2-3 {
margin-left: 15px;
}
}
}
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;
}
}
}
Is there a way to use {$} to get the most direct parent?
In the example below '&#{&}' is not working as I expected, I managed to work around it using mixin.
#mixin modifier($modifier, $block: &) {
&#{"."+$block}--#{$modifier} {
#content;
}
}
.namespace{
$button : 'btn';
.#{$button} {
line-height: 1;
#include modifier('big', $button){ // working but not clean
padding-top: 8px;
}
&#{&}--big{ // not working as {&} is interpolated to namespace .btn
padding-top: 12px;
}
}
}
Compiled to:
.namespace .btn {
line-height: 1;
}
.namespace .btn.btn--big {
padding-top: 8px;
}
.namespace .btn.namespace .btn--big {
padding-top: 12px;
}
The construct looks a bit odd to me – but you could do it like:
.namespace {
$class: ".btn";
#{$class} { line-height: 1; }
#{$class}#{$class}--big { padding-top: 8px; }
& #{$class}#{&} #{$class}--big { padding-top: 12px; }
}
...or using selector append
.namespace .btn {
line-height: 1;
#at-root {
#{selector-append(&,".btn")}--big{ padding-top: 8px; }
#{selector-append(&,&)}--big{ padding-top: 12px; }
}
}
both compiling to:
.namespace .btn { line-height: 1; }
.namespace .btn.btn--big { padding-top: 8px; }
.namespace .btn.namespace .btn--big { padding-top: 12px; }
I'm trying to achieve a loop for padding.
Example from less.org just modified
.generate-pad(10);
.generate-pad(#n, #i: 1) when (#i =< #n) {
.padd-top-#{i} {
padding-top: (#i * 100px / #n);
}
.generate-pad(#n, (#i + 1));
}
outputs the following when its compiled
.padd-top-1 {
padding-top: 10px;
}
.padd-top-2 {
padding-top: 20px;
}
.padd-top-3 {
padding-top: 30px;
}
.padd-top-4 {
padding-top: 40px;
}
.padd-top-5 {
padding-top: 50px;
}
.padd-top-6 {
padding-top: 60px;
}
.padd-top-7 {
padding-top: 70px;
}
.padd-top-8 {
padding-top: 80px;
}
.padd-top-9 {
padding-top: 90px;
}
.padd-top-10 {
padding-top: 100px;
}
but I am trying to replace .pad-top-#{i} with a variable so I can call it later. How can I achieve this?
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;
}