Sass For Loop over Nth Items - css

I'm currently working on a SASS for loop to loop over nth images(50 for example). For every nth-of-type I'd like to increase the transition delay by 50ms. The starting point is 250ms and it seems that the for loop I currently have in the works is not incrementing by 50ms and remains at 250ms at all times.
$time: 250ms;
#for $i from 1 through 50 {
img:nth-of-type(#{$i}) {
transition-delay: $time(#{$i}) + 50ms;
}
}
If anyone has any suggestions or could lend a hand, that would be greatly appreciated. Thank you in advance.

If you're going to use a mixin, you can use a default argument
#mixin transitionDelay($default: 200) {
#for $i from 1 through 50 {
&:nth-of-type(#{$i}) {
transition-delay: #{($i * 50) + $default}ms;
}
}
}
Then include it with an argument...
.cool { #include transitionDelay(200); }
or without
.cool { #include transitionDelay; }

$time: 250;
#for $i from 1 through 50 {
img:nth-of-type(#{$i}) {
$itemType: $time + ($i - 1) * 50;
transition-delay: #{$itemType}ms;
}
}
You could probably achieve the same without a helper variable, but I think it makes things cleaner.

I changed some of the logic to accommodate my needs but here's a revised version of my loop.
#mixin transitionDelay {
#for $i from 1 through 50 {
&:nth-of-type(#{$i}) {
transition-delay: #{$i * 45}ms;
}
}
}

Related

My SASS loop is breaking using interpolation and percentage

This code is breaking my SASS process for some reason..
#for $i from 1 through 100 {
.t-#{$i} {
top: #{$i}%;
}
}
You can change to this:
#for $i from 1 through 100 {
.t-#{$i} {
top: 1% * $i
}
}
From SASS docs:
Here is an example
You can also write like this
#for $i from 1 through 100 {
.t-#{$i} {
top: #{$i + '%'};
}
}

Increase color saturation with sass mixin

I'm trying to write looped mixin that iteratively increases the saturation of a background-color. Here's the latest mixin code:
#mixin generateBackgroundSteps($cell-count, $color) {
#for $i from 0 through $cell-count - 1 {
$percent: (5 * $i) + "%";
$new-color: saturate($color, $percent);
&[setting-id="#{$i}"] {
background-color: $new-color;
}
}
}
No matter how I've altered this, the produced css just keeps looking like this:
.rubric-design .rubric .create-new-criteria .create-criteria-initial-
settings .create-criteria-setting[setting-id="2"] {
background-color: saturate(#90afc8);
}
Maybe it's the way I'm forming $percent. It must be something obvious!
Try using percentage function.
percentage function in SCSS
$percent: percentage((5 * $i) / (5 * $cell-count));
#mixin generateBackgroundSteps($cell-count, $color) {
#for $i from 0 through $cell-count - 1 {
$percent: percentage((5 * $i) / (5 *$cell-count));
$new-color: saturate($color, $percent);
&[setting-id="#{$i}"] {
background-color: $new-color;
}
}
}

Animation delays generation with LESS

