How do I write this in SCSS - sass

I'm not very familiar with SCSS and downt know how the following code should look in SCSS. I wanna add per level 20px margin.
.level-1 {
margin-left: 0px;
}
...
.level-9 {
margin-left: 160px;
}

You can use a for loop :
#for $i from 1 through 9 {
.level-#{$i} {
margin-left: 20px * ($i - 1);
}
}

Related

sass / scss - create class shortcuts

While doing some css I came up with the idea of combining multiple classes into one. The reason is, to use short class names which could probably already be in use.
Assume the following:
.f-box-cell {
flex : 1 1 auto;
// colors
&.red { background-color: red; }
&.green { background-color: green; }
...
// sizes
&.b25 { flex-basis: 25%; }
&.b50 { flex-basis: 50%; }
...
// other options
...
}
Instead of doing ...
<div class="f-box-cell">
<div class="f-box-cell red">
<div class="f-box-cell b25">
<div class="f-box-cell red b25">
... I want do have something like ...
<div class="f-box-cell">
<div class="f-box-cell-red">
<div class="f-box-cell-b25">
<div class="f-box-cell-red-b25">
... with the same effect as the normal class listings.
Obviously, the more "subclasses" are added the more combinations would exist. So I'm interessted - if possible - in creating all these combinations automatically. Completely awesome would be, if the position of the "classes" inside the "combined class" would not matter.
Therefore my 2 main questions are:
Is there a way to achieve something like this with sass / scss?
Is the idea completely stupid?
Thanks in advance
If you only want to have all your classes prefixed and don't mind adding two classes (class="f-box-cell f-box-cell-red"), then you can just use the ampersand multiple times:
.f-box-cell {
flex : 1 1 auto;
// colors
& &-red { background-color: red; }
& &-green { background-color: green; }
...
// sizes
& &-b25 { flex-basis: 25%; }
& &-b50 { flex-basis: 50%; }
...
// other options
...
}
If you only want to use the most specific class, which should inherit from the base one, you can use the #extend rule:
.f-box-cell {
flex : 1 1 auto;
// colors
&-red { #extend .f-box-cell; background-color: red; }
&-green { #extend .f-box-cell; background-color: green; }
...
// sizes
&-b25 { #extend .f-box-cell; flex-basis: 25%; }
&-b50 { #extend .f-box-cell; flex-basis: 50%; }
...
// other options
...
}
Which compiles to:
.f-box-cell,
.f-box-cell-b50,
.f-box-cell-b25,
.f-box-cell-green,
.f-box-cell-red {
flex: 1 1 auto;
}
.f-box-cell-red {
background-color: red;
}
.f-box-cell-green {
background-color: green;
}
.f-box-cell-b25 {
flex-basis: 25%;
}
.f-box-cell-b50 {
flex-basis: 50%;
}

CSS margin loop incrementing by X amount each time

I wonder if it is possible to do this with SCSS? Incrementing by X each time.
It is tricky because the -s or -md needs to be updated instead of the number.
#for $i from 1 through 6 {
.u-marg-t-#{$i} {
margin-top: 0px + ($i * 8);
}
}
Aside from this not even counting correctly, is a #for the best approach, here?
Plain CSS output
.u-marg-t {
&-xs {
margin-top: 8px;
}
&-sm {
margin-top: 16px;
}
&-md {
margin-top: 24px;
}
&-lg {
margin-top: 32px;
}
&-xl {
margin-top: 43px;
}
&-xxl {
margin-top: 50px;
}
}
.u-marg-b {
&-xs {
margin-bottom: 8px;
}
&-sm {
margin-bottom: 16px;
}
&-md {
margin-bottom: 24px;
}
&-lg {
margin-bottom: 32px;
}
&-xl {
margin-bottom: 43px;
}
&-xxl {
margin-bottom: 50px;
}
}
You could use a list with the suffixes you want to use and iterate through inside your for loop. Here's an example:
$sizes: xs, sm, md, lg, xl, xxl;
#for $i from 1 through 6 {
.u-marg-t-{
&#{nth($sizes, $i)} {
margin-top: 0px + ($i * 8);
}
}
}
$sizes is your list with the suffixes. Inside the loop I used the function nth($list, $i) to get the item at position $i in your list.

Sass (SCSS) - How to Add to Individual Values in a Class