I am trying to generate animation delays with LESS. The final result should be similar to:
[data-animation-delay="1"] {
animation-delay: .5s;
}
[data-animation-delay="2"] {
animation-delay: 1s;
}
My code looks like:
#animation-delays: 10;
#animation-delay-step: .5; // delay in seconds
.animation-delays-loop (#i) when (#i > 0) {
[data-animation-step="#{i}"] {
#animation-delay = #animation-delay-step * #{i};
animation-delay: #animation-delay~"s";
}
.animation-delays-loop(#i - 1);
}
.animation-delays-loop (#animation-delays);
However, it doesn't work. The problem seems to be in animation-delay: #animation-delay~"s";. Any ideas how to correct it?
OK, I ended up with doing this:
#animation-delays: 10;
#animation-delay-step: .5; // delay in seconds
.animation-delays-loop (#i) when (#i > 0) {
[data-animation-step="#{i}"] {
#animation-delay: #i * #animation-delay-step;
animation-delay: ~"#{animation-delay}s";
}
.animation-delays-loop(#i - 1);
}
.animation-delays-loop (#animation-delays);
worked like a charm.

Advanced SCSS/SASS mixin/function

I've made a pretty nice chaining effect, that I would love to turn into a mixin, or function, but I can't wrap my head around how to build it. Searched everywhere but I can't assemble the puzzle.
The output should look like this
{
opacity: 0;
transform: translateY(3em);
#keyframes moveUp {
from {
opacity: 0;
transform: translateY(3em);
} to {
opacity: 1;
transform: translateY(0);
}
}
.inview ~ & {
animation: moveUp 1s forwards;
#for $i from 1 through 20 {
&:nth-child(#{$i}) {
animation-delay: (0.1 * $i) + s
}
}
}
}
My current attempt (doesn't compile), looks like this:
#mixin inviewChainAnimation($animationName, $from, $to, $duration, $delay, $count:20) {
$from;
#keyframes #{$animationName} {
from {
$from;
}
to {
$to
}
}
.inview ~ & {
animation: #{$animationName} #{$duration} forwards;
#for $i from 1 through #{$count} {
&:nth-child(#{$i}) {
animation-delay: (#{$delay} * $i) + s
}
}
}
}
How can I get two objects ($from and $to) passed through a function. Is that even possible?
Have you tried SASS-maps to render the declarations? For example:
$mapFrom: (opacity: 0, transform: translateY(3em));
$mapTo: (opacity: 1, transform: translateY(0));
And then in your mixin using of #each directive:
#each $key, $value in $from {
#{$key}: #{$value};
}
But then there is another problem. If I try to parse the modified mixin, I get the following error:
Error: "20" is not an integer.
on line 22 of test.scss, in `inviewChainAnimation'
from line 34 of test.scss
The error occurs at this line:
#for $i from 1 through #{$count} {
To solve this change #{count} to $count. The same for #{$delay}. That's it. Here is the final working mixin:
#mixin inviewChainAnimation($animationName, $from, $to, $duration, $delay, $count: 20) {
#each $key, $value in $from {
#{$key}: #{$value};
}
#keyframes #{$animationName} {
from {
#each $key, $value in $from {
#{$key}: #{$value};
}
}
to {
#each $key, $value in $to {
#{$key}: #{$value};
}
}
}
.inview ~ & {
animation: #{$animationName} #{$duration} forwards;
#for $i from 1 through $count {
&:nth-child(#{$i}) {
animation-delay: ($delay * $i) + s
}
}
}
}
Use of the mixin:
.container {
#include inviewChainAnimation('foo', $mapFrom, $mapTo, .15, .1);
}
If you have the need to pass only one set of css properties, you can use #content to simplify your mixin. See for an example at Passing css property:value into a mixins argument.

SASS foreach on li with certain classes

I've been searching all over for an answer to this question for a specific issue I am looking at with SASS. I am wanting to start with an li at 100% opacity but then have it loop through the li's with certain classes and subtract 5% opacity using the transparentize function. The issue though is the foreach loop, as I don't know how many li's with a certain class I'll have. Let me see if I can explain it with code, basically I'll show you the long form and if someone can help me convert it into a short foreach that would be great.
li {
... styles are here ...
&.Language {
background-color: $red
}
&.Language.comp-1 {
background-color: transparentize($red, 0.10);
}
&.Language.comp-2 {
background-color: transparentize($red, 0.20);
}
&.Language.comp-3 {
background-color: transparentize($red, 0.30);
}
&.Language.comp-4 {
background-color: transparentize($red, 0.40);
}
&.Language.comp-5 {
background-color: transparentize($red, 0.50);
}
}
If I was going to do this in PHP this is how I would do it, I just need the SASS version:
$transparency_increment = .10
foreach( $item as $li ) {
background-color: transparentize( $red, $transparency_increment);
$transparency_increment + .10;
}
Hopefully that makes sense, I'm sure I'll have to use the nth item somewhere since the exact count will be unknown. Thanks for help in advance!
What you're looking for is the #for control directive
This should do what you want:
$red: #ff0000;
#mixin foo($prefix, $num, $step){
#for $i from 1 through $num {
#{$prefix}-#{$i} {
background-color: transparentize($red, $i * $step);
}
}
}
li {
#include foo('&.Language.comp', 10, 0.1);
}
Untested and extracted from bootstrap-sass
#mixin transparent_steps_bg($bg_color, $amount, $tranparancy_amount) {
#while $amount> 0 {
.comp-#{$amount} { background-color: transparentize($bg_color, $amount * tranparancy_amount); }
$amount: $amount - 1;
}

Resources