I want to add 2px to the padding all around an element. So
padding: 10px 14px;
will become
padding: 14px 18px;. How can I achieve this?
Hopefully there is a more elegant solution than (psuedo-code):
$horizontal-padding: 10;
$vertical-padding: 14;
.normal-padding {
padding-top: $vertical-padding;
padding-right: $horizontal-padding;
padding-bottom: $vertical-padding;
padding-left: $horizontal-padding;
}
.extra-padding {
($horizontal-padding + 2 + px), ($vertical-padding + 2 + px);
}
Surely there must be a better way?
Actually, you can write that in a lot of ways. A solution similar to your code could be:
$vertical-padding: 14px;
$horizontal-padding: 10px;
.normal-padding {
padding: $vertical-padding $horizontal-padding;
}
.normal-padding {
$extra: 2px;
padding: #{$vertical-padding + $extra} #{$horizontal-padding + $extra};
}
A more dynamical way (not really useful if you only have these two variations though):
#mixin padding($extra : 0) {
padding: #{14 + $extra}px #{10 + $extra}px;
}
.normal-padding {
#include padding;
}
.extra-padding {
#include padding(2);
}
You can even change the code above to keep the $vertical-padding and $horizontal-padding variables. As I said, there are many ways to do it.
Just for fun. You can use css custom properties:
div {
border: 1px solid;
}
:root {
/* declare global variables */
--padding-x: 10px;
--padding-y: 10px;
}
.padded {
padding: var(--padding-y) var(--padding-x);
}
.extra {
/* redefine variables for `extra` elements */
--padding-x: 30px;
--padding-y: 30px;
}
<div class="padded"></div>
<div class="padded extra"></div>

SCSS repeat value?

I'm trying to work out on SCSS how I would go about something like this:
I would like to have a margin anywhere between 1px and 1000px and have a class for it.
For example
.MarginTop-x
X being where I can write any value. Obviously I couldn't write out
.MarginTop-1 {margin-top:1px}
.MarginTop-2 {margin-top:2px}
.MarginTop-3 {margin-top:3px}
.MarginTop-4 {margin-top:4px}
etc...
Well you need a #for loop to do that .
SCSS :
$class-slug: ".MarginTop";
$stop-loop: 4;
#for $i from 0 through $stop-loop {
#{$class-slug}-#{$i} {
margin-top: #{$i}px;
}
}
Compiled CSS:
.MarginTop-0 {
margin-top: 0px; }
.MarginTop-1 {
margin-top: 1px; }
.MarginTop-2 {
margin-top: 2px; }
.MarginTop-3 {
margin-top: 3px; }
.MarginTop-4 {
margin-top: 4px; }
Not sure of the utility of this, but...
Sass:
#mixin marginTop($amount) {
.marginTop-#{$amount} {
margin-top: unquote($amount + 'px');
}
}
#include marginTop(1);
#include marginTop(100);
Compiled CSS:
.marginTop-1 {
margin-top: 1px;
}
.marginTop-100 {
margin-top: 100px;
}

Incrementing Variable in Loop

I've got the following loop producing some styles for a tag cloud. On the online generators it produces the I'd consider the correct css styles, however in the visual studio solution (2012) which auto produces the css it seems to hang up. (see below) the less. Is there a more proper way to produce something like this via less that won't confuse the VS .less generator?
#iterations: 10;
#maxSize: 40;
#minSize: 10;
.tag-loop (#i) when (#i > -1) {
#j: (#i*(30/#iterations) + #minSize);
li.tag-#{i} {
font-size:~"#{j}px";
}
.tag-loop(#i - 1);
}
.tag-loop (#iterations);
Produces via visual studio:
ul.tag-cloud li.tag-10 {
font-size: 10px;
}
ul.tag-cloud li.tag-9 {
font-size: 10px;
}
ul.tag-cloud li.tag-8 {
font-size: 10px;
}
ul.tag-cloud li.tag-7 {
font-size: 10px;
}
ul.tag-cloud li.tag-6 {
font-size: 10px;
}
ul.tag-cloud li.tag-5 {
font-size: 10px;
}
ul.tag-cloud li.tag-4 {
font-size: 10px;
}
ul.tag-cloud li.tag-3 {
font-size: 10px;
}
ul.tag-cloud li.tag-2 {
font-size: 10px;
}
ul.tag-cloud li.tag-1 {
font-size: 10px;
}
ul.tag-cloud li.tag-0 {
font-size: 10px;
}
If I use something like http://winless.org/online-less-compiler the following is more accurately produced:
li.tag-10 {
font-size: 40px;
}
li.tag-9 {
font-size: 37px;
}
li.tag-8 {
font-size: 34px;
}
li.tag-7 {
font-size: 31px;
}
li.tag-6 {
font-size: 28px;
}
li.tag-5 {
font-size: 25px;
}
li.tag-4 {
font-size: 22px;
}
li.tag-3 {
font-size: 19px;
}
li.tag-2 {
font-size: 16px;
}
li.tag-1 {
font-size: 13px;
}
li.tag-0 {
font-size: 10px;
}
It looks like your VS uses (via Web Essentials 2012?) quite outdated Less 1.3.3 which handles variable scope quite differently, i.e. #j defined in the last iteration overrides all previous #j definitions.
The workaround to this is to calculate font-size value directly:
#iterations: 10;
#maxSize: 40;
#minSize: 10;
.tag-loop (#i) when (#i > -1) {
li.tag-#{i} {
font-size: unit((#i * (30 / #iterations) + #minSize), px);
}
.tag-loop((#i - 1));
}
.tag-loop (#iterations);

Resources